PhoneBase.java revision 888c60a7fe1c8f3612ab8e8ec5f2f7ca8f24e766
1/* 2 * Copyright (C) 2007 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; 18 19import android.content.BroadcastReceiver; 20import android.content.Context; 21import android.content.Intent; 22import android.content.IntentFilter; 23import android.content.SharedPreferences; 24import android.net.LinkProperties; 25import android.net.NetworkCapabilities; 26import android.net.wifi.WifiManager; 27import android.os.AsyncResult; 28import android.os.Build; 29import android.os.Handler; 30import android.os.Looper; 31import android.os.Message; 32import android.os.RegistrantList; 33import android.os.SystemProperties; 34import android.preference.PreferenceManager; 35import android.provider.Settings; 36import android.telephony.CellIdentityCdma; 37import android.telephony.CellInfo; 38import android.telephony.CellInfoCdma; 39import android.telephony.DataConnectionRealTimeInfo; 40import android.telephony.VoLteServiceState; 41import android.telephony.Rlog; 42import android.telephony.ServiceState; 43import android.telephony.SignalStrength; 44import android.text.TextUtils; 45 46import com.android.ims.ImsManager; 47import com.android.internal.R; 48import com.android.internal.telephony.dataconnection.DcTrackerBase; 49import com.android.internal.telephony.imsphone.ImsPhone; 50import com.android.internal.telephony.test.SimulatedRadioControl; 51import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; 52import com.android.internal.telephony.uicc.IccFileHandler; 53import com.android.internal.telephony.uicc.IccRecords; 54import com.android.internal.telephony.uicc.IsimRecords; 55import com.android.internal.telephony.uicc.UiccCard; 56import com.android.internal.telephony.uicc.UiccCardApplication; 57import com.android.internal.telephony.uicc.UiccController; 58import com.android.internal.telephony.uicc.UsimServiceTable; 59 60import java.io.FileDescriptor; 61import java.io.PrintWriter; 62import java.util.ArrayList; 63import java.util.List; 64import java.util.concurrent.atomic.AtomicReference; 65 66import static com.android.internal.telephony.PhoneConstants.DEFAULT_SUBSCRIPTION; 67 68/** 69 * (<em>Not for SDK use</em>) 70 * A base implementation for the com.android.internal.telephony.Phone interface. 71 * 72 * Note that implementations of Phone.java are expected to be used 73 * from a single application thread. This should be the same thread that 74 * originally called PhoneFactory to obtain the interface. 75 * 76 * {@hide} 77 * 78 */ 79 80public abstract class PhoneBase extends Handler implements Phone { 81 private static final String LOG_TAG = "PhoneBase"; 82 83 private BroadcastReceiver mImsIntentReceiver = new BroadcastReceiver() { 84 @Override 85 public void onReceive(Context context, Intent intent) { 86 if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_UP)) { 87 mImsServiceReady = true; 88 updateImsPhone(); 89 } else if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)) { 90 mImsServiceReady = false; 91 updateImsPhone(); 92 } 93 } 94 }; 95 96 // Key used to read and write the saved network selection numeric value 97 public static final String NETWORK_SELECTION_KEY = "network_selection_key"; 98 // Key used to read and write the saved network selection operator name 99 public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key"; 100 101 102 // Key used to read/write "disable data connection on boot" pref (used for testing) 103 public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key"; 104 105 /* Event Constants */ 106 protected static final int EVENT_RADIO_AVAILABLE = 1; 107 /** Supplementary Service Notification received. */ 108 protected static final int EVENT_SSN = 2; 109 protected static final int EVENT_SIM_RECORDS_LOADED = 3; 110 protected static final int EVENT_MMI_DONE = 4; 111 protected static final int EVENT_RADIO_ON = 5; 112 protected static final int EVENT_GET_BASEBAND_VERSION_DONE = 6; 113 protected static final int EVENT_USSD = 7; 114 protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 8; 115 protected static final int EVENT_GET_IMEI_DONE = 9; 116 protected static final int EVENT_GET_IMEISV_DONE = 10; 117 protected static final int EVENT_GET_SIM_STATUS_DONE = 11; 118 protected static final int EVENT_SET_CALL_FORWARD_DONE = 12; 119 protected static final int EVENT_GET_CALL_FORWARD_DONE = 13; 120 protected static final int EVENT_CALL_RING = 14; 121 protected static final int EVENT_CALL_RING_CONTINUE = 15; 122 123 // Used to intercept the carrier selection calls so that 124 // we can save the values. 125 protected static final int EVENT_SET_NETWORK_MANUAL_COMPLETE = 16; 126 protected static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE = 17; 127 protected static final int EVENT_SET_CLIR_COMPLETE = 18; 128 protected static final int EVENT_REGISTERED_TO_NETWORK = 19; 129 protected static final int EVENT_SET_VM_NUMBER_DONE = 20; 130 // Events for CDMA support 131 protected static final int EVENT_GET_DEVICE_IDENTITY_DONE = 21; 132 protected static final int EVENT_RUIM_RECORDS_LOADED = 22; 133 protected static final int EVENT_NV_READY = 23; 134 protected static final int EVENT_SET_ENHANCED_VP = 24; 135 protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER = 25; 136 protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26; 137 protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27; 138 // other 139 protected static final int EVENT_SET_NETWORK_AUTOMATIC = 28; 140 protected static final int EVENT_ICC_RECORD_EVENTS = 29; 141 protected static final int EVENT_ICC_CHANGED = 30; 142 // Single Radio Voice Call Continuity 143 protected static final int EVENT_SRVCC_STATE_CHANGED = 31; 144 protected static final int EVENT_INITIATE_SILENT_REDIAL = 32; 145 protected static final int EVENT_LAST = EVENT_INITIATE_SILENT_REDIAL; 146 147 // Key used to read/write current CLIR setting 148 public static final String CLIR_KEY = "clir_key"; 149 150 // Key used to read/write "disable DNS server check" pref (used for testing) 151 public static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key"; 152 153 /** 154 * Small container class used to hold information relevant to 155 * the carrier selection process. operatorNumeric can be "" 156 * if we are looking for automatic selection. operatorAlphaLong is the 157 * corresponding operator name. 158 */ 159 protected static class NetworkSelectMessage { 160 public Message message; 161 public String operatorNumeric; 162 public String operatorAlphaLong; 163 } 164 165 /* Instance Variables */ 166 public CommandsInterface mCi; 167 boolean mDnsCheckDisabled; 168 public DcTrackerBase mDcTracker; 169 boolean mDoesRilSendMultipleCallRing; 170 int mCallRingContinueToken; 171 int mCallRingDelay; 172 public boolean mIsTheCurrentActivePhone = true; 173 boolean mIsVoiceCapable = true; 174 protected UiccController mUiccController = null; 175 public AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>(); 176 public SmsStorageMonitor mSmsStorageMonitor; 177 public SmsUsageMonitor mSmsUsageMonitor; 178 protected AtomicReference<UiccCardApplication> mUiccApplication = 179 new AtomicReference<UiccCardApplication>(); 180 181 private TelephonyTester mTelephonyTester; 182 private final String mName; 183 private final String mActionDetached; 184 private final String mActionAttached; 185 186 // Holds the subscription information 187 protected Subscription mSubscriptionData = null; 188 protected int mPhoneId; 189 190 protected boolean mImsServiceReady = false; 191 protected ImsPhone mImsPhone = null; 192 193 @Override 194 public String getPhoneName() { 195 return mName; 196 } 197 198 /** 199 * Return the ActionDetached string. When this action is received by components 200 * they are to simulate detaching from the network. 201 * 202 * @return com.android.internal.telephony.{mName}.action_detached 203 * {mName} is GSM, CDMA ... 204 */ 205 public String getActionDetached() { 206 return mActionDetached; 207 } 208 209 /** 210 * Return the ActionAttached string. When this action is received by components 211 * they are to simulate attaching to the network. 212 * 213 * @return com.android.internal.telephony.{mName}.action_detached 214 * {mName} is GSM, CDMA ... 215 */ 216 public String getActionAttached() { 217 return mActionAttached; 218 } 219 220 /** 221 * Set a system property, unless we're in unit test mode 222 */ 223 // CAF_MSIM TODO this need to be replated with TelephonyManager API ? 224 public void setSystemProperty(String property, String value) { 225 if(getUnitTestMode()) { 226 return; 227 } 228 SystemProperties.set(property, value); 229 } 230 231 232 protected final RegistrantList mPreciseCallStateRegistrants 233 = new RegistrantList(); 234 235 protected final RegistrantList mNewRingingConnectionRegistrants 236 = new RegistrantList(); 237 238 protected final RegistrantList mIncomingRingRegistrants 239 = new RegistrantList(); 240 241 protected final RegistrantList mDisconnectRegistrants 242 = new RegistrantList(); 243 244 protected final RegistrantList mServiceStateRegistrants 245 = new RegistrantList(); 246 247 protected final RegistrantList mMmiCompleteRegistrants 248 = new RegistrantList(); 249 250 protected final RegistrantList mMmiRegistrants 251 = new RegistrantList(); 252 253 protected final RegistrantList mUnknownConnectionRegistrants 254 = new RegistrantList(); 255 256 protected final RegistrantList mSuppServiceFailedRegistrants 257 = new RegistrantList(); 258 259 protected final RegistrantList mSimRecordsLoadedRegistrants 260 = new RegistrantList(); 261 262 protected Looper mLooper; /* to insure registrants are in correct thread*/ 263 264 protected final Context mContext; 265 266 /** 267 * PhoneNotifier is an abstraction for all system-wide 268 * state change notification. DefaultPhoneNotifier is 269 * used here unless running we're inside a unit test. 270 */ 271 protected PhoneNotifier mNotifier; 272 273 protected SimulatedRadioControl mSimulatedRadioControl; 274 275 boolean mUnitTestMode; 276 277 /** 278 * Constructs a PhoneBase in normal (non-unit test) mode. 279 * 280 * @param notifier An instance of DefaultPhoneNotifier, 281 * @param context Context object from hosting application 282 * unless unit testing. 283 * @param ci the CommandsInterface 284 */ 285 protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci) { 286 this(name, notifier, context, ci, false); 287 } 288 289 /** 290 * Constructs a PhoneBase in normal (non-unit test) mode. 291 * 292 * @param notifier An instance of DefaultPhoneNotifier, 293 * @param context Context object from hosting application 294 * unless unit testing. 295 * @param ci is CommandsInterface 296 * @param unitTestMode when true, prevents notifications 297 * of state change events 298 */ 299 protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, 300 boolean unitTestMode) { 301 this(name, notifier, context, ci, unitTestMode, DEFAULT_SUBSCRIPTION); 302 } 303 304 /** 305 * Constructs a PhoneBase in normal (non-unit test) mode. 306 * 307 * @param notifier An instance of DefaultPhoneNotifier, 308 * @param context Context object from hosting application 309 * unless unit testing. 310 * @param ci is CommandsInterface 311 * @param unitTestMode when true, prevents notifications 312 * of state change events 313 * @param subscription is current phone subscription 314 */ 315 protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, 316 boolean unitTestMode, int phoneId) { 317 mPhoneId = phoneId; 318 mName = name; 319 mNotifier = notifier; 320 mContext = context; 321 mLooper = Looper.myLooper(); 322 mCi = ci; 323 mActionDetached = this.getClass().getPackage().getName() + ".action_detached"; 324 mActionAttached = this.getClass().getPackage().getName() + ".action_attached"; 325 326 if (Build.IS_DEBUGGABLE) { 327 mTelephonyTester = new TelephonyTester(this); 328 } 329 330 setUnitTestMode(unitTestMode); 331 332 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); 333 mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false); 334 mCi.setOnCallRing(this, EVENT_CALL_RING, null); 335 336 /* "Voice capable" means that this device supports circuit-switched 337 * (i.e. voice) phone calls over the telephony network, and is allowed 338 * to display the in-call UI while a cellular voice call is active. 339 * This will be false on "data only" devices which can't make voice 340 * calls and don't support any in-call UI. 341 */ 342 mIsVoiceCapable = mContext.getResources().getBoolean( 343 com.android.internal.R.bool.config_voice_capable); 344 345 /** 346 * Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs 347 * to be generated locally. Ideally all ring tones should be loops 348 * and this wouldn't be necessary. But to minimize changes to upper 349 * layers it is requested that it be generated by lower layers. 350 * 351 * By default old phones won't have the property set but do generate 352 * the RIL_UNSOL_CALL_RING so the default if there is no property is 353 * true. 354 */ 355 mDoesRilSendMultipleCallRing = SystemProperties.getBoolean( 356 TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true); 357 Rlog.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing); 358 359 mCallRingDelay = SystemProperties.getInt( 360 TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000); 361 Rlog.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay); 362 363 if (getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) return; 364 365 setPropertiesByCarrier(); 366 367 // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers. 368 mSmsStorageMonitor = new SmsStorageMonitor(this); 369 mSmsUsageMonitor = new SmsUsageMonitor(context); 370 mUiccController = UiccController.getInstance(); 371 mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null); 372 373 // Monitor IMS service 374 IntentFilter filter = new IntentFilter(); 375 filter.addAction(ImsManager.ACTION_IMS_SERVICE_UP); 376 filter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN); 377 mContext.registerReceiver(mImsIntentReceiver, filter); 378 379 mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null); 380 } 381 382 @Override 383 public void dispose() { 384 synchronized(PhoneProxy.lockForRadioTechnologyChange) { 385 mContext.unregisterReceiver(mImsIntentReceiver); 386 mCi.unSetOnCallRing(this); 387 // Must cleanup all connectionS and needs to use sendMessage! 388 mDcTracker.cleanUpAllConnections(null); 389 mIsTheCurrentActivePhone = false; 390 // Dispose the SMS usage and storage monitors 391 mSmsStorageMonitor.dispose(); 392 mSmsUsageMonitor.dispose(); 393 mUiccController.unregisterForIccChanged(this); 394 mCi.unregisterForSrvccStateChanged(this); 395 396 if (mTelephonyTester != null) { 397 mTelephonyTester.dispose(); 398 } 399 400 if (mImsPhone != null) { 401 mImsPhone.unregisterForSilentRedial(this); 402 mImsPhone.dispose(); 403 } 404 } 405 } 406 407 @Override 408 public void removeReferences() { 409 mSmsStorageMonitor = null; 410 mSmsUsageMonitor = null; 411 mIccRecords.set(null); 412 mUiccApplication.set(null); 413 mDcTracker = null; 414 mUiccController = null; 415 416 if (mImsPhone != null) { 417 mImsPhone.removeReferences(); 418 mImsPhone = null; 419 } 420 } 421 422 /** 423 * When overridden the derived class needs to call 424 * super.handleMessage(msg) so this method has a 425 * a chance to process the message. 426 * 427 * @param msg 428 */ 429 @Override 430 public void handleMessage(Message msg) { 431 AsyncResult ar; 432 433 if (!mIsTheCurrentActivePhone) { 434 Rlog.e(LOG_TAG, "Received message " + msg + 435 "[" + msg.what + "] while being destroyed. Ignoring."); 436 return; 437 } 438 switch(msg.what) { 439 case EVENT_CALL_RING: 440 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState()); 441 ar = (AsyncResult)msg.obj; 442 if (ar.exception == null) { 443 PhoneConstants.State state = getState(); 444 if ((!mDoesRilSendMultipleCallRing) 445 && ((state == PhoneConstants.State.RINGING) || 446 (state == PhoneConstants.State.IDLE))) { 447 mCallRingContinueToken += 1; 448 sendIncomingCallRingNotification(mCallRingContinueToken); 449 } else { 450 notifyIncomingRing(); 451 } 452 } 453 break; 454 455 case EVENT_CALL_RING_CONTINUE: 456 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received stat=" + getState()); 457 if (getState() == PhoneConstants.State.RINGING) { 458 sendIncomingCallRingNotification(msg.arg1); 459 } 460 break; 461 462 case EVENT_ICC_CHANGED: 463 onUpdateIccAvailability(); 464 break; 465 466 // handle the select network completion callbacks. 467 case EVENT_SET_NETWORK_MANUAL_COMPLETE: 468 case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE: 469 handleSetSelectNetwork((AsyncResult) msg.obj); 470 break; 471 472 case EVENT_INITIATE_SILENT_REDIAL: 473 Rlog.d(LOG_TAG, "Event EVENT_INITIATE_SILENT_REDIAL Received"); 474 ar = (AsyncResult) msg.obj; 475 if ((ar.exception == null) && (ar.result != null)) { 476 String dialString = (String) ar.result; 477 if (TextUtils.isEmpty(dialString)) return; 478 try { 479 dialInternal(dialString, null); 480 } catch (CallStateException e) { 481 Rlog.e(LOG_TAG, "silent redial failed: " + e); 482 } 483 } 484 break; 485 486 case EVENT_SRVCC_STATE_CHANGED: 487 ar = (AsyncResult)msg.obj; 488 if (ar.exception == null) { 489 handleSrvccStateChanged((int[]) ar.result); 490 } else { 491 Rlog.e(LOG_TAG, "Srvcc exception: " + ar.exception); 492 } 493 break; 494 495 default: 496 throw new RuntimeException("unexpected event not handled"); 497 } 498 } 499 500 private void handleSrvccStateChanged(int[] ret) { 501 Rlog.d(LOG_TAG, "handleSrvccStateChanged"); 502 503 Connection conn = null; 504 Call.SrvccState srvccState = Call.SrvccState.NONE; 505 if (ret != null && ret.length != 0) { 506 int state = ret[0]; 507 switch(state) { 508 case VoLteServiceState.HANDOVER_STARTED: 509 srvccState = Call.SrvccState.STARTED; 510 if (mImsPhone != null) { 511 conn = mImsPhone.getHandoverConnection(); 512 } else { 513 Rlog.d(LOG_TAG, "HANDOVER_STARTED: mImsPhone null"); 514 } 515 break; 516 case VoLteServiceState.HANDOVER_COMPLETED: 517 srvccState = Call.SrvccState.COMPLETED; 518 if (mImsPhone != null) { 519 mImsPhone.notifySrvccState(srvccState); 520 } else { 521 Rlog.d(LOG_TAG, "HANDOVER_COMPLETED: mImsPhone null"); 522 } 523 break; 524 case VoLteServiceState.HANDOVER_FAILED: 525 case VoLteServiceState.HANDOVER_CANCELED: 526 srvccState = Call.SrvccState.FAILED; 527 break; 528 529 default: 530 //ignore invalid state 531 return; 532 } 533 534 getCallTracker().notifySrvccState(srvccState, conn); 535 536 VoLteServiceState lteState = new VoLteServiceState(state); 537 notifyVoLteServiceStateChanged(lteState); 538 } 539 } 540 541 // Inherited documentation suffices. 542 @Override 543 public Context getContext() { 544 return mContext; 545 } 546 547 // Will be called when icc changed 548 protected abstract void onUpdateIccAvailability(); 549 550 /** 551 * Disables the DNS check (i.e., allows "0.0.0.0"). 552 * Useful for lab testing environment. 553 * @param b true disables the check, false enables. 554 */ 555 @Override 556 public void disableDnsCheck(boolean b) { 557 mDnsCheckDisabled = b; 558 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 559 SharedPreferences.Editor editor = sp.edit(); 560 editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b); 561 editor.apply(); 562 } 563 564 /** 565 * Returns true if the DNS check is currently disabled. 566 */ 567 @Override 568 public boolean isDnsCheckDisabled() { 569 return mDnsCheckDisabled; 570 } 571 572 // Inherited documentation suffices. 573 @Override 574 public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) { 575 checkCorrectThread(h); 576 577 mPreciseCallStateRegistrants.addUnique(h, what, obj); 578 } 579 580 // Inherited documentation suffices. 581 @Override 582 public void unregisterForPreciseCallStateChanged(Handler h) { 583 mPreciseCallStateRegistrants.remove(h); 584 } 585 586 /** 587 * Subclasses of Phone probably want to replace this with a 588 * version scoped to their packages 589 */ 590 protected void notifyPreciseCallStateChangedP() { 591 AsyncResult ar = new AsyncResult(null, this, null); 592 mPreciseCallStateRegistrants.notifyRegistrants(ar); 593 594 mNotifier.notifyPreciseCallState(this); 595 } 596 597 // Inherited documentation suffices. 598 @Override 599 public void registerForUnknownConnection(Handler h, int what, Object obj) { 600 checkCorrectThread(h); 601 602 mUnknownConnectionRegistrants.addUnique(h, what, obj); 603 } 604 605 // Inherited documentation suffices. 606 @Override 607 public void unregisterForUnknownConnection(Handler h) { 608 mUnknownConnectionRegistrants.remove(h); 609 } 610 611 // Inherited documentation suffices. 612 @Override 613 public void registerForNewRingingConnection( 614 Handler h, int what, Object obj) { 615 checkCorrectThread(h); 616 617 mNewRingingConnectionRegistrants.addUnique(h, what, obj); 618 } 619 620 // Inherited documentation suffices. 621 @Override 622 public void unregisterForNewRingingConnection(Handler h) { 623 mNewRingingConnectionRegistrants.remove(h); 624 } 625 626 // Inherited documentation suffices. 627 @Override 628 public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){ 629 mCi.registerForInCallVoicePrivacyOn(h, what, obj); 630 } 631 632 // Inherited documentation suffices. 633 @Override 634 public void unregisterForInCallVoicePrivacyOn(Handler h){ 635 mCi.unregisterForInCallVoicePrivacyOn(h); 636 } 637 638 // Inherited documentation suffices. 639 @Override 640 public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){ 641 mCi.registerForInCallVoicePrivacyOff(h, what, obj); 642 } 643 644 // Inherited documentation suffices. 645 @Override 646 public void unregisterForInCallVoicePrivacyOff(Handler h){ 647 mCi.unregisterForInCallVoicePrivacyOff(h); 648 } 649 650 // Inherited documentation suffices. 651 @Override 652 public void registerForIncomingRing( 653 Handler h, int what, Object obj) { 654 checkCorrectThread(h); 655 656 mIncomingRingRegistrants.addUnique(h, what, obj); 657 } 658 659 // Inherited documentation suffices. 660 @Override 661 public void unregisterForIncomingRing(Handler h) { 662 mIncomingRingRegistrants.remove(h); 663 } 664 665 // Inherited documentation suffices. 666 @Override 667 public void registerForDisconnect(Handler h, int what, Object obj) { 668 checkCorrectThread(h); 669 670 mDisconnectRegistrants.addUnique(h, what, obj); 671 } 672 673 // Inherited documentation suffices. 674 @Override 675 public void unregisterForDisconnect(Handler h) { 676 mDisconnectRegistrants.remove(h); 677 } 678 679 // Inherited documentation suffices. 680 @Override 681 public void registerForSuppServiceFailed(Handler h, int what, Object obj) { 682 checkCorrectThread(h); 683 684 mSuppServiceFailedRegistrants.addUnique(h, what, obj); 685 } 686 687 // Inherited documentation suffices. 688 @Override 689 public void unregisterForSuppServiceFailed(Handler h) { 690 mSuppServiceFailedRegistrants.remove(h); 691 } 692 693 // Inherited documentation suffices. 694 @Override 695 public void registerForMmiInitiate(Handler h, int what, Object obj) { 696 checkCorrectThread(h); 697 698 mMmiRegistrants.addUnique(h, what, obj); 699 } 700 701 // Inherited documentation suffices. 702 @Override 703 public void unregisterForMmiInitiate(Handler h) { 704 mMmiRegistrants.remove(h); 705 } 706 707 // Inherited documentation suffices. 708 @Override 709 public void registerForMmiComplete(Handler h, int what, Object obj) { 710 checkCorrectThread(h); 711 712 mMmiCompleteRegistrants.addUnique(h, what, obj); 713 } 714 715 // Inherited documentation suffices. 716 @Override 717 public void unregisterForMmiComplete(Handler h) { 718 checkCorrectThread(h); 719 720 mMmiCompleteRegistrants.remove(h); 721 } 722 723 public void registerForSimRecordsLoaded(Handler h, int what, Object obj) { 724 logUnexpectedCdmaMethodCall("registerForSimRecordsLoaded"); 725 } 726 727 public void unregisterForSimRecordsLoaded(Handler h) { 728 logUnexpectedCdmaMethodCall("unregisterForSimRecordsLoaded"); 729 } 730 731 @Override 732 public void setNetworkSelectionModeAutomatic(Message response) { 733 // wrap the response message in our own message along with 734 // an empty string (to indicate automatic selection) for the 735 // operator's id. 736 NetworkSelectMessage nsm = new NetworkSelectMessage(); 737 nsm.message = response; 738 nsm.operatorNumeric = ""; 739 nsm.operatorAlphaLong = ""; 740 741 Message msg = obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm); 742 mCi.setNetworkSelectionModeAutomatic(msg); 743 } 744 745 @Override 746 public void selectNetworkManually(OperatorInfo network, Message response) { 747 // wrap the response message in our own message along with 748 // the operator's id. 749 NetworkSelectMessage nsm = new NetworkSelectMessage(); 750 nsm.message = response; 751 nsm.operatorNumeric = network.getOperatorNumeric(); 752 nsm.operatorAlphaLong = network.getOperatorAlphaLong(); 753 754 Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm); 755 mCi.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg); 756 } 757 758 /** 759 * Used to track the settings upon completion of the network change. 760 */ 761 private void handleSetSelectNetwork(AsyncResult ar) { 762 // look for our wrapper within the asyncresult, skip the rest if it 763 // is null. 764 if (!(ar.userObj instanceof NetworkSelectMessage)) { 765 Rlog.e(LOG_TAG, "unexpected result from user object."); 766 return; 767 } 768 769 NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj; 770 771 // found the object, now we send off the message we had originally 772 // attached to the request. 773 if (nsm.message != null) { 774 AsyncResult.forMessage(nsm.message, ar.result, ar.exception); 775 nsm.message.sendToTarget(); 776 } 777 778 // open the shared preferences editor, and write the value. 779 // nsm.operatorNumeric is "" if we're in automatic.selection. 780 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 781 SharedPreferences.Editor editor = sp.edit(); 782 editor.putString(NETWORK_SELECTION_KEY, nsm.operatorNumeric); 783 editor.putString(NETWORK_SELECTION_NAME_KEY, nsm.operatorAlphaLong); 784 785 // commit and log the result. 786 if (!editor.commit()) { 787 Rlog.e(LOG_TAG, "failed to commit network selection preference"); 788 } 789 } 790 791 /** 792 * Method to retrieve the saved operator id from the Shared Preferences 793 */ 794 private String getSavedNetworkSelection() { 795 // open the shared preferences and search with our key. 796 SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); 797 return sp.getString(NETWORK_SELECTION_KEY, ""); 798 } 799 800 /** 801 * Method to restore the previously saved operator id, or reset to 802 * automatic selection, all depending upon the value in the shared 803 * preferences. 804 */ 805 public void restoreSavedNetworkSelection(Message response) { 806 // retrieve the operator id 807 String networkSelection = getSavedNetworkSelection(); 808 809 // set to auto if the id is empty, otherwise select the network. 810 if (TextUtils.isEmpty(networkSelection)) { 811 mCi.setNetworkSelectionModeAutomatic(response); 812 } else { 813 mCi.setNetworkSelectionModeManual(networkSelection, response); 814 } 815 } 816 817 // Inherited documentation suffices. 818 @Override 819 public void setUnitTestMode(boolean f) { 820 mUnitTestMode = f; 821 } 822 823 // Inherited documentation suffices. 824 @Override 825 public boolean getUnitTestMode() { 826 return mUnitTestMode; 827 } 828 829 /** 830 * To be invoked when a voice call Connection disconnects. 831 * 832 * Subclasses of Phone probably want to replace this with a 833 * version scoped to their packages 834 */ 835 protected void notifyDisconnectP(Connection cn) { 836 AsyncResult ar = new AsyncResult(null, cn, null); 837 mDisconnectRegistrants.notifyRegistrants(ar); 838 } 839 840 // Inherited documentation suffices. 841 @Override 842 public void registerForServiceStateChanged( 843 Handler h, int what, Object obj) { 844 checkCorrectThread(h); 845 846 mServiceStateRegistrants.add(h, what, obj); 847 } 848 849 // Inherited documentation suffices. 850 @Override 851 public void unregisterForServiceStateChanged(Handler h) { 852 mServiceStateRegistrants.remove(h); 853 } 854 855 // Inherited documentation suffices. 856 @Override 857 public void registerForRingbackTone(Handler h, int what, Object obj) { 858 mCi.registerForRingbackTone(h, what, obj); 859 } 860 861 // Inherited documentation suffices. 862 @Override 863 public void unregisterForRingbackTone(Handler h) { 864 mCi.unregisterForRingbackTone(h); 865 } 866 867 // Inherited documentation suffices. 868 @Override 869 public void registerForOnHoldTone(Handler h, int what, Object obj) { 870 } 871 872 // Inherited documentation suffices. 873 @Override 874 public void unregisterForOnHoldTone(Handler h) { 875 } 876 877 // Inherited documentation suffices. 878 @Override 879 public void registerForResendIncallMute(Handler h, int what, Object obj) { 880 mCi.registerForResendIncallMute(h, what, obj); 881 } 882 883 // Inherited documentation suffices. 884 @Override 885 public void unregisterForResendIncallMute(Handler h) { 886 mCi.unregisterForResendIncallMute(h); 887 } 888 889 @Override 890 public void setEchoSuppressionEnabled() { 891 // no need for regular phone 892 } 893 894 /** 895 * Subclasses of Phone probably want to replace this with a 896 * version scoped to their packages 897 */ 898 protected void notifyServiceStateChangedP(ServiceState ss) { 899 AsyncResult ar = new AsyncResult(null, ss, null); 900 mServiceStateRegistrants.notifyRegistrants(ar); 901 902 mNotifier.notifyServiceState(this); 903 } 904 905 // Inherited documentation suffices. 906 @Override 907 public SimulatedRadioControl getSimulatedRadioControl() { 908 return mSimulatedRadioControl; 909 } 910 911 /** 912 * Verifies the current thread is the same as the thread originally 913 * used in the initialization of this instance. Throws RuntimeException 914 * if not. 915 * 916 * @exception RuntimeException if the current thread is not 917 * the thread that originally obtained this PhoneBase instance. 918 */ 919 private void checkCorrectThread(Handler h) { 920 if (h.getLooper() != mLooper) { 921 throw new RuntimeException( 922 "com.android.internal.telephony.Phone must be used from within one thread"); 923 } 924 } 925 926 /** 927 * Set the properties by matching the carrier string in 928 * a string-array resource 929 */ 930 private void setPropertiesByCarrier() { 931 String carrier = SystemProperties.get("ro.carrier"); 932 933 if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) { 934 return; 935 } 936 937 CharSequence[] carrierLocales = mContext. 938 getResources().getTextArray(R.array.carrier_properties); 939 940 for (int i = 0; i < carrierLocales.length; i+=3) { 941 String c = carrierLocales[i].toString(); 942 if (carrier.equals(c)) { 943 String l = carrierLocales[i+1].toString(); 944 945 String language = l.substring(0, 2); 946 String country = ""; 947 if (l.length() >=5) { 948 country = l.substring(3, 5); 949 } 950 MccTable.setSystemLocale(mContext, language, country); 951 952 if (!country.isEmpty()) { 953 try { 954 Settings.Global.getInt(mContext.getContentResolver(), 955 Settings.Global.WIFI_COUNTRY_CODE); 956 } catch (Settings.SettingNotFoundException e) { 957 // note this is not persisting 958 WifiManager wM = (WifiManager) 959 mContext.getSystemService(Context.WIFI_SERVICE); 960 wM.setCountryCode(country, false); 961 } 962 } 963 return; 964 } 965 } 966 } 967 968 /** 969 * Get state 970 */ 971 @Override 972 public abstract PhoneConstants.State getState(); 973 974 /** 975 * Retrieves the IccFileHandler of the Phone instance 976 */ 977 public IccFileHandler getIccFileHandler(){ 978 UiccCardApplication uiccApplication = mUiccApplication.get(); 979 IccFileHandler fh; 980 981 if (uiccApplication == null) { 982 Rlog.d(LOG_TAG, "getIccFileHandler: uiccApplication == null, return null"); 983 fh = null; 984 } else { 985 fh = uiccApplication.getIccFileHandler(); 986 } 987 988 Rlog.d(LOG_TAG, "getIccFileHandler: fh=" + fh); 989 return fh; 990 } 991 992 /* 993 * Retrieves the Handler of the Phone instance 994 */ 995 public Handler getHandler() { 996 return this; 997 } 998 999 @Override 1000 public void updatePhoneObject(int voiceRadioTech) { 1001 // Only the PhoneProxy can update the phone object. 1002 PhoneFactory.getDefaultPhone().updatePhoneObject(voiceRadioTech); 1003 } 1004 1005 /** 1006 * Retrieves the ServiceStateTracker of the phone instance. 1007 */ 1008 public ServiceStateTracker getServiceStateTracker() { 1009 return null; 1010 } 1011 1012 /** 1013 * Get call tracker 1014 */ 1015 public CallTracker getCallTracker() { 1016 return null; 1017 } 1018 1019 public AppType getCurrentUiccAppType() { 1020 UiccCardApplication currentApp = mUiccApplication.get(); 1021 if (currentApp != null) { 1022 return currentApp.getType(); 1023 } 1024 return AppType.APPTYPE_UNKNOWN; 1025 } 1026 1027 @Override 1028 public IccCard getIccCard() { 1029 return null; 1030 //throw new Exception("getIccCard Shouldn't be called from PhoneBase"); 1031 } 1032 1033 @Override 1034 public String getIccSerialNumber() { 1035 IccRecords r = mIccRecords.get(); 1036 return (r != null) ? r.getIccId() : null; 1037 } 1038 1039 @Override 1040 public boolean getIccRecordsLoaded() { 1041 IccRecords r = mIccRecords.get(); 1042 return (r != null) ? r.getRecordsLoaded() : false; 1043 } 1044 1045 /** 1046 * @return all available cell information or null if none. 1047 */ 1048 @Override 1049 public List<CellInfo> getAllCellInfo() { 1050 List<CellInfo> cellInfoList = getServiceStateTracker().getAllCellInfo(); 1051 return privatizeCellInfoList(cellInfoList); 1052 } 1053 1054 /** 1055 * Clear CDMA base station lat/long values if location setting is disabled. 1056 * @param cellInfoList the original cell info list from the RIL 1057 * @return the original list with CDMA lat/long cleared if necessary 1058 */ 1059 private List<CellInfo> privatizeCellInfoList(List<CellInfo> cellInfoList) { 1060 int mode = Settings.Secure.getInt(getContext().getContentResolver(), 1061 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF); 1062 if (mode == Settings.Secure.LOCATION_MODE_OFF) { 1063 ArrayList<CellInfo> privateCellInfoList = new ArrayList<CellInfo>(cellInfoList.size()); 1064 // clear lat/lon values for location privacy 1065 for (CellInfo c : cellInfoList) { 1066 if (c instanceof CellInfoCdma) { 1067 CellInfoCdma cellInfoCdma = (CellInfoCdma) c; 1068 CellIdentityCdma cellIdentity = cellInfoCdma.getCellIdentity(); 1069 CellIdentityCdma maskedCellIdentity = new CellIdentityCdma( 1070 cellIdentity.getNetworkId(), 1071 cellIdentity.getSystemId(), 1072 cellIdentity.getBasestationId(), 1073 Integer.MAX_VALUE, Integer.MAX_VALUE); 1074 CellInfoCdma privateCellInfoCdma = new CellInfoCdma(cellInfoCdma); 1075 privateCellInfoCdma.setCellIdentity(maskedCellIdentity); 1076 privateCellInfoList.add(privateCellInfoCdma); 1077 } else { 1078 privateCellInfoList.add(c); 1079 } 1080 } 1081 cellInfoList = privateCellInfoList; 1082 } 1083 return cellInfoList; 1084 } 1085 1086 /** 1087 * {@inheritDoc} 1088 */ 1089 @Override 1090 public void setCellInfoListRate(int rateInMillis) { 1091 mCi.setCellInfoListRate(rateInMillis, null); 1092 } 1093 1094 @Override 1095 public boolean getMessageWaitingIndicator() { 1096 IccRecords r = mIccRecords.get(); 1097 return (r != null) ? r.getVoiceMessageWaiting() : false; 1098 } 1099 1100 @Override 1101 public boolean getCallForwardingIndicator() { 1102 IccRecords r = mIccRecords.get(); 1103 return (r != null) ? r.getVoiceCallForwardingFlag() : false; 1104 } 1105 1106 /** 1107 * Query the status of the CDMA roaming preference 1108 */ 1109 @Override 1110 public void queryCdmaRoamingPreference(Message response) { 1111 mCi.queryCdmaRoamingPreference(response); 1112 } 1113 1114 /** 1115 * Get the signal strength 1116 */ 1117 @Override 1118 public SignalStrength getSignalStrength() { 1119 ServiceStateTracker sst = getServiceStateTracker(); 1120 if (sst == null) { 1121 return new SignalStrength(); 1122 } else { 1123 return sst.getSignalStrength(); 1124 } 1125 } 1126 1127 /** 1128 * Set the status of the CDMA roaming preference 1129 */ 1130 @Override 1131 public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) { 1132 mCi.setCdmaRoamingPreference(cdmaRoamingType, response); 1133 } 1134 1135 /** 1136 * Set the status of the CDMA subscription mode 1137 */ 1138 @Override 1139 public void setCdmaSubscription(int cdmaSubscriptionType, Message response) { 1140 mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response); 1141 } 1142 1143 /** 1144 * Set the preferred Network Type: Global, CDMA only or GSM/UMTS only 1145 */ 1146 @Override 1147 public void setPreferredNetworkType(int networkType, Message response) { 1148 mCi.setPreferredNetworkType(networkType, response); 1149 } 1150 1151 @Override 1152 public void getPreferredNetworkType(Message response) { 1153 mCi.getPreferredNetworkType(response); 1154 } 1155 1156 @Override 1157 public void getSmscAddress(Message result) { 1158 mCi.getSmscAddress(result); 1159 } 1160 1161 @Override 1162 public void setSmscAddress(String address, Message result) { 1163 mCi.setSmscAddress(address, result); 1164 } 1165 1166 @Override 1167 public void setTTYMode(int ttyMode, Message onComplete) { 1168 mCi.setTTYMode(ttyMode, onComplete); 1169 } 1170 1171 @Override 1172 public void queryTTYMode(Message onComplete) { 1173 mCi.queryTTYMode(onComplete); 1174 } 1175 1176 @Override 1177 public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) { 1178 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1179 logUnexpectedCdmaMethodCall("enableEnhancedVoicePrivacy"); 1180 } 1181 1182 @Override 1183 public void getEnhancedVoicePrivacy(Message onComplete) { 1184 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1185 logUnexpectedCdmaMethodCall("getEnhancedVoicePrivacy"); 1186 } 1187 1188 @Override 1189 public void setBandMode(int bandMode, Message response) { 1190 mCi.setBandMode(bandMode, response); 1191 } 1192 1193 @Override 1194 public void queryAvailableBandMode(Message response) { 1195 mCi.queryAvailableBandMode(response); 1196 } 1197 1198 @Override 1199 public void invokeOemRilRequestRaw(byte[] data, Message response) { 1200 mCi.invokeOemRilRequestRaw(data, response); 1201 } 1202 1203 @Override 1204 public void invokeOemRilRequestStrings(String[] strings, Message response) { 1205 mCi.invokeOemRilRequestStrings(strings, response); 1206 } 1207 1208 @Override 1209 public void nvReadItem(int itemID, Message response) { 1210 mCi.nvReadItem(itemID, response); 1211 } 1212 1213 @Override 1214 public void nvWriteItem(int itemID, String itemValue, Message response) { 1215 mCi.nvWriteItem(itemID, itemValue, response); 1216 } 1217 1218 @Override 1219 public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message response) { 1220 mCi.nvWriteCdmaPrl(preferredRoamingList, response); 1221 } 1222 1223 @Override 1224 public void nvResetConfig(int resetType, Message response) { 1225 mCi.nvResetConfig(resetType, response); 1226 } 1227 1228 @Override 1229 public void notifyDataActivity() { 1230 mNotifier.notifyDataActivity(this); 1231 } 1232 1233 public void notifyMessageWaitingIndicator() { 1234 // Do not notify voice mail waiting if device doesn't support voice 1235 if (!mIsVoiceCapable) 1236 return; 1237 1238 // This function is added to send the notification to DefaultPhoneNotifier. 1239 mNotifier.notifyMessageWaitingChanged(this); 1240 } 1241 1242 public void notifyDataConnection(String reason, String apnType, 1243 PhoneConstants.DataState state) { 1244 mNotifier.notifyDataConnection(this, reason, apnType, state); 1245 } 1246 1247 public void notifyDataConnection(String reason, String apnType) { 1248 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 1249 } 1250 1251 public void notifyDataConnection(String reason) { 1252 String types[] = getActiveApnTypes(); 1253 for (String apnType : types) { 1254 mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType)); 1255 } 1256 } 1257 1258 public void notifyOtaspChanged(int otaspMode) { 1259 mNotifier.notifyOtaspChanged(this, otaspMode); 1260 } 1261 1262 public void notifySignalStrength() { 1263 mNotifier.notifySignalStrength(this); 1264 } 1265 1266 public void notifyCellInfo(List<CellInfo> cellInfo) { 1267 mNotifier.notifyCellInfo(this, privatizeCellInfoList(cellInfo)); 1268 } 1269 1270 public void notifyDataConnectionRealTimeInfo(DataConnectionRealTimeInfo dcRtInfo) { 1271 mNotifier.notifyDataConnectionRealTimeInfo(this, dcRtInfo); 1272 } 1273 1274 public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) { 1275 mNotifier.notifyVoLteServiceStateChanged(this, lteState); 1276 } 1277 1278 /** 1279 * @return true if a mobile originating emergency call is active 1280 */ 1281 public boolean isInEmergencyCall() { 1282 return false; 1283 } 1284 1285 /** 1286 * @return true if we are in the emergency call back mode. This is a period where 1287 * the phone should be using as little power as possible and be ready to receive an 1288 * incoming call from the emergency operator. 1289 */ 1290 public boolean isInEcm() { 1291 return false; 1292 } 1293 1294 @Override 1295 public abstract int getPhoneType(); 1296 1297 /** @hide */ 1298 @Override 1299 public int getVoiceMessageCount(){ 1300 return 0; 1301 } 1302 1303 /** 1304 * Returns the CDMA ERI icon index to display 1305 */ 1306 @Override 1307 public int getCdmaEriIconIndex() { 1308 logUnexpectedCdmaMethodCall("getCdmaEriIconIndex"); 1309 return -1; 1310 } 1311 1312 /** 1313 * Returns the CDMA ERI icon mode, 1314 * 0 - ON 1315 * 1 - FLASHING 1316 */ 1317 @Override 1318 public int getCdmaEriIconMode() { 1319 logUnexpectedCdmaMethodCall("getCdmaEriIconMode"); 1320 return -1; 1321 } 1322 1323 /** 1324 * Returns the CDMA ERI text, 1325 */ 1326 @Override 1327 public String getCdmaEriText() { 1328 logUnexpectedCdmaMethodCall("getCdmaEriText"); 1329 return "GSM nw, no ERI"; 1330 } 1331 1332 @Override 1333 public String getCdmaMin() { 1334 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1335 logUnexpectedCdmaMethodCall("getCdmaMin"); 1336 return null; 1337 } 1338 1339 @Override 1340 public boolean isMinInfoReady() { 1341 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1342 logUnexpectedCdmaMethodCall("isMinInfoReady"); 1343 return false; 1344 } 1345 1346 @Override 1347 public String getCdmaPrlVersion(){ 1348 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1349 logUnexpectedCdmaMethodCall("getCdmaPrlVersion"); 1350 return null; 1351 } 1352 1353 @Override 1354 public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) { 1355 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1356 logUnexpectedCdmaMethodCall("sendBurstDtmf"); 1357 } 1358 1359 @Override 1360 public void exitEmergencyCallbackMode() { 1361 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1362 logUnexpectedCdmaMethodCall("exitEmergencyCallbackMode"); 1363 } 1364 1365 @Override 1366 public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) { 1367 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1368 logUnexpectedCdmaMethodCall("registerForCdmaOtaStatusChange"); 1369 } 1370 1371 @Override 1372 public void unregisterForCdmaOtaStatusChange(Handler h) { 1373 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1374 logUnexpectedCdmaMethodCall("unregisterForCdmaOtaStatusChange"); 1375 } 1376 1377 @Override 1378 public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) { 1379 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1380 logUnexpectedCdmaMethodCall("registerForSubscriptionInfoReady"); 1381 } 1382 1383 @Override 1384 public void unregisterForSubscriptionInfoReady(Handler h) { 1385 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1386 logUnexpectedCdmaMethodCall("unregisterForSubscriptionInfoReady"); 1387 } 1388 1389 /** 1390 * Returns true if OTA Service Provisioning needs to be performed. 1391 * If not overridden return false. 1392 */ 1393 @Override 1394 public boolean needsOtaServiceProvisioning() { 1395 return false; 1396 } 1397 1398 /** 1399 * Return true if number is an OTASP number. 1400 * If not overridden return false. 1401 */ 1402 @Override 1403 public boolean isOtaSpNumber(String dialStr) { 1404 return false; 1405 } 1406 1407 @Override 1408 public void registerForCallWaiting(Handler h, int what, Object obj){ 1409 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1410 logUnexpectedCdmaMethodCall("registerForCallWaiting"); 1411 } 1412 1413 @Override 1414 public void unregisterForCallWaiting(Handler h){ 1415 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1416 logUnexpectedCdmaMethodCall("unregisterForCallWaiting"); 1417 } 1418 1419 @Override 1420 public void registerForEcmTimerReset(Handler h, int what, Object obj) { 1421 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1422 logUnexpectedCdmaMethodCall("registerForEcmTimerReset"); 1423 } 1424 1425 @Override 1426 public void unregisterForEcmTimerReset(Handler h) { 1427 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1428 logUnexpectedCdmaMethodCall("unregisterForEcmTimerReset"); 1429 } 1430 1431 @Override 1432 public void registerForSignalInfo(Handler h, int what, Object obj) { 1433 mCi.registerForSignalInfo(h, what, obj); 1434 } 1435 1436 @Override 1437 public void unregisterForSignalInfo(Handler h) { 1438 mCi.unregisterForSignalInfo(h); 1439 } 1440 1441 @Override 1442 public void registerForDisplayInfo(Handler h, int what, Object obj) { 1443 mCi.registerForDisplayInfo(h, what, obj); 1444 } 1445 1446 @Override 1447 public void unregisterForDisplayInfo(Handler h) { 1448 mCi.unregisterForDisplayInfo(h); 1449 } 1450 1451 @Override 1452 public void registerForNumberInfo(Handler h, int what, Object obj) { 1453 mCi.registerForNumberInfo(h, what, obj); 1454 } 1455 1456 @Override 1457 public void unregisterForNumberInfo(Handler h) { 1458 mCi.unregisterForNumberInfo(h); 1459 } 1460 1461 @Override 1462 public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) { 1463 mCi.registerForRedirectedNumberInfo(h, what, obj); 1464 } 1465 1466 @Override 1467 public void unregisterForRedirectedNumberInfo(Handler h) { 1468 mCi.unregisterForRedirectedNumberInfo(h); 1469 } 1470 1471 @Override 1472 public void registerForLineControlInfo(Handler h, int what, Object obj) { 1473 mCi.registerForLineControlInfo( h, what, obj); 1474 } 1475 1476 @Override 1477 public void unregisterForLineControlInfo(Handler h) { 1478 mCi.unregisterForLineControlInfo(h); 1479 } 1480 1481 @Override 1482 public void registerFoT53ClirlInfo(Handler h, int what, Object obj) { 1483 mCi.registerFoT53ClirlInfo(h, what, obj); 1484 } 1485 1486 @Override 1487 public void unregisterForT53ClirInfo(Handler h) { 1488 mCi.unregisterForT53ClirInfo(h); 1489 } 1490 1491 @Override 1492 public void registerForT53AudioControlInfo(Handler h, int what, Object obj) { 1493 mCi.registerForT53AudioControlInfo( h, what, obj); 1494 } 1495 1496 @Override 1497 public void unregisterForT53AudioControlInfo(Handler h) { 1498 mCi.unregisterForT53AudioControlInfo(h); 1499 } 1500 1501 @Override 1502 public void setOnEcbModeExitResponse(Handler h, int what, Object obj){ 1503 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1504 logUnexpectedCdmaMethodCall("setOnEcbModeExitResponse"); 1505 } 1506 1507 @Override 1508 public void unsetOnEcbModeExitResponse(Handler h){ 1509 // This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone. 1510 logUnexpectedCdmaMethodCall("unsetOnEcbModeExitResponse"); 1511 } 1512 1513 @Override 1514 public String[] getActiveApnTypes() { 1515 return mDcTracker.getActiveApnTypes(); 1516 } 1517 1518 @Override 1519 public String getActiveApnHost(String apnType) { 1520 return mDcTracker.getActiveApnString(apnType); 1521 } 1522 1523 @Override 1524 public LinkProperties getLinkProperties(String apnType) { 1525 return mDcTracker.getLinkProperties(apnType); 1526 } 1527 1528 @Override 1529 public NetworkCapabilities getNetworkCapabilities(String apnType) { 1530 return mDcTracker.getNetworkCapabilities(apnType); 1531 } 1532 1533 @Override 1534 public boolean isDataConnectivityPossible() { 1535 return isDataConnectivityPossible(PhoneConstants.APN_TYPE_DEFAULT); 1536 } 1537 1538 @Override 1539 public boolean isDataConnectivityPossible(String apnType) { 1540 return ((mDcTracker != null) && 1541 (mDcTracker.isDataPossible(apnType))); 1542 } 1543 1544 /** 1545 * Notify registrants of a new ringing Connection. 1546 * Subclasses of Phone probably want to replace this with a 1547 * version scoped to their packages 1548 */ 1549 protected void notifyNewRingingConnectionP(Connection cn) { 1550 if (!mIsVoiceCapable) 1551 return; 1552 AsyncResult ar = new AsyncResult(null, cn, null); 1553 mNewRingingConnectionRegistrants.notifyRegistrants(ar); 1554 } 1555 1556 /** 1557 * Notify registrants of a RING event. 1558 */ 1559 private void notifyIncomingRing() { 1560 if (!mIsVoiceCapable) 1561 return; 1562 AsyncResult ar = new AsyncResult(null, this, null); 1563 mIncomingRingRegistrants.notifyRegistrants(ar); 1564 } 1565 1566 /** 1567 * Send the incoming call Ring notification if conditions are right. 1568 */ 1569 private void sendIncomingCallRingNotification(int token) { 1570 if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing && 1571 (token == mCallRingContinueToken)) { 1572 Rlog.d(LOG_TAG, "Sending notifyIncomingRing"); 1573 notifyIncomingRing(); 1574 sendMessageDelayed( 1575 obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay); 1576 } else { 1577 Rlog.d(LOG_TAG, "Ignoring ring notification request," 1578 + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing 1579 + " token=" + token 1580 + " mCallRingContinueToken=" + mCallRingContinueToken 1581 + " mIsVoiceCapable=" + mIsVoiceCapable); 1582 } 1583 } 1584 1585 @Override 1586 public boolean isCspPlmnEnabled() { 1587 // This function should be overridden by the class GSMPhone. 1588 // Not implemented in CDMAPhone. 1589 logUnexpectedGsmMethodCall("isCspPlmnEnabled"); 1590 return false; 1591 } 1592 1593 @Override 1594 public IsimRecords getIsimRecords() { 1595 Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices"); 1596 return null; 1597 } 1598 1599 @Override 1600 public String getMsisdn() { 1601 logUnexpectedGsmMethodCall("getMsisdn"); 1602 return null; 1603 } 1604 1605 /** 1606 * Common error logger method for unexpected calls to CDMA-only methods. 1607 */ 1608 private static void logUnexpectedCdmaMethodCall(String name) 1609 { 1610 Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + 1611 "called, CDMAPhone inactive."); 1612 } 1613 1614 @Override 1615 public PhoneConstants.DataState getDataConnectionState() { 1616 return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT); 1617 } 1618 1619 /** 1620 * Common error logger method for unexpected calls to GSM/WCDMA-only methods. 1621 */ 1622 private static void logUnexpectedGsmMethodCall(String name) { 1623 Rlog.e(LOG_TAG, "Error! " + name + "() in PhoneBase should not be " + 1624 "called, GSMPhone inactive."); 1625 } 1626 1627 // Called by SimRecords which is constructed with a PhoneBase instead of a GSMPhone. 1628 public void notifyCallForwardingIndicator() { 1629 // This function should be overridden by the class GSMPhone. Not implemented in CDMAPhone. 1630 Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone."); 1631 } 1632 1633 public void notifyDataConnectionFailed(String reason, String apnType) { 1634 mNotifier.notifyDataConnectionFailed(this, reason, apnType); 1635 } 1636 1637 public void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, 1638 String failCause) { 1639 mNotifier.notifyPreciseDataConnectionFailed(this, reason, apnType, apn, failCause); 1640 } 1641 1642 /** 1643 * {@inheritDoc} 1644 */ 1645 @Override 1646 public int getLteOnCdmaMode() { 1647 return mCi.getLteOnCdmaMode(); 1648 } 1649 1650 /** 1651 * Sets the SIM voice message waiting indicator records. 1652 * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported 1653 * @param countWaiting The number of messages waiting, if known. Use 1654 * -1 to indicate that an unknown number of 1655 * messages are waiting 1656 */ 1657 @Override 1658 public void setVoiceMessageWaiting(int line, int countWaiting) { 1659 IccRecords r = mIccRecords.get(); 1660 if (r != null) { 1661 r.setVoiceMessageWaiting(line, countWaiting); 1662 } 1663 } 1664 1665 /** 1666 * Gets the USIM service table from the UICC, if present and available. 1667 * @return an interface to the UsimServiceTable record, or null if not available 1668 */ 1669 @Override 1670 public UsimServiceTable getUsimServiceTable() { 1671 IccRecords r = mIccRecords.get(); 1672 return (r != null) ? r.getUsimServiceTable() : null; 1673 } 1674 1675 /** 1676 * Gets the Uicc card corresponding to this phone. 1677 * @return the UiccCard object corresponding to the phone ID. 1678 */ 1679 @Override 1680 public UiccCard getUiccCard() { 1681 return mUiccController.getUiccCard(mPhoneId); 1682 } 1683 1684 /** 1685 * Get P-CSCF address from PCO after data connection is established or modified. 1686 */ 1687 @Override 1688 public String[] getPcscfAddress() { 1689 return mDcTracker.getPcscfAddress(); 1690 } 1691 1692 /** 1693 * Set IMS registration state 1694 */ 1695 @Override 1696 public void setImsRegistrationState(boolean registered) { 1697 mDcTracker.setImsRegistrationState(registered); 1698 } 1699 1700 /** 1701 * Return an instance of a IMS phone 1702 */ 1703 @Override 1704 public Phone getImsPhone() { 1705 return mImsPhone; 1706 } 1707 1708 protected void updateImsPhone() { 1709 Rlog.d(LOG_TAG, "updateImsPhone" 1710 + " mImsServiceReady=" + mImsServiceReady); 1711 1712 if (mImsServiceReady && (mImsPhone == null)) { 1713 mImsPhone = PhoneFactory.makeImsPhone(mNotifier, this); 1714 CallManager.getInstance().registerPhone(mImsPhone); 1715 mImsPhone.registerForSilentRedial( 1716 this, EVENT_INITIATE_SILENT_REDIAL, null); 1717 } else if (!mImsServiceReady && (mImsPhone != null)) { 1718 CallManager.getInstance().unregisterPhone(mImsPhone); 1719 mImsPhone.unregisterForSilentRedial(this); 1720 1721 mImsPhone.dispose(); 1722 mImsPhone.removeReferences(); 1723 mImsPhone = null; 1724 } 1725 } 1726 1727 protected Connection dialInternal(String dialString, UUSInfo uusInfo) 1728 throws CallStateException { 1729 // dialInternal shall be overriden by GSMPhone and CDMAPhone 1730 return null; 1731 } 1732 1733 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1734 pw.println("PhoneBase:"); 1735 pw.println(" mCi=" + mCi); 1736 pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled); 1737 pw.println(" mDcTracker=" + mDcTracker); 1738 pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing); 1739 pw.println(" mCallRingContinueToken=" + mCallRingContinueToken); 1740 pw.println(" mCallRingDelay=" + mCallRingDelay); 1741 pw.println(" mIsTheCurrentActivePhone=" + mIsTheCurrentActivePhone); 1742 pw.println(" mIsVoiceCapable=" + mIsVoiceCapable); 1743 pw.println(" mIccRecords=" + mIccRecords.get()); 1744 pw.println(" mUiccApplication=" + mUiccApplication.get()); 1745 pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor); 1746 pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor); 1747 pw.flush(); 1748 pw.println(" mLooper=" + mLooper); 1749 pw.println(" mContext=" + mContext); 1750 pw.println(" mNotifier=" + mNotifier); 1751 pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl); 1752 pw.println(" mUnitTestMode=" + mUnitTestMode); 1753 pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled()); 1754 pw.println(" getUnitTestMode()=" + getUnitTestMode()); 1755 pw.println(" getState()=" + getState()); 1756 pw.println(" getIccSerialNumber()=" + getIccSerialNumber()); 1757 pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded()); 1758 pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator()); 1759 pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator()); 1760 pw.println(" isInEmergencyCall()=" + isInEmergencyCall()); 1761 pw.flush(); 1762 pw.println(" isInEcm()=" + isInEcm()); 1763 pw.println(" getPhoneName()=" + getPhoneName()); 1764 pw.println(" getPhoneType()=" + getPhoneType()); 1765 pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount()); 1766 pw.println(" getActiveApnTypes()=" + getActiveApnTypes()); 1767 pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible()); 1768 pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning()); 1769 } 1770 1771 /** 1772 * Returns the subscription id. 1773 */ 1774 public long getSubId() { 1775 long [] subId = SubscriptionController.getInstance().getSubId(mPhoneId); 1776 return subId[0]; 1777 } 1778 1779 /** 1780 * Returns the phone id. 1781 */ 1782 public int getPhoneId() { 1783 return mPhoneId; 1784 } 1785 1786 //Gets Subscription information in the Phone Object 1787 public Subscription getSubscriptionInfo() { 1788 return mSubscriptionData; 1789 } 1790 1791 /** 1792 * Return the service state of mImsPhone if it is STATE_IN_SERVICE 1793 * otherwise return the current voice service state 1794 */ 1795 @Override 1796 public int getVoicePhoneServiceState() { 1797 if (mImsPhone != null 1798 && mImsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) { 1799 return ServiceState.STATE_IN_SERVICE; 1800 } 1801 return getServiceState().getState(); 1802 } 1803} 1804