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