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