1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.telephony.sip; 18 19 import android.content.Context; 20 import android.net.LinkProperties; 21 import android.os.AsyncResult; 22 import android.os.Handler; 23 import android.os.Message; 24 import android.os.RegistrantList; 25 import android.os.ResultReceiver; 26 import android.sysprop.TelephonyProperties; 27 import android.telephony.NetworkScanRequest; 28 import android.telephony.ServiceState; 29 import android.telephony.SignalStrength; 30 31 import com.android.internal.telephony.Call; 32 import com.android.internal.telephony.Connection; 33 import com.android.internal.telephony.IccCard; 34 import com.android.internal.telephony.IccPhoneBookInterfaceManager; 35 import com.android.internal.telephony.MmiCode; 36 import com.android.internal.telephony.OperatorInfo; 37 import com.android.internal.telephony.Phone; 38 import com.android.internal.telephony.PhoneConstants; 39 import com.android.internal.telephony.PhoneNotifier; 40 import com.android.internal.telephony.uicc.IccFileHandler; 41 import com.android.telephony.Rlog; 42 43 import java.util.ArrayList; 44 import java.util.List; 45 46 abstract class SipPhoneBase extends Phone { 47 private static final String LOG_TAG = "SipPhoneBase"; 48 49 private RegistrantList mRingbackRegistrants = new RegistrantList(); 50 private PhoneConstants.State mState = PhoneConstants.State.IDLE; 51 SipPhoneBase(String name, Context context, PhoneNotifier notifier)52 public SipPhoneBase(String name, Context context, PhoneNotifier notifier) { 53 super(name, notifier, context, new SipCommandInterface(context), false); 54 } 55 56 @Override getForegroundCall()57 public abstract Call getForegroundCall(); 58 59 @Override getBackgroundCall()60 public abstract Call getBackgroundCall(); 61 62 @Override getRingingCall()63 public abstract Call getRingingCall(); 64 migrateFrom(SipPhoneBase from)65 void migrateFrom(SipPhoneBase from) { 66 super.migrateFrom(from); 67 migrate(mRingbackRegistrants, from.mRingbackRegistrants); 68 } 69 70 @Override registerForRingbackTone(Handler h, int what, Object obj)71 public void registerForRingbackTone(Handler h, int what, Object obj) { 72 mRingbackRegistrants.addUnique(h, what, obj); 73 } 74 75 @Override unregisterForRingbackTone(Handler h)76 public void unregisterForRingbackTone(Handler h) { 77 mRingbackRegistrants.remove(h); 78 } 79 80 @Override startRingbackTone()81 public void startRingbackTone() { 82 AsyncResult result = new AsyncResult(null, Boolean.TRUE, null); 83 mRingbackRegistrants.notifyRegistrants(result); 84 } 85 86 @Override stopRingbackTone()87 public void stopRingbackTone() { 88 AsyncResult result = new AsyncResult(null, Boolean.FALSE, null); 89 mRingbackRegistrants.notifyRegistrants(result); 90 } 91 92 @Override getServiceState()93 public ServiceState getServiceState() { 94 // FIXME: we may need to provide this when data connectivity is lost 95 // or when server is down 96 ServiceState s = new ServiceState(); 97 s.setVoiceRegState(ServiceState.STATE_IN_SERVICE); 98 return s; 99 } 100 101 @Override getState()102 public PhoneConstants.State getState() { 103 return mState; 104 } 105 106 @Override getPhoneType()107 public int getPhoneType() { 108 return PhoneConstants.PHONE_TYPE_SIP; 109 } 110 111 @Override getSignalStrength()112 public SignalStrength getSignalStrength() { 113 return new SignalStrength(); 114 } 115 116 @Override getMessageWaitingIndicator()117 public boolean getMessageWaitingIndicator() { 118 return false; 119 } 120 121 @Override getCallForwardingIndicator()122 public boolean getCallForwardingIndicator() { 123 return false; 124 } 125 126 @Override getPendingMmiCodes()127 public List<? extends MmiCode> getPendingMmiCodes() { 128 return new ArrayList<MmiCode>(0); 129 } 130 131 @Override getDataConnectionState()132 public PhoneConstants.DataState getDataConnectionState() { 133 return PhoneConstants.DataState.DISCONNECTED; 134 } 135 136 @Override getDataActivityState()137 public DataActivityState getDataActivityState() { 138 return DataActivityState.NONE; 139 } 140 141 /** 142 * SIP phones do not have a subscription id, so do not notify of specific phone state changes. 143 */ notifyPhoneStateChanged()144 /* package */ void notifyPhoneStateChanged() { 145 // Do nothing. 146 } 147 148 /** 149 * Notify registrants of a change in the call state. This notifies changes in 150 * {@link com.android.internal.telephony.Call.State}. Use this when changes 151 * in the precise call state are needed, else use notifyPhoneStateChanged. 152 */ notifyPreciseCallStateChanged()153 /* package */ void notifyPreciseCallStateChanged() { 154 /* we'd love it if this was package-scoped*/ 155 super.notifyPreciseCallStateChangedP(); 156 } 157 notifyNewRingingConnection(Connection c)158 void notifyNewRingingConnection(Connection c) { 159 super.notifyNewRingingConnectionP(c); 160 } 161 notifyDisconnect(Connection cn)162 void notifyDisconnect(Connection cn) { 163 mDisconnectRegistrants.notifyResult(cn); 164 } 165 notifyUnknownConnection()166 void notifyUnknownConnection() { 167 mUnknownConnectionRegistrants.notifyResult(this); 168 } 169 notifySuppServiceFailed(SuppService code)170 void notifySuppServiceFailed(SuppService code) { 171 mSuppServiceFailedRegistrants.notifyResult(code); 172 } 173 notifyServiceStateChanged(ServiceState ss)174 void notifyServiceStateChanged(ServiceState ss) { 175 super.notifyServiceStateChangedP(ss); 176 } 177 178 @Override notifyCallForwardingIndicator()179 public void notifyCallForwardingIndicator() { 180 mNotifier.notifyCallForwardingChanged(this); 181 } 182 canDial()183 public boolean canDial() { 184 int serviceState = getServiceState().getState(); 185 Rlog.v(LOG_TAG, "canDial(): serviceState = " + serviceState); 186 if (serviceState == ServiceState.STATE_POWER_OFF) return false; 187 188 boolean disableCall = TelephonyProperties.disable_call().orElse(false); 189 Rlog.v(LOG_TAG, "canDial(): disableCall = " + disableCall); 190 if (disableCall) return false; 191 192 Rlog.v(LOG_TAG, "canDial(): ringingCall: " + getRingingCall().getState()); 193 Rlog.v(LOG_TAG, "canDial(): foregndCall: " + getForegroundCall().getState()); 194 Rlog.v(LOG_TAG, "canDial(): backgndCall: " + getBackgroundCall().getState()); 195 return !getRingingCall().isRinging() 196 && (!getForegroundCall().getState().isAlive() 197 || !getBackgroundCall().getState().isAlive()); 198 } 199 200 @Override handleInCallMmiCommands(String dialString)201 public boolean handleInCallMmiCommands(String dialString) { 202 return false; 203 } 204 isInCall()205 boolean isInCall() { 206 Call.State foregroundCallState = getForegroundCall().getState(); 207 Call.State backgroundCallState = getBackgroundCall().getState(); 208 Call.State ringingCallState = getRingingCall().getState(); 209 210 return (foregroundCallState.isAlive() || backgroundCallState.isAlive() 211 || ringingCallState.isAlive()); 212 } 213 214 @Override handlePinMmi(String dialString)215 public boolean handlePinMmi(String dialString) { 216 return false; 217 } 218 219 @Override handleUssdRequest(String dialString, ResultReceiver wrappedCallback)220 public boolean handleUssdRequest(String dialString, ResultReceiver wrappedCallback) { 221 return false; 222 } 223 224 @Override sendUssdResponse(String ussdMessge)225 public void sendUssdResponse(String ussdMessge) { 226 } 227 228 @Override registerForSuppServiceNotification( Handler h, int what, Object obj)229 public void registerForSuppServiceNotification( 230 Handler h, int what, Object obj) { 231 } 232 233 @Override unregisterForSuppServiceNotification(Handler h)234 public void unregisterForSuppServiceNotification(Handler h) { 235 } 236 237 @Override setRadioPower(boolean power)238 public void setRadioPower(boolean power) { 239 } 240 241 @Override getVoiceMailNumber()242 public String getVoiceMailNumber() { 243 return null; 244 } 245 246 @Override getVoiceMailAlphaTag()247 public String getVoiceMailAlphaTag() { 248 return null; 249 } 250 251 @Override getDeviceId()252 public String getDeviceId() { 253 return null; 254 } 255 256 @Override getDeviceSvn()257 public String getDeviceSvn() { 258 return null; 259 } 260 261 @Override getImei()262 public String getImei() { 263 return null; 264 } 265 266 @Override getEsn()267 public String getEsn() { 268 Rlog.e(LOG_TAG, "[SipPhone] getEsn() is a CDMA method"); 269 return "0"; 270 } 271 272 @Override getMeid()273 public String getMeid() { 274 Rlog.e(LOG_TAG, "[SipPhone] getMeid() is a CDMA method"); 275 return "0"; 276 } 277 278 @Override getSubscriberId()279 public String getSubscriberId() { 280 return null; 281 } 282 283 @Override getGroupIdLevel1()284 public String getGroupIdLevel1() { 285 return null; 286 } 287 288 @Override getGroupIdLevel2()289 public String getGroupIdLevel2() { 290 return null; 291 } 292 293 @Override getIccSerialNumber()294 public String getIccSerialNumber() { 295 return null; 296 } 297 298 @Override getLine1Number()299 public String getLine1Number() { 300 return null; 301 } 302 303 @Override getLine1AlphaTag()304 public String getLine1AlphaTag() { 305 return null; 306 } 307 308 @Override setLine1Number(String alphaTag, String number, Message onComplete)309 public boolean setLine1Number(String alphaTag, String number, Message onComplete) { 310 // FIXME: what to reply for SIP? 311 return false; 312 } 313 314 @Override setVoiceMailNumber(String alphaTag, String voiceMailNumber, Message onComplete)315 public void setVoiceMailNumber(String alphaTag, String voiceMailNumber, 316 Message onComplete) { 317 // FIXME: what to reply for SIP? 318 AsyncResult.forMessage(onComplete, null, null); 319 onComplete.sendToTarget(); 320 } 321 322 @Override getCallForwardingOption(int commandInterfaceCFReason, Message onComplete)323 public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) { 324 } 325 326 @Override getCallForwardingOption(int commandInterfaceCFReason, int serviceClass, Message onComplete)327 public void getCallForwardingOption(int commandInterfaceCFReason, int serviceClass, 328 Message onComplete) { 329 } 330 331 @Override setCallForwardingOption(int commandInterfaceCFAction, int commandInterfaceCFReason, String dialingNumber, int timerSeconds, Message onComplete)332 public void setCallForwardingOption(int commandInterfaceCFAction, 333 int commandInterfaceCFReason, String dialingNumber, 334 int timerSeconds, Message onComplete) { 335 } 336 337 @Override setCallForwardingOption(int commandInterfaceCFAction, int commandInterfaceCFReason, String dialingNumber, int serviceClass, int timerSeconds, Message onComplete)338 public void setCallForwardingOption(int commandInterfaceCFAction, 339 int commandInterfaceCFReason, String dialingNumber, int serviceClass, 340 int timerSeconds, Message onComplete) { 341 } 342 343 @Override getOutgoingCallerIdDisplay(Message onComplete)344 public void getOutgoingCallerIdDisplay(Message onComplete) { 345 // FIXME: what to reply? 346 AsyncResult.forMessage(onComplete, null, null); 347 onComplete.sendToTarget(); 348 } 349 350 @Override setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, Message onComplete)351 public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode, 352 Message onComplete) { 353 // FIXME: what's this for SIP? 354 AsyncResult.forMessage(onComplete, null, null); 355 onComplete.sendToTarget(); 356 } 357 358 @Override getCallWaiting(Message onComplete)359 public void getCallWaiting(Message onComplete) { 360 AsyncResult.forMessage(onComplete, null, null); 361 onComplete.sendToTarget(); 362 } 363 364 @Override setCallWaiting(boolean enable, Message onComplete)365 public void setCallWaiting(boolean enable, Message onComplete) { 366 Rlog.e(LOG_TAG, "call waiting not supported"); 367 } 368 369 @Override getIccRecordsLoaded()370 public boolean getIccRecordsLoaded() { 371 return false; 372 } 373 374 @Override getIccCard()375 public IccCard getIccCard() { 376 return null; 377 } 378 379 @Override getAvailableNetworks(Message response)380 public void getAvailableNetworks(Message response) { 381 } 382 383 @Override startNetworkScan(NetworkScanRequest nsr, Message response)384 public void startNetworkScan(NetworkScanRequest nsr, Message response) { 385 } 386 387 @Override stopNetworkScan(Message response)388 public void stopNetworkScan(Message response) { 389 } 390 391 @Override setNetworkSelectionModeAutomatic(Message response)392 public void setNetworkSelectionModeAutomatic(Message response) { 393 } 394 395 @Override selectNetworkManually(OperatorInfo network, boolean persistSelection, Message response)396 public void selectNetworkManually(OperatorInfo network, boolean persistSelection, 397 Message response) { 398 } 399 400 @Override setOnPostDialCharacter(Handler h, int what, Object obj)401 public void setOnPostDialCharacter(Handler h, int what, Object obj) { 402 } 403 404 @Override updateServiceLocation()405 public void updateServiceLocation() { 406 } 407 408 @Override enableLocationUpdates()409 public void enableLocationUpdates() { 410 } 411 412 @Override disableLocationUpdates()413 public void disableLocationUpdates() { 414 } 415 416 @Override getDataRoamingEnabled()417 public boolean getDataRoamingEnabled() { 418 return false; 419 } 420 421 @Override setDataRoamingEnabled(boolean enable)422 public void setDataRoamingEnabled(boolean enable) { 423 } 424 425 @Override isUserDataEnabled()426 public boolean isUserDataEnabled() { 427 return false; 428 } 429 enableDataConnectivity()430 public boolean enableDataConnectivity() { 431 return false; 432 } 433 disableDataConnectivity()434 public boolean disableDataConnectivity() { 435 return false; 436 } 437 438 @Override isDataAllowed(int apnType)439 public boolean isDataAllowed(int apnType) { 440 return false; 441 } 442 saveClirSetting(int commandInterfaceCLIRMode)443 public void saveClirSetting(int commandInterfaceCLIRMode) { 444 } 445 446 @Override getIccPhoneBookInterfaceManager()447 public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){ 448 return null; 449 } 450 451 @Override getIccFileHandler()452 public IccFileHandler getIccFileHandler(){ 453 return null; 454 } 455 456 @Override activateCellBroadcastSms(int activate, Message response)457 public void activateCellBroadcastSms(int activate, Message response) { 458 Rlog.e(LOG_TAG, "Error! This functionality is not implemented for SIP."); 459 } 460 461 @Override getCellBroadcastSmsConfig(Message response)462 public void getCellBroadcastSmsConfig(Message response) { 463 Rlog.e(LOG_TAG, "Error! This functionality is not implemented for SIP."); 464 } 465 466 @Override setCellBroadcastSmsConfig(int[] configValuesArray, Message response)467 public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response){ 468 Rlog.e(LOG_TAG, "Error! This functionality is not implemented for SIP."); 469 } 470 471 //@Override 472 @Override needsOtaServiceProvisioning()473 public boolean needsOtaServiceProvisioning() { 474 // FIXME: what's this for SIP? 475 return false; 476 } 477 478 //@Override 479 @Override getLinkProperties(String apnType)480 public LinkProperties getLinkProperties(String apnType) { 481 // FIXME: what's this for SIP? 482 return null; 483 } 484 485 /** 486 * Determines if video calling is enabled. Always {@code false} for SIP. 487 * 488 * @return {@code false} since SIP does not support video calling. 489 */ 490 @Override isVideoEnabled()491 public boolean isVideoEnabled() { 492 return false; 493 } 494 updatePhoneState()495 void updatePhoneState() { 496 PhoneConstants.State oldState = mState; 497 498 if (getRingingCall().isRinging()) { 499 mState = PhoneConstants.State.RINGING; 500 } else if (getForegroundCall().isIdle() 501 && getBackgroundCall().isIdle()) { 502 mState = PhoneConstants.State.IDLE; 503 } else { 504 mState = PhoneConstants.State.OFFHOOK; 505 } 506 507 if (mState != oldState) { 508 Rlog.d(LOG_TAG, " ^^^ new phone state: " + mState); 509 notifyPhoneStateChanged(); 510 } 511 } 512 513 @Override onUpdateIccAvailability()514 protected void onUpdateIccAvailability() { 515 } 516 517 @Override sendEmergencyCallStateChange(boolean callActive)518 public void sendEmergencyCallStateChange(boolean callActive) { 519 } 520 521 @Override setBroadcastEmergencyCallStateChanges(boolean broadcast)522 public void setBroadcastEmergencyCallStateChanges(boolean broadcast) { 523 } 524 525 @Override getCallBarring(String facility, String password, Message onComplete, int serviceClass)526 public void getCallBarring(String facility, String password, Message onComplete, 527 int serviceClass) { 528 } 529 530 @Override setCallBarring(String facility, boolean lockState, String password, Message onComplete, int serviceClass)531 public void setCallBarring(String facility, boolean lockState, String password, 532 Message onComplete, int serviceClass) { 533 } 534 } 535