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