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