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