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