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