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