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