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