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