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