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