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