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