1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.telephony;
18 
19 import android.annotation.Nullable;
20 import android.annotation.UnsupportedAppUsage;
21 import android.app.BroadcastOptions;
22 import android.content.BroadcastReceiver;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.IntentFilter;
26 import android.content.SharedPreferences;
27 import android.net.LinkProperties;
28 import android.net.NetworkCapabilities;
29 import android.net.NetworkStats;
30 import android.net.Uri;
31 import android.net.wifi.WifiManager;
32 import android.os.AsyncResult;
33 import android.os.Build;
34 import android.os.Handler;
35 import android.os.Looper;
36 import android.os.Message;
37 import android.os.PersistableBundle;
38 import android.os.Registrant;
39 import android.os.RegistrantList;
40 import android.os.SystemClock;
41 import android.os.SystemProperties;
42 import android.os.WorkSource;
43 import android.preference.PreferenceManager;
44 import android.provider.Settings;
45 import android.telecom.VideoProfile;
46 import android.telephony.AccessNetworkConstants;
47 import android.telephony.CarrierConfigManager;
48 import android.telephony.CarrierRestrictionRules;
49 import android.telephony.CellInfo;
50 import android.telephony.CellLocation;
51 import android.telephony.ClientRequestStats;
52 import android.telephony.DataFailCause;
53 import android.telephony.ImsiEncryptionInfo;
54 import android.telephony.PhoneStateListener;
55 import android.telephony.PhysicalChannelConfig;
56 import android.telephony.RadioAccessFamily;
57 import android.telephony.Rlog;
58 import android.telephony.ServiceState;
59 import android.telephony.SignalStrength;
60 import android.telephony.SubscriptionManager;
61 import android.telephony.TelephonyManager;
62 import android.telephony.data.ApnSetting;
63 import android.telephony.data.ApnSetting.ApnType;
64 import android.telephony.emergency.EmergencyNumber;
65 import android.telephony.ims.stub.ImsRegistrationImplBase;
66 import android.text.TextUtils;
67 import android.util.LocalLog;
68 import android.util.SparseArray;
69 
70 import com.android.ims.ImsCall;
71 import com.android.ims.ImsConfig;
72 import com.android.ims.ImsManager;
73 import com.android.internal.R;
74 import com.android.internal.telephony.dataconnection.DataConnectionReasons;
75 import com.android.internal.telephony.dataconnection.DataEnabledSettings;
76 import com.android.internal.telephony.dataconnection.DcTracker;
77 import com.android.internal.telephony.dataconnection.TransportManager;
78 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
79 import com.android.internal.telephony.imsphone.ImsPhoneCall;
80 import com.android.internal.telephony.test.SimulatedRadioControl;
81 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
82 import com.android.internal.telephony.uicc.IccFileHandler;
83 import com.android.internal.telephony.uicc.IccRecords;
84 import com.android.internal.telephony.uicc.IsimRecords;
85 import com.android.internal.telephony.uicc.UiccCard;
86 import com.android.internal.telephony.uicc.UiccCardApplication;
87 import com.android.internal.telephony.uicc.UiccController;
88 import com.android.internal.telephony.uicc.UsimServiceTable;
89 
90 import java.io.FileDescriptor;
91 import java.io.PrintWriter;
92 import java.util.ArrayList;
93 import java.util.Arrays;
94 import java.util.HashSet;
95 import java.util.List;
96 import java.util.Locale;
97 import java.util.Set;
98 import java.util.concurrent.atomic.AtomicReference;
99 
100 /**
101  * (<em>Not for SDK use</em>)
102  * A base implementation for the com.android.internal.telephony.Phone interface.
103  *
104  * Note that implementations of Phone.java are expected to be used
105  * from a single application thread. This should be the same thread that
106  * originally called PhoneFactory to obtain the interface.
107  *
108  *  {@hide}
109  *
110  */
111 
112 public abstract class Phone extends Handler implements PhoneInternalInterface {
113     private static final String LOG_TAG = "Phone";
114 
115     protected final static Object lockForRadioTechnologyChange = new Object();
116 
117     protected final int USSD_MAX_QUEUE = 10;
118 
119     private BroadcastReceiver mImsIntentReceiver = new BroadcastReceiver() {
120         @Override
121         public void onReceive(Context context, Intent intent) {
122             Rlog.d(LOG_TAG, "mImsIntentReceiver: action " + intent.getAction());
123             if (intent.hasExtra(ImsManager.EXTRA_PHONE_ID)) {
124                 int extraPhoneId = intent.getIntExtra(ImsManager.EXTRA_PHONE_ID,
125                         SubscriptionManager.INVALID_PHONE_INDEX);
126                 Rlog.d(LOG_TAG, "mImsIntentReceiver: extraPhoneId = " + extraPhoneId);
127                 if (extraPhoneId == SubscriptionManager.INVALID_PHONE_INDEX ||
128                         extraPhoneId != getPhoneId()) {
129                     return;
130                 }
131             }
132 
133             synchronized (Phone.lockForRadioTechnologyChange) {
134                 if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_UP)) {
135                     mImsServiceReady = true;
136                     updateImsPhone();
137                     ImsManager.getInstance(mContext, mPhoneId).updateImsServiceConfig(false);
138                 } else if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)) {
139                     mImsServiceReady = false;
140                     updateImsPhone();
141                 }
142             }
143         }
144     };
145 
146     // Key used to read and write the saved network selection numeric value
147     public static final String NETWORK_SELECTION_KEY = "network_selection_key";
148     // Key used to read and write the saved network selection operator name
149     public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key";
150     // Key used to read and write the saved network selection operator short name
151     public static final String NETWORK_SELECTION_SHORT_KEY = "network_selection_short_key";
152 
153 
154     // Key used to read/write "disable data connection on boot" pref (used for testing)
155     public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";
156 
157     // Key used to read/write data_roaming_is_user_setting pref
158     public static final String DATA_ROAMING_IS_USER_SETTING_KEY = "data_roaming_is_user_setting_key";
159 
160     // Default value when there has been no last emergency SMS time recorded yet.
161     private static final int EMERGENCY_SMS_NO_TIME_RECORDED = -1;
162     // The max timer value that the platform can be in emergency SMS mode (5 minutes).
163     private static final int EMERGENCY_SMS_TIMER_MAX_MS = 300000;
164 
165     /* Event Constants */
166     protected static final int EVENT_RADIO_AVAILABLE             = 1;
167     /** Supplementary Service Notification received. */
168     protected static final int EVENT_SSN                         = 2;
169     protected static final int EVENT_SIM_RECORDS_LOADED          = 3;
170     private static final int EVENT_MMI_DONE                      = 4;
171     protected static final int EVENT_RADIO_ON                    = 5;
172     protected static final int EVENT_GET_BASEBAND_VERSION_DONE   = 6;
173     protected static final int EVENT_USSD                        = 7;
174     protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE  = 8;
175     protected static final int EVENT_GET_IMEI_DONE               = 9;
176     protected static final int EVENT_GET_IMEISV_DONE             = 10;
177     private static final int EVENT_GET_SIM_STATUS_DONE           = 11;
178     protected static final int EVENT_SET_CALL_FORWARD_DONE       = 12;
179     protected static final int EVENT_GET_CALL_FORWARD_DONE       = 13;
180     protected static final int EVENT_CALL_RING                   = 14;
181     private static final int EVENT_CALL_RING_CONTINUE            = 15;
182 
183     // Used to intercept the carrier selection calls so that
184     // we can save the values.
185     private static final int EVENT_SET_NETWORK_MANUAL_COMPLETE      = 16;
186     private static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE   = 17;
187     protected static final int EVENT_SET_CLIR_COMPLETE              = 18;
188     protected static final int EVENT_REGISTERED_TO_NETWORK          = 19;
189     protected static final int EVENT_SET_VM_NUMBER_DONE             = 20;
190     // Events for CDMA support
191     protected static final int EVENT_GET_DEVICE_IDENTITY_DONE       = 21;
192     protected static final int EVENT_RUIM_RECORDS_LOADED            = 22;
193     protected static final int EVENT_NV_READY                       = 23;
194     private static final int EVENT_SET_ENHANCED_VP                  = 24;
195     protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER  = 25;
196     protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26;
197     protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27;
198     // other
199     protected static final int EVENT_SET_NETWORK_AUTOMATIC          = 28;
200     protected static final int EVENT_ICC_RECORD_EVENTS              = 29;
201     private static final int EVENT_ICC_CHANGED                      = 30;
202     // Single Radio Voice Call Continuity
203     private static final int EVENT_SRVCC_STATE_CHANGED              = 31;
204     private static final int EVENT_INITIATE_SILENT_REDIAL           = 32;
205     private static final int EVENT_RADIO_NOT_AVAILABLE              = 33;
206     private static final int EVENT_UNSOL_OEM_HOOK_RAW               = 34;
207     protected static final int EVENT_GET_RADIO_CAPABILITY           = 35;
208     protected static final int EVENT_SS                             = 36;
209     private static final int EVENT_CONFIG_LCE                       = 37;
210     private static final int EVENT_CHECK_FOR_NETWORK_AUTOMATIC      = 38;
211     protected static final int EVENT_VOICE_RADIO_TECH_CHANGED       = 39;
212     protected static final int EVENT_REQUEST_VOICE_RADIO_TECH_DONE  = 40;
213     protected static final int EVENT_RIL_CONNECTED                  = 41;
214     protected static final int EVENT_UPDATE_PHONE_OBJECT            = 42;
215     protected static final int EVENT_CARRIER_CONFIG_CHANGED         = 43;
216     // Carrier's CDMA prefer mode setting
217     protected static final int EVENT_SET_ROAMING_PREFERENCE_DONE    = 44;
218     protected static final int EVENT_MODEM_RESET                    = 45;
219     protected static final int EVENT_VRS_OR_RAT_CHANGED             = 46;
220     // Radio state change
221     protected static final int EVENT_RADIO_STATE_CHANGED            = 47;
222     protected static final int EVENT_SET_CARRIER_DATA_ENABLED       = 48;
223     protected static final int EVENT_DEVICE_PROVISIONED_CHANGE      = 49;
224     protected static final int EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE = 50;
225     protected static final int EVENT_GET_AVAILABLE_NETWORKS_DONE    = 51;
226 
227     private static final int EVENT_ALL_DATA_DISCONNECTED         = 52;
228 
229     protected static final int EVENT_LAST = EVENT_ALL_DATA_DISCONNECTED;
230 
231     // For shared prefs.
232     private static final String GSM_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_roaming_list_";
233     private static final String GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_non_roaming_list_";
234     private static final String CDMA_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_roaming_list_";
235     private static final String CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_non_roaming_list_";
236 
237     // Key used to read/write current CLIR setting
238     public static final String CLIR_KEY = "clir_key";
239 
240     // Key used for storing voice mail count
241     private static final String VM_COUNT = "vm_count_key";
242     // Key used to read/write the ID for storing the voice mail
243     private static final String VM_ID = "vm_id_key";
244 
245     // Key used for storing call forwarding status
246     public static final String CF_STATUS = "cf_status_key";
247     // Key used to read/write the ID for storing the call forwarding status
248     public static final String CF_ID = "cf_id_key";
249 
250     // Key used to read/write "disable DNS server check" pref (used for testing)
251     private static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key";
252 
253     // Integer used to let the calling application know that the we are ignoring auto mode switch.
254     private static final int ALREADY_IN_AUTO_SELECTION = 1;
255 
256     /**
257      * This method is invoked when the Phone exits Emergency Callback Mode.
258      */
handleExitEmergencyCallbackMode()259     protected void handleExitEmergencyCallbackMode() {
260     }
261 
262     /**
263      * Small container class used to hold information relevant to
264      * the carrier selection process. operatorNumeric can be ""
265      * if we are looking for automatic selection. operatorAlphaLong is the
266      * corresponding operator name.
267      */
268     private static class NetworkSelectMessage {
269         public Message message;
270         public String operatorNumeric;
271         public String operatorAlphaLong;
272         public String operatorAlphaShort;
273     }
274 
275     /* Instance Variables */
276     @UnsupportedAppUsage
277     public CommandsInterface mCi;
278     protected int mVmCount = 0;
279     private boolean mDnsCheckDisabled;
280     // Data connection trackers. For each transport type (e.g. WWAN, WLAN), there will be a
281     // corresponding DcTracker. The WWAN DcTracker is for cellular data connections while
282     // WLAN DcTracker is for IWLAN data connection. For IWLAN legacy mode, only one (WWAN) DcTracker
283     // will be created.
284     protected final SparseArray<DcTracker> mDcTrackers = new SparseArray<>();
285     /* Used for dispatching signals to configured carrier apps */
286     protected CarrierSignalAgent mCarrierSignalAgent;
287     /* Used for dispatching carrier action from carrier apps */
288     protected CarrierActionAgent mCarrierActionAgent;
289     private boolean mDoesRilSendMultipleCallRing;
290     private int mCallRingContinueToken;
291     private int mCallRingDelay;
292     private boolean mIsVoiceCapable = true;
293     private final AppSmsManager mAppSmsManager;
294     private SimActivationTracker mSimActivationTracker;
295     // Keep track of whether or not the phone is in Emergency Callback Mode for Phone and
296     // subclasses
297     protected boolean mIsPhoneInEcmState = false;
298     private volatile long mTimeLastEmergencySmsSentMs = EMERGENCY_SMS_NO_TIME_RECORDED;
299 
300     // Variable to cache the video capability. When RAT changes, we lose this info and are unable
301     // to recover from the state. We cache it and notify listeners when they register.
302     protected boolean mIsVideoCapable = false;
303     @UnsupportedAppUsage
304     protected UiccController mUiccController = null;
305     @UnsupportedAppUsage
306     protected final AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
307     @UnsupportedAppUsage
308     public SmsStorageMonitor mSmsStorageMonitor;
309     public SmsUsageMonitor mSmsUsageMonitor;
310     @UnsupportedAppUsage
311     protected AtomicReference<UiccCardApplication> mUiccApplication =
312             new AtomicReference<UiccCardApplication>();
313     TelephonyTester mTelephonyTester;
314     private String mName;
315     private final String mActionDetached;
316     private final String mActionAttached;
317     protected DeviceStateMonitor mDeviceStateMonitor;
318     protected TransportManager mTransportManager;
319     protected DataEnabledSettings mDataEnabledSettings;
320     // Used for identify the carrier of current subscription
321     protected CarrierResolver mCarrierResolver;
322 
323     @UnsupportedAppUsage
324     protected int mPhoneId;
325 
326     private boolean mImsServiceReady = false;
327     @UnsupportedAppUsage
328     protected Phone mImsPhone = null;
329 
330     private final AtomicReference<RadioCapability> mRadioCapability =
331             new AtomicReference<RadioCapability>();
332 
333     private static final int DEFAULT_REPORT_INTERVAL_MS = 200;
334     private static final boolean LCE_PULL_MODE = true;
335     private int mLceStatus = RILConstants.LCE_NOT_AVAILABLE;
336     protected TelephonyComponentFactory mTelephonyComponentFactory;
337 
338     //IMS
339     /**
340      * {@link CallStateException} message text used to indicate that an IMS call has failed because
341      * it needs to be retried using GSM or CDMA (e.g. CS fallback).
342      * TODO: Replace this with a proper exception; {@link CallStateException} doesn't make sense.
343      */
344     public static final String CS_FALLBACK = "cs_fallback";
345     public static final String EXTRA_KEY_ALERT_TITLE = "alertTitle";
346     public static final String EXTRA_KEY_ALERT_MESSAGE = "alertMessage";
347     public static final String EXTRA_KEY_ALERT_SHOW = "alertShow";
348     public static final String EXTRA_KEY_NOTIFICATION_MESSAGE = "notificationMessage";
349 
350     private final RegistrantList mPreciseCallStateRegistrants = new RegistrantList();
351 
352     private final RegistrantList mHandoverRegistrants = new RegistrantList();
353 
354     private final RegistrantList mNewRingingConnectionRegistrants = new RegistrantList();
355 
356     private final RegistrantList mIncomingRingRegistrants = new RegistrantList();
357 
358     protected final RegistrantList mDisconnectRegistrants = new RegistrantList();
359 
360     private final RegistrantList mServiceStateRegistrants = new RegistrantList();
361 
362     protected final RegistrantList mMmiCompleteRegistrants = new RegistrantList();
363 
364     @UnsupportedAppUsage
365     protected final RegistrantList mMmiRegistrants = new RegistrantList();
366 
367     protected final RegistrantList mUnknownConnectionRegistrants = new RegistrantList();
368 
369     protected final RegistrantList mSuppServiceFailedRegistrants = new RegistrantList();
370 
371     protected final RegistrantList mRadioOffOrNotAvailableRegistrants = new RegistrantList();
372 
373     protected final RegistrantList mSimRecordsLoadedRegistrants = new RegistrantList();
374 
375     private final RegistrantList mVideoCapabilityChangedRegistrants = new RegistrantList();
376 
377     protected final RegistrantList mEmergencyCallToggledRegistrants = new RegistrantList();
378 
379     private final RegistrantList mAllDataDisconnectedRegistrants = new RegistrantList();
380 
381     private final RegistrantList mCellInfoRegistrants = new RegistrantList();
382 
383     protected Registrant mPostDialHandler;
384 
385     protected final LocalLog mLocalLog;
386 
387     private Looper mLooper; /* to insure registrants are in correct thread*/
388 
389     @UnsupportedAppUsage
390     protected final Context mContext;
391 
392     /**
393      * PhoneNotifier is an abstraction for all system-wide
394      * state change notification. DefaultPhoneNotifier is
395      * used here unless running we're inside a unit test.
396      */
397     @UnsupportedAppUsage
398     protected PhoneNotifier mNotifier;
399 
400     protected SimulatedRadioControl mSimulatedRadioControl;
401 
402     private boolean mUnitTestMode;
403 
getIccRecords()404     public IccRecords getIccRecords() {
405         return mIccRecords.get();
406     }
407 
408     /**
409      * Returns a string identifier for this phone interface for parties
410      *  outside the phone app process.
411      *  @return The string name.
412      */
413     @UnsupportedAppUsage
getPhoneName()414     public String getPhoneName() {
415         return mName;
416     }
417 
setPhoneName(String name)418     protected void setPhoneName(String name) {
419         mName = name;
420     }
421 
422     /**
423      * Retrieves Nai for phones. Returns null if Nai is not set.
424      */
425     @UnsupportedAppUsage
getNai()426     public String getNai(){
427          return null;
428     }
429 
430     /**
431      * Return the ActionDetached string. When this action is received by components
432      * they are to simulate detaching from the network.
433      *
434      * @return com.android.internal.telephony.{mName}.action_detached
435      *          {mName} is GSM, CDMA ...
436      */
getActionDetached()437     public String getActionDetached() {
438         return mActionDetached;
439     }
440 
441     /**
442      * Return the ActionAttached string. When this action is received by components
443      * they are to simulate attaching to the network.
444      *
445      * @return com.android.internal.telephony.{mName}.action_detached
446      *          {mName} is GSM, CDMA ...
447      */
getActionAttached()448     public String getActionAttached() {
449         return mActionAttached;
450     }
451 
452     /**
453      * Set a system property for the current phone, unless we're in unit test mode
454      */
455     // CAF_MSIM TODO this need to be replated with TelephonyManager API ?
setSystemProperty(String property, String value)456     public void setSystemProperty(String property, String value) {
457         if (getUnitTestMode()) {
458             return;
459         }
460         TelephonyManager.setTelephonyProperty(mPhoneId, property, value);
461     }
462 
463     /**
464      * Set a system property for all phones, unless we're in unit test mode
465      */
setGlobalSystemProperty(String property, String value)466     public void setGlobalSystemProperty(String property, String value) {
467         if (getUnitTestMode()) {
468             return;
469         }
470         TelephonyManager.setTelephonyProperty(property, value);
471     }
472 
473     /**
474      * Set a system property, unless we're in unit test mode
475      */
476     // CAF_MSIM TODO this need to be replated with TelephonyManager API ?
477     @UnsupportedAppUsage
getSystemProperty(String property, String defValue)478     public String getSystemProperty(String property, String defValue) {
479         if(getUnitTestMode()) {
480             return null;
481         }
482         return SystemProperties.get(property, defValue);
483     }
484 
485     /**
486      * Constructs a Phone in normal (non-unit test) mode.
487      *
488      * @param notifier An instance of DefaultPhoneNotifier,
489      * @param context Context object from hosting application
490      * unless unit testing.
491      * @param ci is CommandsInterface
492      * @param unitTestMode when true, prevents notifications
493      * of state change events
494      */
Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode)495     protected Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci,
496                     boolean unitTestMode) {
497         this(name, notifier, context, ci, unitTestMode, SubscriptionManager.DEFAULT_PHONE_INDEX,
498                 TelephonyComponentFactory.getInstance());
499     }
500 
501     /**
502      * Constructs a Phone in normal (non-unit test) mode.
503      *
504      * @param notifier An instance of DefaultPhoneNotifier,
505      * @param context Context object from hosting application
506      * unless unit testing.
507      * @param ci is CommandsInterface
508      * @param unitTestMode when true, prevents notifications
509      * of state change events
510      * @param phoneId the phone-id of this phone.
511      */
Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode, int phoneId, TelephonyComponentFactory telephonyComponentFactory)512     protected Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci,
513                     boolean unitTestMode, int phoneId,
514                     TelephonyComponentFactory telephonyComponentFactory) {
515         mPhoneId = phoneId;
516         mName = name;
517         mNotifier = notifier;
518         mContext = context;
519         mLooper = Looper.myLooper();
520         mCi = ci;
521         mActionDetached = this.getClass().getPackage().getName() + ".action_detached";
522         mActionAttached = this.getClass().getPackage().getName() + ".action_attached";
523         mAppSmsManager = telephonyComponentFactory.inject(AppSmsManager.class.getName())
524                 .makeAppSmsManager(context);
525         mLocalLog = new LocalLog(64);
526 
527         if (Build.IS_DEBUGGABLE) {
528             mTelephonyTester = new TelephonyTester(this);
529         }
530 
531         setUnitTestMode(unitTestMode);
532 
533         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
534         mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
535         mCi.setOnCallRing(this, EVENT_CALL_RING, null);
536 
537         /* "Voice capable" means that this device supports circuit-switched
538         * (i.e. voice) phone calls over the telephony network, and is allowed
539         * to display the in-call UI while a cellular voice call is active.
540         * This will be false on "data only" devices which can't make voice
541         * calls and don't support any in-call UI.
542         */
543         mIsVoiceCapable = mContext.getResources().getBoolean(
544                 com.android.internal.R.bool.config_voice_capable);
545 
546         /**
547          *  Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs
548          *  to be generated locally. Ideally all ring tones should be loops
549          * and this wouldn't be necessary. But to minimize changes to upper
550          * layers it is requested that it be generated by lower layers.
551          *
552          * By default old phones won't have the property set but do generate
553          * the RIL_UNSOL_CALL_RING so the default if there is no property is
554          * true.
555          */
556         mDoesRilSendMultipleCallRing = SystemProperties.getBoolean(
557                 TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true);
558         Rlog.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
559 
560         mCallRingDelay = SystemProperties.getInt(
561                 TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000);
562         Rlog.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
563 
564         if (getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
565             return;
566         }
567 
568         // The locale from the "ro.carrier" system property or R.array.carrier_properties.
569         // This will be overwritten by the Locale from the SIM language settings (EF-PL, EF-LI)
570         // if applicable.
571         final Locale carrierLocale = getLocaleFromCarrierProperties(mContext);
572         if (carrierLocale != null && !TextUtils.isEmpty(carrierLocale.getCountry())) {
573             final String country = carrierLocale.getCountry();
574             try {
575                 Settings.Global.getInt(mContext.getContentResolver(),
576                         Settings.Global.WIFI_COUNTRY_CODE);
577             } catch (Settings.SettingNotFoundException e) {
578                 // note this is not persisting
579                 WifiManager wM = (WifiManager)
580                         mContext.getSystemService(Context.WIFI_SERVICE);
581                 wM.setCountryCode(country);
582             }
583         }
584 
585         // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
586         mTelephonyComponentFactory = telephonyComponentFactory;
587         mSmsStorageMonitor = mTelephonyComponentFactory.inject(SmsStorageMonitor.class.getName())
588                 .makeSmsStorageMonitor(this);
589         mSmsUsageMonitor = mTelephonyComponentFactory.inject(SmsUsageMonitor.class.getName())
590                 .makeSmsUsageMonitor(context);
591         mUiccController = UiccController.getInstance();
592         mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
593         mSimActivationTracker = mTelephonyComponentFactory
594                 .inject(SimActivationTracker.class.getName())
595                 .makeSimActivationTracker(this);
596         if (getPhoneType() != PhoneConstants.PHONE_TYPE_SIP) {
597             mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null);
598         }
599         mCi.setOnUnsolOemHookRaw(this, EVENT_UNSOL_OEM_HOOK_RAW, null);
600         mCi.startLceService(DEFAULT_REPORT_INTERVAL_MS, LCE_PULL_MODE,
601                 obtainMessage(EVENT_CONFIG_LCE));
602     }
603 
604     /**
605      * Start listening for IMS service UP/DOWN events. If using the new ImsResolver APIs, we should
606      * always be setting up ImsPhones.
607      */
startMonitoringImsService()608     public void startMonitoringImsService() {
609         if (getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) {
610             return;
611         }
612 
613         synchronized(Phone.lockForRadioTechnologyChange) {
614             IntentFilter filter = new IntentFilter();
615             ImsManager imsManager = ImsManager.getInstance(mContext, getPhoneId());
616             // Don't listen to deprecated intents using the new dynamic binding.
617             if (imsManager != null && !imsManager.isDynamicBinding()) {
618                 filter.addAction(ImsManager.ACTION_IMS_SERVICE_UP);
619                 filter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN);
620                 mContext.registerReceiver(mImsIntentReceiver, filter);
621             }
622 
623             // Monitor IMS service - but first poll to see if already up (could miss
624             // intent). Also, when using new ImsResolver APIs, the service will be available soon,
625             // so start trying to bind.
626             if (imsManager != null) {
627                 // If it is dynamic binding, kick off ImsPhone creation now instead of waiting for
628                 // the service to be available.
629                 if (imsManager.isDynamicBinding() || imsManager.isServiceAvailable()) {
630                     mImsServiceReady = true;
631                     updateImsPhone();
632                 }
633             }
634         }
635     }
636 
637     /**
638      * Checks if device should convert CDMA Caller ID restriction related MMI codes to
639      * equivalent 3GPP MMI Codes that provide same functionality when device is roaming.
640      * This method should only return true on multi-mode devices when carrier requires this
641      * conversion to be done on the device.
642      *
643      * @return true when carrier config
644      * "KEY_CONVERT_CDMA_CALLER_ID_MMI_CODES_WHILE_ROAMING_ON_3GPP_BOOL" is set to true
645      */
supportsConversionOfCdmaCallerIdMmiCodesWhileRoaming()646     public boolean supportsConversionOfCdmaCallerIdMmiCodesWhileRoaming() {
647         CarrierConfigManager configManager = (CarrierConfigManager)
648                 getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
649         PersistableBundle b = configManager.getConfigForSubId(getSubId());
650         if (b != null) {
651             return b.getBoolean(
652                     CarrierConfigManager
653                             .KEY_CONVERT_CDMA_CALLER_ID_MMI_CODES_WHILE_ROAMING_ON_3GPP_BOOL,
654                     false);
655         } else {
656             // Default value set in CarrierConfigManager
657             return false;
658         }
659     }
660 
661     /**
662      * When overridden the derived class needs to call
663      * super.handleMessage(msg) so this method has a
664      * a chance to process the message.
665      *
666      * @param msg
667      */
668     @Override
handleMessage(Message msg)669     public void handleMessage(Message msg) {
670         AsyncResult ar;
671 
672         // messages to be handled whether or not the phone is being destroyed
673         // should only include messages which are being re-directed and do not use
674         // resources of the phone being destroyed
675         switch (msg.what) {
676             // handle the select network completion callbacks.
677             case EVENT_SET_NETWORK_MANUAL_COMPLETE:
678             case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE:
679                 handleSetSelectNetwork((AsyncResult) msg.obj);
680                 return;
681         }
682 
683         switch(msg.what) {
684             case EVENT_CALL_RING:
685                 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState());
686                 ar = (AsyncResult)msg.obj;
687                 if (ar.exception == null) {
688                     PhoneConstants.State state = getState();
689                     if ((!mDoesRilSendMultipleCallRing)
690                             && ((state == PhoneConstants.State.RINGING) ||
691                                     (state == PhoneConstants.State.IDLE))) {
692                         mCallRingContinueToken += 1;
693                         sendIncomingCallRingNotification(mCallRingContinueToken);
694                     } else {
695                         notifyIncomingRing();
696                     }
697                 }
698                 break;
699 
700             case EVENT_CALL_RING_CONTINUE:
701                 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received state=" + getState());
702                 if (getState() == PhoneConstants.State.RINGING) {
703                     sendIncomingCallRingNotification(msg.arg1);
704                 }
705                 break;
706 
707             case EVENT_ICC_CHANGED:
708                 onUpdateIccAvailability();
709                 break;
710 
711             case EVENT_INITIATE_SILENT_REDIAL:
712                 Rlog.d(LOG_TAG, "Event EVENT_INITIATE_SILENT_REDIAL Received");
713                 ar = (AsyncResult) msg.obj;
714                 if ((ar.exception == null) && (ar.result != null)) {
715                     String dialString = (String) ar.result;
716                     if (TextUtils.isEmpty(dialString)) return;
717                     try {
718                         dialInternal(dialString, new DialArgs.Builder().build());
719                     } catch (CallStateException e) {
720                         Rlog.e(LOG_TAG, "silent redial failed: " + e);
721                     }
722                 }
723                 break;
724 
725             case EVENT_SRVCC_STATE_CHANGED:
726                 ar = (AsyncResult)msg.obj;
727                 if (ar.exception == null) {
728                     handleSrvccStateChanged((int[]) ar.result);
729                 } else {
730                     Rlog.e(LOG_TAG, "Srvcc exception: " + ar.exception);
731                 }
732                 break;
733 
734             case EVENT_UNSOL_OEM_HOOK_RAW:
735                 ar = (AsyncResult)msg.obj;
736                 if (ar.exception == null) {
737                     byte[] data = (byte[])ar.result;
738                     mNotifier.notifyOemHookRawEventForSubscriber(this, data);
739                 } else {
740                     Rlog.e(LOG_TAG, "OEM hook raw exception: " + ar.exception);
741                 }
742                 break;
743 
744             case EVENT_CONFIG_LCE:
745                 ar = (AsyncResult) msg.obj;
746                 if (ar.exception != null) {
747                     Rlog.d(LOG_TAG, "config LCE service failed: " + ar.exception);
748                 } else {
749                     final ArrayList<Integer> statusInfo = (ArrayList<Integer>)ar.result;
750                     mLceStatus = statusInfo.get(0);
751                 }
752                 break;
753 
754             case EVENT_CHECK_FOR_NETWORK_AUTOMATIC: {
755                 onCheckForNetworkSelectionModeAutomatic(msg);
756                 break;
757             }
758 
759             case EVENT_ALL_DATA_DISCONNECTED:
760                 if (areAllDataDisconnected()) {
761                     mAllDataDisconnectedRegistrants.notifyRegistrants();
762                 }
763                 break;
764             default:
765                 throw new RuntimeException("unexpected event not handled");
766         }
767     }
768 
getHandoverConnection()769     public ArrayList<Connection> getHandoverConnection() {
770         return null;
771     }
772 
notifySrvccState(Call.SrvccState state)773     public void notifySrvccState(Call.SrvccState state) {
774     }
775 
registerForSilentRedial(Handler h, int what, Object obj)776     public void registerForSilentRedial(Handler h, int what, Object obj) {
777     }
778 
unregisterForSilentRedial(Handler h)779     public void unregisterForSilentRedial(Handler h) {
780     }
781 
handleSrvccStateChanged(int[] ret)782     private void handleSrvccStateChanged(int[] ret) {
783         Rlog.d(LOG_TAG, "handleSrvccStateChanged");
784 
785         ArrayList<Connection> conn = null;
786         Phone imsPhone = mImsPhone;
787         Call.SrvccState srvccState = Call.SrvccState.NONE;
788         if (ret != null && ret.length != 0) {
789             int state = ret[0];
790             switch(state) {
791                 case TelephonyManager.SRVCC_STATE_HANDOVER_STARTED:
792                     srvccState = Call.SrvccState.STARTED;
793                     if (imsPhone != null) {
794                         conn = imsPhone.getHandoverConnection();
795                         migrateFrom(imsPhone);
796                     } else {
797                         Rlog.d(LOG_TAG, "HANDOVER_STARTED: mImsPhone null");
798                     }
799                     break;
800                 case TelephonyManager.SRVCC_STATE_HANDOVER_COMPLETED:
801                     srvccState = Call.SrvccState.COMPLETED;
802                     if (imsPhone != null) {
803                         imsPhone.notifySrvccState(srvccState);
804                     } else {
805                         Rlog.d(LOG_TAG, "HANDOVER_COMPLETED: mImsPhone null");
806                     }
807                     break;
808                 case TelephonyManager.SRVCC_STATE_HANDOVER_FAILED:
809                 case TelephonyManager.SRVCC_STATE_HANDOVER_CANCELED:
810                     srvccState = Call.SrvccState.FAILED;
811                     break;
812 
813                 default:
814                     //ignore invalid state
815                     return;
816             }
817 
818             getCallTracker().notifySrvccState(srvccState, conn);
819 
820             notifySrvccStateChanged(state);
821         }
822     }
823 
824     /**
825      * Gets the context for the phone, as set at initialization time.
826      */
827     @UnsupportedAppUsage
getContext()828     public Context getContext() {
829         return mContext;
830     }
831 
832     // Will be called when icc changed
onUpdateIccAvailability()833     protected abstract void onUpdateIccAvailability();
834 
835     /**
836      * Disables the DNS check (i.e., allows "0.0.0.0").
837      * Useful for lab testing environment.
838      * @param b true disables the check, false enables.
839      */
disableDnsCheck(boolean b)840     public void disableDnsCheck(boolean b) {
841         mDnsCheckDisabled = b;
842         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
843         SharedPreferences.Editor editor = sp.edit();
844         editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
845         editor.apply();
846     }
847 
848     /**
849      * Returns true if the DNS check is currently disabled.
850      */
isDnsCheckDisabled()851     public boolean isDnsCheckDisabled() {
852         return mDnsCheckDisabled;
853     }
854 
855     /**
856      * Register for getting notifications for change in the Call State {@link Call.State}
857      * This is called PreciseCallState because the call state is more precise than the
858      * {@link PhoneConstants.State} which can be obtained using the {@link PhoneStateListener}
859      *
860      * Resulting events will have an AsyncResult in <code>Message.obj</code>.
861      * AsyncResult.userData will be set to the obj argument here.
862      * The <em>h</em> parameter is held only by a weak reference.
863      */
864     @UnsupportedAppUsage
registerForPreciseCallStateChanged(Handler h, int what, Object obj)865     public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
866         checkCorrectThread(h);
867 
868         mPreciseCallStateRegistrants.addUnique(h, what, obj);
869     }
870 
871     /**
872      * Unregisters for voice call state change notifications.
873      * Extraneous calls are tolerated silently.
874      */
875     @UnsupportedAppUsage
unregisterForPreciseCallStateChanged(Handler h)876     public void unregisterForPreciseCallStateChanged(Handler h) {
877         mPreciseCallStateRegistrants.remove(h);
878     }
879 
880     /**
881      * Subclasses of Phone probably want to replace this with a
882      * version scoped to their packages
883      */
notifyPreciseCallStateChangedP()884     protected void notifyPreciseCallStateChangedP() {
885         AsyncResult ar = new AsyncResult(null, this, null);
886         mPreciseCallStateRegistrants.notifyRegistrants(ar);
887 
888         mNotifier.notifyPreciseCallState(this);
889     }
890 
891     /**
892      * Notifies when a Handover happens due to SRVCC or Silent Redial
893      */
registerForHandoverStateChanged(Handler h, int what, Object obj)894     public void registerForHandoverStateChanged(Handler h, int what, Object obj) {
895         checkCorrectThread(h);
896         mHandoverRegistrants.addUnique(h, what, obj);
897     }
898 
899     /**
900      * Unregisters for handover state notifications
901      */
unregisterForHandoverStateChanged(Handler h)902     public void unregisterForHandoverStateChanged(Handler h) {
903         mHandoverRegistrants.remove(h);
904     }
905 
906     /**
907      * Subclasses of Phone probably want to replace this with a
908      * version scoped to their packages
909      */
notifyHandoverStateChanged(Connection cn)910     public void notifyHandoverStateChanged(Connection cn) {
911        AsyncResult ar = new AsyncResult(null, cn, null);
912        mHandoverRegistrants.notifyRegistrants(ar);
913     }
914 
setIsInEmergencyCall()915     protected void setIsInEmergencyCall() {
916     }
917 
918     /**
919      * Notify the phone that an SMS has been sent. This will be used determine if the SMS was sent
920      * to an emergency address.
921      * @param destinationAddress the address that the SMS was sent to.
922      */
notifySmsSent(String destinationAddress)923     public void notifySmsSent(String destinationAddress) {
924         TelephonyManager m = (TelephonyManager) getContext().getSystemService(
925                 Context.TELEPHONY_SERVICE);
926         if (m != null && m.isEmergencyNumber(destinationAddress)) {
927             mLocalLog.log("Emergency SMS detected, recording time.");
928             mTimeLastEmergencySmsSentMs = SystemClock.elapsedRealtime();
929         }
930     }
931 
932     /**
933      * Determine if the Phone has recently sent an emergency SMS and is still in the interval of
934      * time defined by a carrier that we may need to do perform special actions, for example
935      * override user setting for location so the carrier can find the user's location for emergency
936      * services.
937      *
938      * @return true if the device is in emergency SMS mode, false otherwise.
939      */
isInEmergencySmsMode()940     public boolean isInEmergencySmsMode() {
941         long lastSmsTimeMs = mTimeLastEmergencySmsSentMs;
942         if (lastSmsTimeMs == EMERGENCY_SMS_NO_TIME_RECORDED) {
943             // an emergency SMS hasn't been sent since the last check.
944             return false;
945         }
946         CarrierConfigManager configManager = (CarrierConfigManager)
947                 getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
948         PersistableBundle b = configManager.getConfigForSubId(getSubId());
949         if (b == null) {
950             // default for KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT is 0 and CarrierConfig isn't
951             // available, so return false.
952             return false;
953         }
954         int eSmsTimerMs = b.getInt(CarrierConfigManager.KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT, 0);
955         if (eSmsTimerMs == 0) {
956             // We do not support this feature for this carrier.
957             return false;
958         }
959         if (eSmsTimerMs > EMERGENCY_SMS_TIMER_MAX_MS) {
960             eSmsTimerMs = EMERGENCY_SMS_TIMER_MAX_MS;
961         }
962         boolean isInEmergencySmsMode = SystemClock.elapsedRealtime()
963                 <= (lastSmsTimeMs + eSmsTimerMs);
964         if (!isInEmergencySmsMode) {
965             // Shortcut this next time so we do not have to waste time if another emergency SMS
966             // hasn't been sent since the last query.
967             mTimeLastEmergencySmsSentMs = EMERGENCY_SMS_NO_TIME_RECORDED;
968         } else {
969             mLocalLog.log("isInEmergencySmsMode: queried while eSMS mode is active.");
970         }
971         return isInEmergencySmsMode;
972     }
973 
migrateFrom(Phone from)974     protected void migrateFrom(Phone from) {
975         migrate(mHandoverRegistrants, from.mHandoverRegistrants);
976         migrate(mPreciseCallStateRegistrants, from.mPreciseCallStateRegistrants);
977         migrate(mNewRingingConnectionRegistrants, from.mNewRingingConnectionRegistrants);
978         migrate(mIncomingRingRegistrants, from.mIncomingRingRegistrants);
979         migrate(mDisconnectRegistrants, from.mDisconnectRegistrants);
980         migrate(mServiceStateRegistrants, from.mServiceStateRegistrants);
981         migrate(mMmiCompleteRegistrants, from.mMmiCompleteRegistrants);
982         migrate(mMmiRegistrants, from.mMmiRegistrants);
983         migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants);
984         migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants);
985         migrate(mCellInfoRegistrants, from.mCellInfoRegistrants);
986         // The emergency state of IMS phone will be cleared in ImsPhone#notifySrvccState after
987         // receive SRVCC completed
988         if (from.isInEmergencyCall()) {
989             setIsInEmergencyCall();
990         }
991     }
992 
migrate(RegistrantList to, RegistrantList from)993     protected void migrate(RegistrantList to, RegistrantList from) {
994         from.removeCleared();
995         for (int i = 0, n = from.size(); i < n; i++) {
996             Registrant r = (Registrant) from.get(i);
997             Message msg = r.messageForRegistrant();
998             // Since CallManager has already registered with both CS and IMS phones,
999             // the migrate should happen only for those registrants which are not
1000             // registered with CallManager.Hence the below check is needed to add
1001             // only those registrants to the registrant list which are not
1002             // coming from the CallManager.
1003             if (msg != null) {
1004                 if (msg.obj == CallManager.getInstance().getRegistrantIdentifier()) {
1005                     continue;
1006                 } else {
1007                     to.add((Registrant) from.get(i));
1008                 }
1009             } else {
1010                 Rlog.d(LOG_TAG, "msg is null");
1011             }
1012         }
1013     }
1014 
1015     /**
1016      * Notifies when a previously untracked non-ringing/waiting connection has appeared.
1017      * This is likely due to some other entity (eg, SIM card application) initiating a call.
1018      */
1019     @UnsupportedAppUsage
registerForUnknownConnection(Handler h, int what, Object obj)1020     public void registerForUnknownConnection(Handler h, int what, Object obj) {
1021         checkCorrectThread(h);
1022 
1023         mUnknownConnectionRegistrants.addUnique(h, what, obj);
1024     }
1025 
1026     /**
1027      * Unregisters for unknown connection notifications.
1028      */
1029     @UnsupportedAppUsage
unregisterForUnknownConnection(Handler h)1030     public void unregisterForUnknownConnection(Handler h) {
1031         mUnknownConnectionRegistrants.remove(h);
1032     }
1033 
1034     /**
1035      * Notifies when a new ringing or waiting connection has appeared.<p>
1036      *
1037      *  Messages received from this:
1038      *  Message.obj will be an AsyncResult
1039      *  AsyncResult.userObj = obj
1040      *  AsyncResult.result = a Connection. <p>
1041      *  Please check Connection.isRinging() to make sure the Connection
1042      *  has not dropped since this message was posted.
1043      *  If Connection.isRinging() is true, then
1044      *   Connection.getCall() == Phone.getRingingCall()
1045      */
1046     @UnsupportedAppUsage
registerForNewRingingConnection( Handler h, int what, Object obj)1047     public void registerForNewRingingConnection(
1048             Handler h, int what, Object obj) {
1049         checkCorrectThread(h);
1050 
1051         mNewRingingConnectionRegistrants.addUnique(h, what, obj);
1052     }
1053 
1054     /**
1055      * Unregisters for new ringing connection notification.
1056      * Extraneous calls are tolerated silently
1057      */
1058     @UnsupportedAppUsage
unregisterForNewRingingConnection(Handler h)1059     public void unregisterForNewRingingConnection(Handler h) {
1060         mNewRingingConnectionRegistrants.remove(h);
1061     }
1062 
1063     /**
1064      * Notifies when phone's video capabilities changes <p>
1065      *
1066      *  Messages received from this:
1067      *  Message.obj will be an AsyncResult
1068      *  AsyncResult.userObj = obj
1069      *  AsyncResult.result = true if phone supports video calling <p>
1070      */
registerForVideoCapabilityChanged( Handler h, int what, Object obj)1071     public void registerForVideoCapabilityChanged(
1072             Handler h, int what, Object obj) {
1073         checkCorrectThread(h);
1074 
1075         mVideoCapabilityChangedRegistrants.addUnique(h, what, obj);
1076 
1077         // Notify any registrants of the cached video capability as soon as they register.
1078         notifyForVideoCapabilityChanged(mIsVideoCapable);
1079     }
1080 
1081     /**
1082      * Unregisters for video capability changed notification.
1083      * Extraneous calls are tolerated silently
1084      */
unregisterForVideoCapabilityChanged(Handler h)1085     public void unregisterForVideoCapabilityChanged(Handler h) {
1086         mVideoCapabilityChangedRegistrants.remove(h);
1087     }
1088 
1089     /**
1090      * Register for notifications when a sInCall VoicePrivacy is enabled
1091      *
1092      * @param h Handler that receives the notification message.
1093      * @param what User-defined message code.
1094      * @param obj User object.
1095      */
registerForInCallVoicePrivacyOn(Handler h, int what, Object obj)1096     public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
1097         mCi.registerForInCallVoicePrivacyOn(h, what, obj);
1098     }
1099 
1100     /**
1101      * Unegister for notifications when a sInCall VoicePrivacy is enabled
1102      *
1103      * @param h Handler to be removed from the registrant list.
1104      */
unregisterForInCallVoicePrivacyOn(Handler h)1105     public void unregisterForInCallVoicePrivacyOn(Handler h){
1106         mCi.unregisterForInCallVoicePrivacyOn(h);
1107     }
1108 
1109     /**
1110      * Register for notifications when a sInCall VoicePrivacy is disabled
1111      *
1112      * @param h Handler that receives the notification message.
1113      * @param what User-defined message code.
1114      * @param obj User object.
1115      */
registerForInCallVoicePrivacyOff(Handler h, int what, Object obj)1116     public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
1117         mCi.registerForInCallVoicePrivacyOff(h, what, obj);
1118     }
1119 
1120     /**
1121      * Unregister for notifications when a sInCall VoicePrivacy is disabled
1122      *
1123      * @param h Handler to be removed from the registrant list.
1124      */
unregisterForInCallVoicePrivacyOff(Handler h)1125     public void unregisterForInCallVoicePrivacyOff(Handler h){
1126         mCi.unregisterForInCallVoicePrivacyOff(h);
1127     }
1128 
1129     /**
1130      * Notifies when an incoming call rings.<p>
1131      *
1132      *  Messages received from this:
1133      *  Message.obj will be an AsyncResult
1134      *  AsyncResult.userObj = obj
1135      *  AsyncResult.result = a Connection. <p>
1136      */
1137     @UnsupportedAppUsage
registerForIncomingRing( Handler h, int what, Object obj)1138     public void registerForIncomingRing(
1139             Handler h, int what, Object obj) {
1140         checkCorrectThread(h);
1141 
1142         mIncomingRingRegistrants.addUnique(h, what, obj);
1143     }
1144 
1145     /**
1146      * Unregisters for ring notification.
1147      * Extraneous calls are tolerated silently
1148      */
1149     @UnsupportedAppUsage
unregisterForIncomingRing(Handler h)1150     public void unregisterForIncomingRing(Handler h) {
1151         mIncomingRingRegistrants.remove(h);
1152     }
1153 
1154     /**
1155      * Notifies when a voice connection has disconnected, either due to local
1156      * or remote hangup or error.
1157      *
1158      *  Messages received from this will have the following members:<p>
1159      *  <ul><li>Message.obj will be an AsyncResult</li>
1160      *  <li>AsyncResult.userObj = obj</li>
1161      *  <li>AsyncResult.result = a Connection object that is
1162      *  no longer connected.</li></ul>
1163      */
1164     @UnsupportedAppUsage
registerForDisconnect(Handler h, int what, Object obj)1165     public void registerForDisconnect(Handler h, int what, Object obj) {
1166         checkCorrectThread(h);
1167 
1168         mDisconnectRegistrants.addUnique(h, what, obj);
1169     }
1170 
1171     /**
1172      * Unregisters for voice disconnection notification.
1173      * Extraneous calls are tolerated silently
1174      */
1175     @UnsupportedAppUsage
unregisterForDisconnect(Handler h)1176     public void unregisterForDisconnect(Handler h) {
1177         mDisconnectRegistrants.remove(h);
1178     }
1179 
1180     /**
1181      * Register for notifications when a supplementary service attempt fails.
1182      * Message.obj will contain an AsyncResult.
1183      *
1184      * @param h Handler that receives the notification message.
1185      * @param what User-defined message code.
1186      * @param obj User object.
1187      */
registerForSuppServiceFailed(Handler h, int what, Object obj)1188     public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
1189         checkCorrectThread(h);
1190 
1191         mSuppServiceFailedRegistrants.addUnique(h, what, obj);
1192     }
1193 
1194     /**
1195      * Unregister for notifications when a supplementary service attempt fails.
1196      * Extraneous calls are tolerated silently
1197      *
1198      * @param h Handler to be removed from the registrant list.
1199      */
unregisterForSuppServiceFailed(Handler h)1200     public void unregisterForSuppServiceFailed(Handler h) {
1201         mSuppServiceFailedRegistrants.remove(h);
1202     }
1203 
1204     /**
1205      * Register for notifications of initiation of a new MMI code request.
1206      * MMI codes for GSM are discussed in 3GPP TS 22.030.<p>
1207      *
1208      * Example: If Phone.dial is called with "*#31#", then the app will
1209      * be notified here.<p>
1210      *
1211      * The returned <code>Message.obj</code> will contain an AsyncResult.
1212      *
1213      * <code>obj.result</code> will be an "MmiCode" object.
1214      */
1215     @UnsupportedAppUsage
registerForMmiInitiate(Handler h, int what, Object obj)1216     public void registerForMmiInitiate(Handler h, int what, Object obj) {
1217         checkCorrectThread(h);
1218 
1219         mMmiRegistrants.addUnique(h, what, obj);
1220     }
1221 
1222     /**
1223      * Unregisters for new MMI initiate notification.
1224      * Extraneous calls are tolerated silently
1225      */
1226     @UnsupportedAppUsage
unregisterForMmiInitiate(Handler h)1227     public void unregisterForMmiInitiate(Handler h) {
1228         mMmiRegistrants.remove(h);
1229     }
1230 
1231     /**
1232      * Register for notifications that an MMI request has completed
1233      * its network activity and is in its final state. This may mean a state
1234      * of COMPLETE, FAILED, or CANCELLED.
1235      *
1236      * <code>Message.obj</code> will contain an AsyncResult.
1237      * <code>obj.result</code> will be an "MmiCode" object
1238      */
1239     @UnsupportedAppUsage
registerForMmiComplete(Handler h, int what, Object obj)1240     public void registerForMmiComplete(Handler h, int what, Object obj) {
1241         checkCorrectThread(h);
1242 
1243         mMmiCompleteRegistrants.addUnique(h, what, obj);
1244     }
1245 
1246     /**
1247      * Unregisters for MMI complete notification.
1248      * Extraneous calls are tolerated silently
1249      */
1250     @UnsupportedAppUsage
unregisterForMmiComplete(Handler h)1251     public void unregisterForMmiComplete(Handler h) {
1252         checkCorrectThread(h);
1253 
1254         mMmiCompleteRegistrants.remove(h);
1255     }
1256 
1257     /**
1258      * Registration point for Sim records loaded
1259      * @param h handler to notify
1260      * @param what what code of message when delivered
1261      * @param obj placed in Message.obj
1262      */
1263     @UnsupportedAppUsage
registerForSimRecordsLoaded(Handler h, int what, Object obj)1264     public void registerForSimRecordsLoaded(Handler h, int what, Object obj) {
1265     }
1266 
1267     /**
1268      * Unregister for notifications for Sim records loaded
1269      * @param h Handler to be removed from the registrant list.
1270      */
1271     @UnsupportedAppUsage
unregisterForSimRecordsLoaded(Handler h)1272     public void unregisterForSimRecordsLoaded(Handler h) {
1273     }
1274 
1275     /**
1276      * Register for TTY mode change notifications from the network.
1277      * Message.obj will contain an AsyncResult.
1278      * AsyncResult.result will be an Integer containing new mode.
1279      *
1280      * @param h Handler that receives the notification message.
1281      * @param what User-defined message code.
1282      * @param obj User object.
1283      */
registerForTtyModeReceived(Handler h, int what, Object obj)1284     public void registerForTtyModeReceived(Handler h, int what, Object obj) {
1285     }
1286 
1287     /**
1288      * Unregisters for TTY mode change notifications.
1289      * Extraneous calls are tolerated silently
1290      *
1291      * @param h Handler to be removed from the registrant list.
1292      */
unregisterForTtyModeReceived(Handler h)1293     public void unregisterForTtyModeReceived(Handler h) {
1294     }
1295 
1296     /**
1297      * Switches network selection mode to "automatic", re-scanning and
1298      * re-selecting a network if appropriate.
1299      *
1300      * @param response The message to dispatch when the network selection
1301      * is complete.
1302      *
1303      * @see #selectNetworkManually(OperatorInfo, boolean, android.os.Message)
1304      */
1305     @UnsupportedAppUsage
setNetworkSelectionModeAutomatic(Message response)1306     public void setNetworkSelectionModeAutomatic(Message response) {
1307         Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic, querying current mode");
1308         // we don't want to do this unecesarily - it acutally causes
1309         // the radio to repeate network selection and is costly
1310         // first check if we're already in automatic mode
1311         Message msg = obtainMessage(EVENT_CHECK_FOR_NETWORK_AUTOMATIC);
1312         msg.obj = response;
1313         mCi.getNetworkSelectionMode(msg);
1314     }
1315 
onCheckForNetworkSelectionModeAutomatic(Message fromRil)1316     private void onCheckForNetworkSelectionModeAutomatic(Message fromRil) {
1317         AsyncResult ar = (AsyncResult)fromRil.obj;
1318         Message response = (Message)ar.userObj;
1319         boolean doAutomatic = true;
1320         if (ar.exception == null && ar.result != null) {
1321             try {
1322                 int[] modes = (int[])ar.result;
1323                 if (modes[0] == 0) {
1324                     // already confirmed to be in automatic mode - don't resend
1325                     doAutomatic = false;
1326                 }
1327             } catch (Exception e) {
1328                 // send the setting on error
1329             }
1330         }
1331 
1332         // wrap the response message in our own message along with
1333         // an empty string (to indicate automatic selection) for the
1334         // operator's id.
1335         NetworkSelectMessage nsm = new NetworkSelectMessage();
1336         nsm.message = response;
1337         nsm.operatorNumeric = "";
1338         nsm.operatorAlphaLong = "";
1339         nsm.operatorAlphaShort = "";
1340 
1341         if (doAutomatic) {
1342             Message msg = obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm);
1343             mCi.setNetworkSelectionModeAutomatic(msg);
1344         } else {
1345             Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic - already auto, ignoring");
1346             // let the calling application know that the we are ignoring automatic mode switch.
1347             if (nsm.message != null) {
1348                 nsm.message.arg1 = ALREADY_IN_AUTO_SELECTION;
1349             }
1350 
1351             ar.userObj = nsm;
1352             handleSetSelectNetwork(ar);
1353         }
1354 
1355         updateSavedNetworkOperator(nsm);
1356     }
1357 
1358     /**
1359      * Query the radio for the current network selection mode.
1360      *
1361      * Return values:
1362      *     0 - automatic.
1363      *     1 - manual.
1364      */
getNetworkSelectionMode(Message message)1365     public void getNetworkSelectionMode(Message message) {
1366         mCi.getNetworkSelectionMode(message);
1367     }
1368 
getClientRequestStats()1369     public List<ClientRequestStats> getClientRequestStats() {
1370         return mCi.getClientRequestStats();
1371     }
1372 
1373     /**
1374      * Manually selects a network. <code>response</code> is
1375      * dispatched when this is complete.  <code>response.obj</code> will be
1376      * an AsyncResult, and <code>response.obj.exception</code> will be non-null
1377      * on failure.
1378      *
1379      * @see #setNetworkSelectionModeAutomatic(Message)
1380      */
1381     @UnsupportedAppUsage
selectNetworkManually(OperatorInfo network, boolean persistSelection, Message response)1382     public void selectNetworkManually(OperatorInfo network, boolean persistSelection,
1383             Message response) {
1384         // wrap the response message in our own message along with
1385         // the operator's id.
1386         NetworkSelectMessage nsm = new NetworkSelectMessage();
1387         nsm.message = response;
1388         nsm.operatorNumeric = network.getOperatorNumeric();
1389         nsm.operatorAlphaLong = network.getOperatorAlphaLong();
1390         nsm.operatorAlphaShort = network.getOperatorAlphaShort();
1391 
1392         Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm);
1393         mCi.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg);
1394 
1395         if (persistSelection) {
1396             updateSavedNetworkOperator(nsm);
1397         } else {
1398             clearSavedNetworkSelection();
1399         }
1400     }
1401 
1402     /**
1403      * Registration point for emergency call/callback mode start. Message.obj is AsyncResult and
1404      * Message.obj.result will be Integer indicating start of call by value 1 or end of call by
1405      * value 0
1406      * @param h handler to notify
1407      * @param what what code of message when delivered
1408      * @param obj placed in Message.obj.userObj
1409      */
registerForEmergencyCallToggle(Handler h, int what, Object obj)1410     public void registerForEmergencyCallToggle(Handler h, int what, Object obj) {
1411         Registrant r = new Registrant(h, what, obj);
1412         mEmergencyCallToggledRegistrants.add(r);
1413     }
1414 
unregisterForEmergencyCallToggle(Handler h)1415     public void unregisterForEmergencyCallToggle(Handler h) {
1416         mEmergencyCallToggledRegistrants.remove(h);
1417     }
1418 
updateSavedNetworkOperator(NetworkSelectMessage nsm)1419     private void updateSavedNetworkOperator(NetworkSelectMessage nsm) {
1420         int subId = getSubId();
1421         if (SubscriptionManager.isValidSubscriptionId(subId)) {
1422             // open the shared preferences editor, and write the value.
1423             // nsm.operatorNumeric is "" if we're in automatic.selection.
1424             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
1425             SharedPreferences.Editor editor = sp.edit();
1426             editor.putString(NETWORK_SELECTION_KEY + subId, nsm.operatorNumeric);
1427             editor.putString(NETWORK_SELECTION_NAME_KEY + subId, nsm.operatorAlphaLong);
1428             editor.putString(NETWORK_SELECTION_SHORT_KEY + subId, nsm.operatorAlphaShort);
1429 
1430             // commit and log the result.
1431             if (!editor.commit()) {
1432                 Rlog.e(LOG_TAG, "failed to commit network selection preference");
1433             }
1434         } else {
1435             Rlog.e(LOG_TAG, "Cannot update network selection preference due to invalid subId " +
1436                     subId);
1437         }
1438     }
1439 
1440     /**
1441      * Used to track the settings upon completion of the network change.
1442      */
handleSetSelectNetwork(AsyncResult ar)1443     private void handleSetSelectNetwork(AsyncResult ar) {
1444         // look for our wrapper within the asyncresult, skip the rest if it
1445         // is null.
1446         if (!(ar.userObj instanceof NetworkSelectMessage)) {
1447             Rlog.e(LOG_TAG, "unexpected result from user object.");
1448             return;
1449         }
1450 
1451         NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj;
1452 
1453         // found the object, now we send off the message we had originally
1454         // attached to the request.
1455         if (nsm.message != null) {
1456             AsyncResult.forMessage(nsm.message, ar.result, ar.exception);
1457             nsm.message.sendToTarget();
1458         }
1459     }
1460 
1461     /**
1462      * Method to retrieve the saved operator from the Shared Preferences
1463      */
getSavedNetworkSelection()1464     private OperatorInfo getSavedNetworkSelection() {
1465         // open the shared preferences and search with our key.
1466         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
1467         String numeric = sp.getString(NETWORK_SELECTION_KEY + getSubId(), "");
1468         String name = sp.getString(NETWORK_SELECTION_NAME_KEY + getSubId(), "");
1469         String shrt = sp.getString(NETWORK_SELECTION_SHORT_KEY + getSubId(), "");
1470         return new OperatorInfo(name, shrt, numeric);
1471     }
1472 
1473     /**
1474      * Clears the saved network selection.
1475      */
clearSavedNetworkSelection()1476     private void clearSavedNetworkSelection() {
1477         // open the shared preferences and search with our key.
1478         PreferenceManager.getDefaultSharedPreferences(getContext()).edit().
1479                 remove(NETWORK_SELECTION_KEY + getSubId()).
1480                 remove(NETWORK_SELECTION_NAME_KEY + getSubId()).
1481                 remove(NETWORK_SELECTION_SHORT_KEY + getSubId()).commit();
1482     }
1483 
1484     /**
1485      * Method to restore the previously saved operator id, or reset to
1486      * automatic selection, all depending upon the value in the shared
1487      * preferences.
1488      */
restoreSavedNetworkSelection(Message response)1489     private void restoreSavedNetworkSelection(Message response) {
1490         // retrieve the operator
1491         OperatorInfo networkSelection = getSavedNetworkSelection();
1492 
1493         // set to auto if the id is empty, otherwise select the network.
1494         if (networkSelection == null || TextUtils.isEmpty(networkSelection.getOperatorNumeric())) {
1495             setNetworkSelectionModeAutomatic(response);
1496         } else {
1497             selectNetworkManually(networkSelection, true, response);
1498         }
1499     }
1500 
1501     /**
1502      * Saves CLIR setting so that we can re-apply it as necessary
1503      * (in case the RIL resets it across reboots).
1504      */
saveClirSetting(int commandInterfaceCLIRMode)1505     public void saveClirSetting(int commandInterfaceCLIRMode) {
1506         // Open the shared preferences editor, and write the value.
1507         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
1508         SharedPreferences.Editor editor = sp.edit();
1509         editor.putInt(CLIR_KEY + getPhoneId(), commandInterfaceCLIRMode);
1510         Rlog.i(LOG_TAG, "saveClirSetting: " + CLIR_KEY + getPhoneId() + "=" +
1511                 commandInterfaceCLIRMode);
1512 
1513         // Commit and log the result.
1514         if (!editor.commit()) {
1515             Rlog.e(LOG_TAG, "Failed to commit CLIR preference");
1516         }
1517     }
1518 
1519     /**
1520      * For unit tests; don't send notifications to "Phone"
1521      * mailbox registrants if true.
1522      */
setUnitTestMode(boolean f)1523     private void setUnitTestMode(boolean f) {
1524         mUnitTestMode = f;
1525     }
1526 
1527     /**
1528      * @return true If unit test mode is enabled
1529      */
getUnitTestMode()1530     public boolean getUnitTestMode() {
1531         return mUnitTestMode;
1532     }
1533 
1534     /**
1535      * To be invoked when a voice call Connection disconnects.
1536      *
1537      * Subclasses of Phone probably want to replace this with a
1538      * version scoped to their packages
1539      */
notifyDisconnectP(Connection cn)1540     protected void notifyDisconnectP(Connection cn) {
1541         AsyncResult ar = new AsyncResult(null, cn, null);
1542         mDisconnectRegistrants.notifyRegistrants(ar);
1543     }
1544 
1545     /**
1546      * Register for ServiceState changed.
1547      * Message.obj will contain an AsyncResult.
1548      * AsyncResult.result will be a ServiceState instance
1549      */
1550     @UnsupportedAppUsage
registerForServiceStateChanged( Handler h, int what, Object obj)1551     public void registerForServiceStateChanged(
1552             Handler h, int what, Object obj) {
1553         mServiceStateRegistrants.add(h, what, obj);
1554     }
1555 
1556     /**
1557      * Unregisters for ServiceStateChange notification.
1558      * Extraneous calls are tolerated silently
1559      */
1560     @UnsupportedAppUsage
unregisterForServiceStateChanged(Handler h)1561     public void unregisterForServiceStateChanged(Handler h) {
1562         mServiceStateRegistrants.remove(h);
1563     }
1564 
1565     /**
1566      * Notifies when out-band ringback tone is needed.<p>
1567      *
1568      *  Messages received from this:
1569      *  Message.obj will be an AsyncResult
1570      *  AsyncResult.userObj = obj
1571      *  AsyncResult.result = boolean, true to start play ringback tone
1572      *                       and false to stop. <p>
1573      */
1574     @UnsupportedAppUsage
registerForRingbackTone(Handler h, int what, Object obj)1575     public void registerForRingbackTone(Handler h, int what, Object obj) {
1576         mCi.registerForRingbackTone(h, what, obj);
1577     }
1578 
1579     /**
1580      * Unregisters for ringback tone notification.
1581      */
1582     @UnsupportedAppUsage
unregisterForRingbackTone(Handler h)1583     public void unregisterForRingbackTone(Handler h) {
1584         mCi.unregisterForRingbackTone(h);
1585     }
1586 
1587     /**
1588      * Notifies when out-band on-hold tone is needed.<p>
1589      *
1590      *  Messages received from this:
1591      *  Message.obj will be an AsyncResult
1592      *  AsyncResult.userObj = obj
1593      *  AsyncResult.result = boolean, true to start play on-hold tone
1594      *                       and false to stop. <p>
1595      */
registerForOnHoldTone(Handler h, int what, Object obj)1596     public void registerForOnHoldTone(Handler h, int what, Object obj) {
1597     }
1598 
1599     /**
1600      * Unregisters for on-hold tone notification.
1601      */
unregisterForOnHoldTone(Handler h)1602     public void unregisterForOnHoldTone(Handler h) {
1603     }
1604 
1605     /**
1606      * Registers the handler to reset the uplink mute state to get
1607      * uplink audio.
1608      */
registerForResendIncallMute(Handler h, int what, Object obj)1609     public void registerForResendIncallMute(Handler h, int what, Object obj) {
1610         mCi.registerForResendIncallMute(h, what, obj);
1611     }
1612 
1613     /**
1614      * Unregisters for resend incall mute notifications.
1615      */
unregisterForResendIncallMute(Handler h)1616     public void unregisterForResendIncallMute(Handler h) {
1617         mCi.unregisterForResendIncallMute(h);
1618     }
1619 
1620     /**
1621      * Registers for CellInfo changed.
1622      * Message.obj will contain an AsyncResult.
1623      * AsyncResult.result will be a List<CellInfo> instance
1624      */
registerForCellInfo( Handler h, int what, Object obj)1625     public void registerForCellInfo(
1626             Handler h, int what, Object obj) {
1627         mCellInfoRegistrants.add(h, what, obj);
1628     }
1629 
1630     /**
1631      * Unregisters for CellInfo notification.
1632      * Extraneous calls are tolerated silently
1633      */
unregisterForCellInfo(Handler h)1634     public void unregisterForCellInfo(Handler h) {
1635         mCellInfoRegistrants.remove(h);
1636     }
1637 
1638     /**
1639      * Enables or disables echo suppression.
1640      */
setEchoSuppressionEnabled()1641     public void setEchoSuppressionEnabled() {
1642         // no need for regular phone
1643     }
1644 
1645     /**
1646      * Subclasses of Phone probably want to replace this with a
1647      * version scoped to their packages
1648      */
notifyServiceStateChangedP(ServiceState ss)1649     protected void notifyServiceStateChangedP(ServiceState ss) {
1650         AsyncResult ar = new AsyncResult(null, ss, null);
1651         mServiceStateRegistrants.notifyRegistrants(ar);
1652 
1653         mNotifier.notifyServiceState(this);
1654     }
1655 
1656     /**
1657      * If this is a simulated phone interface, returns a SimulatedRadioControl.
1658      * @return SimulatedRadioControl if this is a simulated interface;
1659      * otherwise, null.
1660      */
getSimulatedRadioControl()1661     public SimulatedRadioControl getSimulatedRadioControl() {
1662         return mSimulatedRadioControl;
1663     }
1664 
1665     /**
1666      * Verifies the current thread is the same as the thread originally
1667      * used in the initialization of this instance. Throws RuntimeException
1668      * if not.
1669      *
1670      * @exception RuntimeException if the current thread is not
1671      * the thread that originally obtained this Phone instance.
1672      */
checkCorrectThread(Handler h)1673     private void checkCorrectThread(Handler h) {
1674         if (h.getLooper() != mLooper) {
1675             throw new RuntimeException(
1676                     "com.android.internal.telephony.Phone must be used from within one thread");
1677         }
1678     }
1679 
1680     /**
1681      * Set the properties by matching the carrier string in
1682      * a string-array resource
1683      */
getLocaleFromCarrierProperties(Context ctx)1684     private static Locale getLocaleFromCarrierProperties(Context ctx) {
1685         String carrier = SystemProperties.get("ro.carrier");
1686 
1687         if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) {
1688             return null;
1689         }
1690 
1691         CharSequence[] carrierLocales = ctx.getResources().getTextArray(R.array.carrier_properties);
1692 
1693         for (int i = 0; i < carrierLocales.length; i+=3) {
1694             String c = carrierLocales[i].toString();
1695             if (carrier.equals(c)) {
1696                 return Locale.forLanguageTag(carrierLocales[i + 1].toString().replace('_', '-'));
1697             }
1698         }
1699 
1700         return null;
1701     }
1702 
1703     /**
1704      * Get current coarse-grained voice call state.
1705      * Use {@link #registerForPreciseCallStateChanged(Handler, int, Object)
1706      * registerForPreciseCallStateChanged()} for change notification. <p>
1707      * If the phone has an active call and call waiting occurs,
1708      * then the phone state is RINGING not OFFHOOK
1709      * <strong>Note:</strong>
1710      * This registration point provides notification of finer-grained
1711      * changes.<p>
1712      */
1713     @UnsupportedAppUsage
getState()1714     public abstract PhoneConstants.State getState();
1715 
1716     /**
1717      * Retrieves the IccFileHandler of the Phone instance
1718      */
1719     @UnsupportedAppUsage
getIccFileHandler()1720     public IccFileHandler getIccFileHandler(){
1721         UiccCardApplication uiccApplication = mUiccApplication.get();
1722         IccFileHandler fh;
1723 
1724         if (uiccApplication == null) {
1725             Rlog.d(LOG_TAG, "getIccFileHandler: uiccApplication == null, return null");
1726             fh = null;
1727         } else {
1728             fh = uiccApplication.getIccFileHandler();
1729         }
1730 
1731         Rlog.d(LOG_TAG, "getIccFileHandler: fh=" + fh);
1732         return fh;
1733     }
1734 
1735     /*
1736      * Retrieves the Handler of the Phone instance
1737      */
getHandler()1738     public Handler getHandler() {
1739         return this;
1740     }
1741 
1742     /**
1743      * Update the phone object if the voice radio technology has changed
1744      *
1745      * @param voiceRadioTech The new voice radio technology
1746      */
updatePhoneObject(int voiceRadioTech)1747     public void updatePhoneObject(int voiceRadioTech) {
1748     }
1749 
1750     /**
1751     * Retrieves the ServiceStateTracker of the phone instance.
1752     */
1753     @UnsupportedAppUsage
getServiceStateTracker()1754     public ServiceStateTracker getServiceStateTracker() {
1755         return null;
1756     }
1757 
1758     /**
1759      * Retrieves the EmergencyNumberTracker of the phone instance.
1760      */
getEmergencyNumberTracker()1761     public EmergencyNumberTracker getEmergencyNumberTracker() {
1762         return null;
1763     }
1764 
1765     /**
1766     * Get call tracker
1767     */
1768     @UnsupportedAppUsage
getCallTracker()1769     public CallTracker getCallTracker() {
1770         return null;
1771     }
1772 
1773     /**
1774      * @return The instance of transport manager
1775      */
getTransportManager()1776     public TransportManager getTransportManager() {
1777         return null;
1778     }
1779 
1780     /**
1781      * Update voice activation state
1782      */
setVoiceActivationState(int state)1783     public void setVoiceActivationState(int state) {
1784         mSimActivationTracker.setVoiceActivationState(state);
1785     }
1786     /**
1787      * Update data activation state
1788      */
setDataActivationState(int state)1789     public void setDataActivationState(int state) {
1790         mSimActivationTracker.setDataActivationState(state);
1791     }
1792 
1793     /**
1794      * Returns voice activation state
1795      */
getVoiceActivationState()1796     public int getVoiceActivationState() {
1797         return mSimActivationTracker.getVoiceActivationState();
1798     }
1799     /**
1800      * Returns data activation state
1801      */
getDataActivationState()1802     public int getDataActivationState() {
1803         return mSimActivationTracker.getDataActivationState();
1804     }
1805 
1806     /**
1807      * Update voice mail count related fields and notify listeners
1808      */
updateVoiceMail()1809     public void updateVoiceMail() {
1810         Rlog.e(LOG_TAG, "updateVoiceMail() should be overridden");
1811     }
1812 
getCurrentUiccAppType()1813     public AppType getCurrentUiccAppType() {
1814         UiccCardApplication currentApp = mUiccApplication.get();
1815         if (currentApp != null) {
1816             return currentApp.getType();
1817         }
1818         return AppType.APPTYPE_UNKNOWN;
1819     }
1820 
1821     /**
1822      * Returns the ICC card interface for this phone, or null
1823      * if not applicable to underlying technology.
1824      */
1825     @UnsupportedAppUsage
getIccCard()1826     public IccCard getIccCard() {
1827         return null;
1828         //throw new Exception("getIccCard Shouldn't be called from Phone");
1829     }
1830 
1831     /**
1832      * Retrieves the serial number of the ICC, if applicable. Returns only the decimal digits before
1833      * the first hex digit in the ICC ID.
1834      */
1835     @UnsupportedAppUsage
getIccSerialNumber()1836     public String getIccSerialNumber() {
1837         IccRecords r = mIccRecords.get();
1838         return (r != null) ? r.getIccId() : null;
1839     }
1840 
1841     /**
1842      * Retrieves the full serial number of the ICC (including hex digits), if applicable.
1843      */
getFullIccSerialNumber()1844     public String getFullIccSerialNumber() {
1845         IccRecords r = mIccRecords.get();
1846         return (r != null) ? r.getFullIccId() : null;
1847     }
1848 
1849     /**
1850      * Returns SIM record load state. Use
1851      * <code>getSimCard().registerForReady()</code> for change notification.
1852      *
1853      * @return true if records from the SIM have been loaded and are
1854      * available (if applicable). If not applicable to the underlying
1855      * technology, returns true as well.
1856      */
getIccRecordsLoaded()1857     public boolean getIccRecordsLoaded() {
1858         IccRecords r = mIccRecords.get();
1859         return (r != null) ? r.getRecordsLoaded() : false;
1860     }
1861 
1862     /** Set the minimum interval for CellInfo requests to the modem */
setCellInfoMinInterval(int interval)1863     public void setCellInfoMinInterval(int interval) {
1864         getServiceStateTracker().setCellInfoMinInterval(interval);
1865     }
1866 
1867     /**
1868      * @return the last known CellInfo
1869      */
getAllCellInfo()1870     public List<CellInfo> getAllCellInfo() {
1871         return getServiceStateTracker().getAllCellInfo();
1872     }
1873 
1874     /**
1875      * @param workSource calling WorkSource
1876      * @param rspMsg the response message containing the cell info
1877      */
requestCellInfoUpdate(WorkSource workSource, Message rspMsg)1878     public void requestCellInfoUpdate(WorkSource workSource, Message rspMsg) {
1879         getServiceStateTracker().requestAllCellInfo(workSource, rspMsg);
1880     }
1881 
1882     /**
1883      * @return the current cell location if known
1884      */
1885     @UnsupportedAppUsage
getCellLocation()1886     public CellLocation getCellLocation() {
1887         return getServiceStateTracker().getCellLocation();
1888     }
1889 
1890     /**
1891      * @param workSource calling WorkSource
1892      * @param rspMsg the response message containing the cell location
1893      */
getCellLocation(WorkSource workSource, Message rspMsg)1894     public void getCellLocation(WorkSource workSource, Message rspMsg) {
1895         getServiceStateTracker().requestCellLocation(workSource, rspMsg);
1896     }
1897 
1898     /**
1899      * Sets the minimum time in milli-seconds between {@link PhoneStateListener#onCellInfoChanged
1900      * PhoneStateListener.onCellInfoChanged} will be invoked.
1901      *
1902      * The default, 0, means invoke onCellInfoChanged when any of the reported
1903      * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue
1904      * A onCellInfoChanged.
1905      *
1906      * @param rateInMillis the rate
1907      * @param workSource calling WorkSource
1908      */
setCellInfoListRate(int rateInMillis, WorkSource workSource)1909     public void setCellInfoListRate(int rateInMillis, WorkSource workSource) {
1910         mCi.setCellInfoListRate(rateInMillis, null, workSource);
1911     }
1912 
1913     /**
1914      * Get voice message waiting indicator status. No change notification
1915      * available on this interface. Use PhoneStateNotifier or similar instead.
1916      *
1917      * @return true if there is a voice message waiting
1918      */
getMessageWaitingIndicator()1919     public boolean getMessageWaitingIndicator() {
1920         return mVmCount != 0;
1921     }
1922 
getCallForwardingIndicatorFromSharedPref()1923     private int getCallForwardingIndicatorFromSharedPref() {
1924         int status = IccRecords.CALL_FORWARDING_STATUS_DISABLED;
1925         int subId = getSubId();
1926         if (SubscriptionManager.isValidSubscriptionId(subId)) {
1927             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
1928             status = sp.getInt(CF_STATUS + subId, IccRecords.CALL_FORWARDING_STATUS_UNKNOWN);
1929             Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: for subId " + subId + "= " +
1930                     status);
1931             // Check for old preference if status is UNKNOWN for current subId. This part of the
1932             // code is needed only when upgrading from M to N.
1933             if (status == IccRecords.CALL_FORWARDING_STATUS_UNKNOWN) {
1934                 String subscriberId = sp.getString(CF_ID, null);
1935                 if (subscriberId != null) {
1936                     String currentSubscriberId = getSubscriberId();
1937 
1938                     if (subscriberId.equals(currentSubscriberId)) {
1939                         // get call forwarding status from preferences
1940                         status = sp.getInt(CF_STATUS, IccRecords.CALL_FORWARDING_STATUS_DISABLED);
1941                         setCallForwardingIndicatorInSharedPref(
1942                                 status == IccRecords.CALL_FORWARDING_STATUS_ENABLED ? true : false);
1943                         Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: " + status);
1944                     } else {
1945                         Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: returning " +
1946                                 "DISABLED as status for matching subscriberId not found");
1947                     }
1948 
1949                     // get rid of old preferences.
1950                     SharedPreferences.Editor editor = sp.edit();
1951                     editor.remove(CF_ID);
1952                     editor.remove(CF_STATUS);
1953                     editor.apply();
1954                 }
1955             }
1956         } else {
1957             Rlog.e(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: invalid subId " + subId);
1958         }
1959         return status;
1960     }
1961 
setCallForwardingIndicatorInSharedPref(boolean enable)1962     private void setCallForwardingIndicatorInSharedPref(boolean enable) {
1963         int status = enable ? IccRecords.CALL_FORWARDING_STATUS_ENABLED :
1964                 IccRecords.CALL_FORWARDING_STATUS_DISABLED;
1965         int subId = getSubId();
1966         Rlog.i(LOG_TAG, "setCallForwardingIndicatorInSharedPref: Storing status = " + status +
1967                 " in pref " + CF_STATUS + subId);
1968 
1969         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
1970         SharedPreferences.Editor editor = sp.edit();
1971         editor.putInt(CF_STATUS + subId, status);
1972         editor.apply();
1973     }
1974 
setVoiceCallForwardingFlag(int line, boolean enable, String number)1975     public void setVoiceCallForwardingFlag(int line, boolean enable, String number) {
1976         setCallForwardingIndicatorInSharedPref(enable);
1977         IccRecords r = mIccRecords.get();
1978         if (r != null) {
1979             r.setVoiceCallForwardingFlag(line, enable, number);
1980         }
1981     }
1982 
setVoiceCallForwardingFlag(IccRecords r, int line, boolean enable, String number)1983     protected void setVoiceCallForwardingFlag(IccRecords r, int line, boolean enable,
1984                                               String number) {
1985         setCallForwardingIndicatorInSharedPref(enable);
1986         r.setVoiceCallForwardingFlag(line, enable, number);
1987     }
1988 
1989     /**
1990      * Get voice call forwarding indicator status. No change notification
1991      * available on this interface. Use PhoneStateNotifier or similar instead.
1992      *
1993      * @return true if there is a voice call forwarding
1994      */
getCallForwardingIndicator()1995     public boolean getCallForwardingIndicator() {
1996         if (getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
1997             Rlog.e(LOG_TAG, "getCallForwardingIndicator: not possible in CDMA");
1998             return false;
1999         }
2000         IccRecords r = mIccRecords.get();
2001         int callForwardingIndicator = IccRecords.CALL_FORWARDING_STATUS_UNKNOWN;
2002         if (r != null) {
2003             callForwardingIndicator = r.getVoiceCallForwardingFlag();
2004         }
2005         if (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_UNKNOWN) {
2006             callForwardingIndicator = getCallForwardingIndicatorFromSharedPref();
2007         }
2008         Rlog.v(LOG_TAG, "getCallForwardingIndicator: iccForwardingFlag=" + (r != null
2009                     ? r.getVoiceCallForwardingFlag() : "null") + ", sharedPrefFlag="
2010                     + getCallForwardingIndicatorFromSharedPref());
2011         return (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_ENABLED);
2012     }
2013 
getCarrierSignalAgent()2014     public CarrierSignalAgent getCarrierSignalAgent() {
2015         return mCarrierSignalAgent;
2016     }
2017 
getCarrierActionAgent()2018     public CarrierActionAgent getCarrierActionAgent() {
2019         return mCarrierActionAgent;
2020     }
2021 
2022     /**
2023      *  Query the CDMA roaming preference setting
2024      *
2025      * @param response is callback message to report one of  CDMA_RM_*
2026      */
queryCdmaRoamingPreference(Message response)2027     public void queryCdmaRoamingPreference(Message response) {
2028         mCi.queryCdmaRoamingPreference(response);
2029     }
2030 
2031     /**
2032      * Get current signal strength. No change notification available on this
2033      * interface. Use <code>PhoneStateNotifier</code> or an equivalent.
2034      * An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu).
2035      * The following special values are defined:</p>
2036      * <ul><li>0 means "-113 dBm or less".</li>
2037      * <li>31 means "-51 dBm or greater".</li></ul>
2038      *
2039      * @return Current signal strength as SignalStrength
2040      */
getSignalStrength()2041     public SignalStrength getSignalStrength() {
2042         ServiceStateTracker sst = getServiceStateTracker();
2043         if (sst == null) {
2044             return new SignalStrength();
2045         } else {
2046             return sst.getSignalStrength();
2047         }
2048     }
2049 
2050     /**
2051      * @return true, if the device is in a state where both voice and data
2052      * are supported simultaneously. This can change based on location or network condition.
2053      */
isConcurrentVoiceAndDataAllowed()2054     public boolean isConcurrentVoiceAndDataAllowed() {
2055         ServiceStateTracker sst = getServiceStateTracker();
2056         return sst == null ? false : sst.isConcurrentVoiceAndDataAllowed();
2057     }
2058 
2059     /**
2060      *  Requests to set the CDMA roaming preference
2061      * @param cdmaRoamingType one of  CDMA_RM_*
2062      * @param response is callback message
2063      */
setCdmaRoamingPreference(int cdmaRoamingType, Message response)2064     public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
2065         mCi.setCdmaRoamingPreference(cdmaRoamingType, response);
2066     }
2067 
2068     /**
2069      *  Requests to set the CDMA subscription mode
2070      * @param cdmaSubscriptionType one of  CDMA_SUBSCRIPTION_*
2071      * @param response is callback message
2072      */
setCdmaSubscription(int cdmaSubscriptionType, Message response)2073     public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
2074         mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response);
2075     }
2076 
2077     /**
2078      *  Requests to set the preferred network type for searching and registering
2079      * (CS/PS domain, RAT, and operation mode)
2080      * @param networkType one of  NT_*_TYPE
2081      * @param response is callback message
2082      */
2083     @UnsupportedAppUsage
setPreferredNetworkType(int networkType, Message response)2084     public void setPreferredNetworkType(int networkType, Message response) {
2085         // Only set preferred network types to that which the modem supports
2086         int modemRaf = getRadioAccessFamily();
2087         int rafFromType = RadioAccessFamily.getRafFromNetworkType(networkType);
2088 
2089         if (modemRaf == RadioAccessFamily.RAF_UNKNOWN
2090                 || rafFromType == RadioAccessFamily.RAF_UNKNOWN) {
2091             Rlog.d(LOG_TAG, "setPreferredNetworkType: Abort, unknown RAF: "
2092                     + modemRaf + " " + rafFromType);
2093             if (response != null) {
2094                 CommandException ex;
2095 
2096                 ex = new CommandException(CommandException.Error.GENERIC_FAILURE);
2097                 AsyncResult.forMessage(response, null, ex);
2098                 response.sendToTarget();
2099             }
2100             return;
2101         }
2102 
2103         int filteredRaf = (rafFromType & modemRaf);
2104         int filteredType = RadioAccessFamily.getNetworkTypeFromRaf(filteredRaf);
2105 
2106         Rlog.d(LOG_TAG, "setPreferredNetworkType: networkType = " + networkType
2107                 + " modemRaf = " + modemRaf
2108                 + " rafFromType = " + rafFromType
2109                 + " filteredType = " + filteredType);
2110 
2111         mCi.setPreferredNetworkType(filteredType, response);
2112     }
2113 
2114     /**
2115      *  Query the preferred network type setting
2116      *
2117      * @param response is callback message to report one of  NT_*_TYPE
2118      */
getPreferredNetworkType(Message response)2119     public void getPreferredNetworkType(Message response) {
2120         mCi.getPreferredNetworkType(response);
2121     }
2122 
2123     /**
2124      * Gets the default SMSC address.
2125      *
2126      * @param result Callback message contains the SMSC address.
2127      */
2128     @UnsupportedAppUsage
getSmscAddress(Message result)2129     public void getSmscAddress(Message result) {
2130         mCi.getSmscAddress(result);
2131     }
2132 
2133     /**
2134      * Sets the default SMSC address.
2135      *
2136      * @param address new SMSC address
2137      * @param result Callback message is empty on completion
2138      */
2139     @UnsupportedAppUsage
setSmscAddress(String address, Message result)2140     public void setSmscAddress(String address, Message result) {
2141         mCi.setSmscAddress(address, result);
2142     }
2143 
2144     /**
2145      * setTTYMode
2146      * sets a TTY mode option.
2147      * @param ttyMode is a one of the following:
2148      * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
2149      * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
2150      * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
2151      * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
2152      * @param onComplete a callback message when the action is completed
2153      */
setTTYMode(int ttyMode, Message onComplete)2154     public void setTTYMode(int ttyMode, Message onComplete) {
2155         mCi.setTTYMode(ttyMode, onComplete);
2156     }
2157 
2158     /**
2159      * setUiTTYMode
2160      * sets a TTY mode option.
2161      * @param ttyMode is a one of the following:
2162      * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
2163      * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
2164      * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
2165      * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
2166      * @param onComplete a callback message when the action is completed
2167      */
setUiTTYMode(int uiTtyMode, Message onComplete)2168     public void setUiTTYMode(int uiTtyMode, Message onComplete) {
2169         Rlog.d(LOG_TAG, "unexpected setUiTTYMode method call");
2170     }
2171 
2172     /**
2173      * queryTTYMode
2174      * query the status of the TTY mode
2175      *
2176      * @param onComplete a callback message when the action is completed.
2177      */
queryTTYMode(Message onComplete)2178     public void queryTTYMode(Message onComplete) {
2179         mCi.queryTTYMode(onComplete);
2180     }
2181 
2182     /**
2183      * Enable or disable enhanced Voice Privacy (VP). If enhanced VP is
2184      * disabled, normal VP is enabled.
2185      *
2186      * @param enable whether true or false to enable or disable.
2187      * @param onComplete a callback message when the action is completed.
2188      */
enableEnhancedVoicePrivacy(boolean enable, Message onComplete)2189     public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
2190     }
2191 
2192     /**
2193      * Get the currently set Voice Privacy (VP) mode.
2194      *
2195      * @param onComplete a callback message when the action is completed.
2196      */
getEnhancedVoicePrivacy(Message onComplete)2197     public void getEnhancedVoicePrivacy(Message onComplete) {
2198     }
2199 
2200     /**
2201      * Assign a specified band for RF configuration.
2202      *
2203      * @param bandMode one of BM_*_BAND
2204      * @param response is callback message
2205      */
setBandMode(int bandMode, Message response)2206     public void setBandMode(int bandMode, Message response) {
2207         mCi.setBandMode(bandMode, response);
2208     }
2209 
2210     /**
2211      * Query the list of band mode supported by RF.
2212      *
2213      * @param response is callback message
2214      *        ((AsyncResult)response.obj).result  is an int[] where int[0] is
2215      *        the size of the array and the rest of each element representing
2216      *        one available BM_*_BAND
2217      */
queryAvailableBandMode(Message response)2218     public void queryAvailableBandMode(Message response) {
2219         mCi.queryAvailableBandMode(response);
2220     }
2221 
2222     /**
2223      * Invokes RIL_REQUEST_OEM_HOOK_RAW on RIL implementation.
2224      *
2225      * @param data The data for the request.
2226      * @param response <strong>On success</strong>,
2227      * (byte[])(((AsyncResult)response.obj).result)
2228      * <strong>On failure</strong>,
2229      * (((AsyncResult)response.obj).result) == null and
2230      * (((AsyncResult)response.obj).exception) being an instance of
2231      * com.android.internal.telephony.gsm.CommandException
2232      *
2233      * @see #invokeOemRilRequestRaw(byte[], android.os.Message)
2234      * @deprecated OEM needs a vendor-extension hal and their apps should use that instead
2235      */
2236     @UnsupportedAppUsage
2237     @Deprecated
invokeOemRilRequestRaw(byte[] data, Message response)2238     public void invokeOemRilRequestRaw(byte[] data, Message response) {
2239         mCi.invokeOemRilRequestRaw(data, response);
2240     }
2241 
2242     /**
2243      * Invokes RIL_REQUEST_OEM_HOOK_Strings on RIL implementation.
2244      *
2245      * @param strings The strings to make available as the request data.
2246      * @param response <strong>On success</strong>, "response" bytes is
2247      * made available as:
2248      * (String[])(((AsyncResult)response.obj).result).
2249      * <strong>On failure</strong>,
2250      * (((AsyncResult)response.obj).result) == null and
2251      * (((AsyncResult)response.obj).exception) being an instance of
2252      * com.android.internal.telephony.gsm.CommandException
2253      *
2254      * @see #invokeOemRilRequestStrings(java.lang.String[], android.os.Message)
2255      * @deprecated OEM needs a vendor-extension hal and their apps should use that instead
2256      */
2257     @UnsupportedAppUsage
2258     @Deprecated
invokeOemRilRequestStrings(String[] strings, Message response)2259     public void invokeOemRilRequestStrings(String[] strings, Message response) {
2260         mCi.invokeOemRilRequestStrings(strings, response);
2261     }
2262 
2263     /**
2264      * Read one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}.
2265      * Used for device configuration by some CDMA operators.
2266      *
2267      * @param itemID the ID of the item to read
2268      * @param response callback message with the String response in the obj field
2269      * @param workSource calling WorkSource
2270      */
nvReadItem(int itemID, Message response, WorkSource workSource)2271     public void nvReadItem(int itemID, Message response, WorkSource workSource) {
2272         mCi.nvReadItem(itemID, response, workSource);
2273     }
2274 
2275     /**
2276      * Write one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}.
2277      * Used for device configuration by some CDMA operators.
2278      *
2279      * @param itemID the ID of the item to read
2280      * @param itemValue the value to write, as a String
2281      * @param response Callback message.
2282      * @param workSource calling WorkSource
2283      */
nvWriteItem(int itemID, String itemValue, Message response, WorkSource workSource)2284     public void nvWriteItem(int itemID, String itemValue, Message response,
2285             WorkSource workSource) {
2286         mCi.nvWriteItem(itemID, itemValue, response, workSource);
2287     }
2288 
2289     /**
2290      * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
2291      * Used for device configuration by some CDMA operators.
2292      *
2293      * @param preferredRoamingList byte array containing the new PRL
2294      * @param response Callback message.
2295      */
nvWriteCdmaPrl(byte[] preferredRoamingList, Message response)2296     public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message response) {
2297         mCi.nvWriteCdmaPrl(preferredRoamingList, response);
2298     }
2299 
2300     /**
2301      * Perform the radio modem reboot. The radio will be taken offline. Used for device
2302      * configuration by some CDMA operators.
2303      * TODO: reuse nvResetConfig for now, should move to separate HAL API.
2304      *
2305      * @param response Callback message.
2306      */
rebootModem(Message response)2307     public void rebootModem(Message response) {
2308         mCi.nvResetConfig(1 /* 1: reload NV reset, trigger a modem reboot */, response);
2309     }
2310 
2311     /**
2312      * Perform the modem configuration reset. Used for device configuration by some CDMA operators.
2313      * TODO: reuse nvResetConfig for now, should move to separate HAL API.
2314      *
2315      * @param response Callback message.
2316      */
resetModemConfig(Message response)2317     public void resetModemConfig(Message response) {
2318         mCi.nvResetConfig(3 /* factory NV reset */, response);
2319     }
2320 
notifyDataActivity()2321     public void notifyDataActivity() {
2322         mNotifier.notifyDataActivity(this);
2323     }
2324 
notifyMessageWaitingIndicator()2325     private void notifyMessageWaitingIndicator() {
2326         // Do not notify voice mail waiting if device doesn't support voice
2327         if (!mIsVoiceCapable)
2328             return;
2329 
2330         // This function is added to send the notification to DefaultPhoneNotifier.
2331         mNotifier.notifyMessageWaitingChanged(this);
2332     }
2333 
notifyDataConnection(String apnType)2334     public void notifyDataConnection(String apnType) {
2335         mNotifier.notifyDataConnection(this, apnType, getDataConnectionState(apnType));
2336     }
2337 
notifyDataConnection()2338     public void notifyDataConnection() {
2339         String types[] = getActiveApnTypes();
2340         if (types != null) {
2341             for (String apnType : types) {
2342                 mNotifier.notifyDataConnection(this, apnType,
2343                         getDataConnectionState(apnType));
2344             }
2345         }
2346     }
2347 
2348     @UnsupportedAppUsage
notifyOtaspChanged(int otaspMode)2349     public void notifyOtaspChanged(int otaspMode) {
2350         mNotifier.notifyOtaspChanged(this, otaspMode);
2351     }
2352 
notifyVoiceActivationStateChanged(int state)2353     public void notifyVoiceActivationStateChanged(int state) {
2354         mNotifier.notifyVoiceActivationStateChanged(this, state);
2355     }
2356 
notifyDataActivationStateChanged(int state)2357     public void notifyDataActivationStateChanged(int state) {
2358         mNotifier.notifyDataActivationStateChanged(this, state);
2359     }
2360 
notifyUserMobileDataStateChanged(boolean state)2361     public void notifyUserMobileDataStateChanged(boolean state) {
2362         mNotifier.notifyUserMobileDataStateChanged(this, state);
2363     }
2364 
notifySignalStrength()2365     public void notifySignalStrength() {
2366         mNotifier.notifySignalStrength(this);
2367     }
2368 
getDataConnectionState(String apnType)2369     public PhoneConstants.DataState getDataConnectionState(String apnType) {
2370         return PhoneConstants.DataState.DISCONNECTED;
2371     }
2372 
notifyCellInfo(List<CellInfo> cellInfo)2373     public void notifyCellInfo(List<CellInfo> cellInfo) {
2374         AsyncResult ar = new AsyncResult(null, cellInfo, null);
2375         mCellInfoRegistrants.notifyRegistrants(ar);
2376 
2377         mNotifier.notifyCellInfo(this, cellInfo);
2378     }
2379 
2380     /** Notify {@link PhysicalChannelConfig} changes. */
notifyPhysicalChannelConfiguration(List<PhysicalChannelConfig> configs)2381     public void notifyPhysicalChannelConfiguration(List<PhysicalChannelConfig> configs) {
2382         mNotifier.notifyPhysicalChannelConfiguration(this, configs);
2383     }
2384 
2385     /**
2386      * Notify listeners that SRVCC state has changed.
2387      */
notifySrvccStateChanged(int state)2388     public void notifySrvccStateChanged(int state) {
2389         mNotifier.notifySrvccStateChanged(this, state);
2390     }
2391 
2392     /** Notify the {@link EmergencyNumber} changes. */
notifyEmergencyNumberList()2393     public void notifyEmergencyNumberList() {
2394         mNotifier.notifyEmergencyNumberList(this);
2395     }
2396 
2397     /**
2398      * @return true if a mobile originating emergency call is active
2399      */
isInEmergencyCall()2400     public boolean isInEmergencyCall() {
2401         return false;
2402     }
2403 
2404     // This property is used to handle phone process crashes, and is the same for CDMA and IMS
2405     // phones
getInEcmMode()2406     protected static boolean getInEcmMode() {
2407         return SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false);
2408     }
2409 
2410     /**
2411      * @return {@code true} if we are in emergency call back mode. This is a period where the phone
2412      * should be using as little power as possible and be ready to receive an incoming call from the
2413      * emergency operator.
2414      */
isInEcm()2415     public boolean isInEcm() {
2416         return mIsPhoneInEcmState;
2417     }
2418 
setIsInEcm(boolean isInEcm)2419     public void setIsInEcm(boolean isInEcm) {
2420         setGlobalSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE, String.valueOf(isInEcm));
2421         mIsPhoneInEcmState = isInEcm;
2422     }
2423 
2424     @UnsupportedAppUsage
getVideoState(Call call)2425     private static int getVideoState(Call call) {
2426         int videoState = VideoProfile.STATE_AUDIO_ONLY;
2427         Connection conn = call.getEarliestConnection();
2428         if (conn != null) {
2429             videoState = conn.getVideoState();
2430         }
2431         return videoState;
2432     }
2433 
2434     /**
2435      * Determines if the specified call currently is or was at some point a video call, or if it is
2436      * a conference call.
2437      * @param call The call.
2438      * @return {@code true} if the call is or was a video call or is a conference call,
2439      *      {@code false} otherwise.
2440      */
isVideoCallOrConference(Call call)2441     private boolean isVideoCallOrConference(Call call) {
2442         if (call.isMultiparty()) {
2443             return true;
2444         }
2445 
2446         boolean isDowngradedVideoCall = false;
2447         if (call instanceof ImsPhoneCall) {
2448             ImsPhoneCall imsPhoneCall = (ImsPhoneCall) call;
2449             ImsCall imsCall = imsPhoneCall.getImsCall();
2450             return imsCall != null && (imsCall.isVideoCall() ||
2451                     imsCall.wasVideoCall());
2452         }
2453         return isDowngradedVideoCall;
2454     }
2455 
2456     /**
2457      * @return {@code true} if an IMS video call or IMS conference is present, false otherwise.
2458      */
isImsVideoCallOrConferencePresent()2459     public boolean isImsVideoCallOrConferencePresent() {
2460         boolean isPresent = false;
2461         if (mImsPhone != null) {
2462             isPresent = isVideoCallOrConference(mImsPhone.getForegroundCall()) ||
2463                     isVideoCallOrConference(mImsPhone.getBackgroundCall()) ||
2464                     isVideoCallOrConference(mImsPhone.getRingingCall());
2465         }
2466         Rlog.d(LOG_TAG, "isImsVideoCallOrConferencePresent: " + isPresent);
2467         return isPresent;
2468     }
2469 
2470     /**
2471      * Return a numerical identifier for the phone radio interface.
2472      * @return PHONE_TYPE_XXX as defined above.
2473      */
2474     @UnsupportedAppUsage
getPhoneType()2475     public abstract int getPhoneType();
2476 
2477     /**
2478      * Returns unread voicemail count. This count is shown when the  voicemail
2479      * notification is expanded.<p>
2480      */
getVoiceMessageCount()2481     public int getVoiceMessageCount(){
2482         return mVmCount;
2483     }
2484 
2485     /** sets the voice mail count of the phone and notifies listeners. */
setVoiceMessageCount(int countWaiting)2486     public void setVoiceMessageCount(int countWaiting) {
2487         mVmCount = countWaiting;
2488         int subId = getSubId();
2489         if (SubscriptionManager.isValidSubscriptionId(subId)) {
2490 
2491             Rlog.d(LOG_TAG, "setVoiceMessageCount: Storing Voice Mail Count = " + countWaiting +
2492                     " for mVmCountKey = " + VM_COUNT + subId + " in preferences.");
2493 
2494             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
2495             SharedPreferences.Editor editor = sp.edit();
2496             editor.putInt(VM_COUNT + subId, countWaiting);
2497             editor.apply();
2498         } else {
2499             Rlog.e(LOG_TAG, "setVoiceMessageCount in sharedPreference: invalid subId " + subId);
2500         }
2501         // store voice mail count in SIM
2502         IccRecords records = UiccController.getInstance().getIccRecords(
2503                 mPhoneId, UiccController.APP_FAM_3GPP);
2504         if (records != null) {
2505             Rlog.d(LOG_TAG, "setVoiceMessageCount: updating SIM Records");
2506             records.setVoiceMessageWaiting(1, countWaiting);
2507         } else {
2508             Rlog.d(LOG_TAG, "setVoiceMessageCount: SIM Records not found");
2509         }
2510         // notify listeners of voice mail
2511         notifyMessageWaitingIndicator();
2512     }
2513 
2514     /** gets the voice mail count from preferences */
getStoredVoiceMessageCount()2515     protected int getStoredVoiceMessageCount() {
2516         int countVoiceMessages = 0;
2517         int subId = getSubId();
2518         if (SubscriptionManager.isValidSubscriptionId(subId)) {
2519             int invalidCount = -2;  //-1 is not really invalid. It is used for unknown number of vm
2520             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
2521             int countFromSP = sp.getInt(VM_COUNT + subId, invalidCount);
2522             if (countFromSP != invalidCount) {
2523                 countVoiceMessages = countFromSP;
2524                 Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: from preference for subId " + subId +
2525                         "= " + countVoiceMessages);
2526             } else {
2527                 // Check for old preference if count not found for current subId. This part of the
2528                 // code is needed only when upgrading from M to N.
2529                 String subscriberId = sp.getString(VM_ID, null);
2530                 if (subscriberId != null) {
2531                     String currentSubscriberId = getSubscriberId();
2532 
2533                     if (currentSubscriberId != null && currentSubscriberId.equals(subscriberId)) {
2534                         // get voice mail count from preferences
2535                         countVoiceMessages = sp.getInt(VM_COUNT, 0);
2536                         setVoiceMessageCount(countVoiceMessages);
2537                         Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: from preference = " +
2538                                 countVoiceMessages);
2539                     } else {
2540                         Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: returning 0 as count for " +
2541                                 "matching subscriberId not found");
2542 
2543                     }
2544                     // get rid of old preferences.
2545                     SharedPreferences.Editor editor = sp.edit();
2546                     editor.remove(VM_ID);
2547                     editor.remove(VM_COUNT);
2548                     editor.apply();
2549                 }
2550             }
2551         } else {
2552             Rlog.e(LOG_TAG, "getStoredVoiceMessageCount: invalid subId " + subId);
2553         }
2554         return countVoiceMessages;
2555     }
2556 
2557     /**
2558      * send secret dialer codes to launch arbitrary activities.
2559      * an Intent is started with the android_secret_code://<code> URI.
2560      *
2561      * @param code stripped version of secret code without *#*# prefix and #*#* suffix
2562      */
sendDialerSpecialCode(String code)2563     public void sendDialerSpecialCode(String code) {
2564         if (!TextUtils.isEmpty(code)) {
2565             final BroadcastOptions options = BroadcastOptions.makeBasic();
2566             options.setBackgroundActivityStartsAllowed(true);
2567             Intent intent = new Intent(TelephonyIntents.SECRET_CODE_ACTION,
2568                     Uri.parse("android_secret_code://" + code));
2569             intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
2570             mContext.sendBroadcast(intent, null, options.toBundle());
2571 
2572             // {@link TelephonyManager.ACTION_SECRET_CODE} will replace {@link
2573             // TelephonyIntents#SECRET_CODE_ACTION} in the next Android version. Before
2574             // that both of these two actions will be broadcast.
2575             Intent secrectCodeIntent = new Intent(TelephonyManager.ACTION_SECRET_CODE,
2576                     Uri.parse("android_secret_code://" + code));
2577             secrectCodeIntent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
2578             mContext.sendBroadcast(secrectCodeIntent, null, options.toBundle());
2579         }
2580     }
2581 
2582     /**
2583      * Returns the CDMA ERI icon index to display
2584      */
getCdmaEriIconIndex()2585     public int getCdmaEriIconIndex() {
2586         return -1;
2587     }
2588 
2589     /**
2590      * Returns the CDMA ERI icon mode,
2591      * 0 - ON
2592      * 1 - FLASHING
2593      */
getCdmaEriIconMode()2594     public int getCdmaEriIconMode() {
2595         return -1;
2596     }
2597 
2598     /**
2599      * Returns the CDMA ERI text,
2600      */
getCdmaEriText()2601     public String getCdmaEriText() {
2602         return "GSM nw, no ERI";
2603     }
2604 
2605     /**
2606      * Retrieves the MIN for CDMA phones.
2607      */
getCdmaMin()2608     public String getCdmaMin() {
2609         return null;
2610     }
2611 
2612     /**
2613      * Check if subscription data has been assigned to mMin
2614      *
2615      * return true if MIN info is ready; false otherwise.
2616      */
isMinInfoReady()2617     public boolean isMinInfoReady() {
2618         return false;
2619     }
2620 
2621     /**
2622      *  Retrieves PRL Version for CDMA phones
2623      */
getCdmaPrlVersion()2624     public String getCdmaPrlVersion(){
2625         return null;
2626     }
2627 
2628     /**
2629      * send burst DTMF tone, it can send the string as single character or multiple character
2630      * ignore if there is no active call or not valid digits string.
2631      * Valid digit means only includes characters ISO-LATIN characters 0-9, *, #
2632      * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character,
2633      * this api can send single character and multiple character, also, this api has response
2634      * back to caller.
2635      *
2636      * @param dtmfString is string representing the dialing digit(s) in the active call
2637      * @param on the DTMF ON length in milliseconds, or 0 for default
2638      * @param off the DTMF OFF length in milliseconds, or 0 for default
2639      * @param onComplete is the callback message when the action is processed by BP
2640      *
2641      */
sendBurstDtmf(String dtmfString, int on, int off, Message onComplete)2642     public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
2643     }
2644 
2645     /**
2646      * Sets an event to be fired when the telephony system processes
2647      * a post-dial character on an outgoing call.<p>
2648      *
2649      * Messages of type <code>what</code> will be sent to <code>h</code>.
2650      * The <code>obj</code> field of these Message's will be instances of
2651      * <code>AsyncResult</code>. <code>Message.obj.result</code> will be
2652      * a Connection object.<p>
2653      *
2654      * Message.arg1 will be the post dial character being processed,
2655      * or 0 ('\0') if end of string.<p>
2656      *
2657      * If Connection.getPostDialState() == WAIT,
2658      * the application must call
2659      * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar()
2660      * Connection.proceedAfterWaitChar()} or
2661      * {@link com.android.internal.telephony.Connection#cancelPostDial()
2662      * Connection.cancelPostDial()}
2663      * for the telephony system to continue playing the post-dial
2664      * DTMF sequence.<p>
2665      *
2666      * If Connection.getPostDialState() == WILD,
2667      * the application must call
2668      * {@link com.android.internal.telephony.Connection#proceedAfterWildChar
2669      * Connection.proceedAfterWildChar()}
2670      * or
2671      * {@link com.android.internal.telephony.Connection#cancelPostDial()
2672      * Connection.cancelPostDial()}
2673      * for the telephony system to continue playing the
2674      * post-dial DTMF sequence.<p>
2675      *
2676      * Only one post dial character handler may be set. <p>
2677      * Calling this method with "h" equal to null unsets this handler.<p>
2678      */
2679     @UnsupportedAppUsage
setOnPostDialCharacter(Handler h, int what, Object obj)2680     public void setOnPostDialCharacter(Handler h, int what, Object obj) {
2681         mPostDialHandler = new Registrant(h, what, obj);
2682     }
2683 
getPostDialHandler()2684     public Registrant getPostDialHandler() {
2685         return mPostDialHandler;
2686     }
2687 
2688     /**
2689      * request to exit emergency call back mode
2690      * the caller should use setOnECMModeExitResponse
2691      * to receive the emergency callback mode exit response
2692      */
2693     @UnsupportedAppUsage
exitEmergencyCallbackMode()2694     public void exitEmergencyCallbackMode() {
2695     }
2696 
2697     /**
2698      * Register for notifications when CDMA OTA Provision status change
2699      *
2700      * @param h Handler that receives the notification message.
2701      * @param what User-defined message code.
2702      * @param obj User object.
2703      */
registerForCdmaOtaStatusChange(Handler h, int what, Object obj)2704     public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
2705     }
2706 
2707     /**
2708      * Unregister for notifications when CDMA OTA Provision status change
2709      * @param h Handler to be removed from the registrant list.
2710      */
unregisterForCdmaOtaStatusChange(Handler h)2711     public void unregisterForCdmaOtaStatusChange(Handler h) {
2712     }
2713 
2714     /**
2715      * Registration point for subscription info ready
2716      * @param h handler to notify
2717      * @param what what code of message when delivered
2718      * @param obj placed in Message.obj
2719      */
registerForSubscriptionInfoReady(Handler h, int what, Object obj)2720     public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
2721     }
2722 
2723     /**
2724      * Unregister for notifications for subscription info
2725      * @param h Handler to be removed from the registrant list.
2726      */
unregisterForSubscriptionInfoReady(Handler h)2727     public void unregisterForSubscriptionInfoReady(Handler h) {
2728     }
2729 
2730     /**
2731      * Returns true if OTA Service Provisioning needs to be performed.
2732      */
2733     @UnsupportedAppUsage
needsOtaServiceProvisioning()2734     public boolean needsOtaServiceProvisioning() {
2735         return false;
2736     }
2737 
2738     /**
2739      * this decides if the dial number is OTA(Over the air provision) number or not
2740      * @param dialStr is string representing the dialing digit(s)
2741      * @return  true means the dialStr is OTA number, and false means the dialStr is not OTA number
2742      */
isOtaSpNumber(String dialStr)2743     public  boolean isOtaSpNumber(String dialStr) {
2744         return false;
2745     }
2746 
2747     /**
2748      * Register for notifications when CDMA call waiting comes
2749      *
2750      * @param h Handler that receives the notification message.
2751      * @param what User-defined message code.
2752      * @param obj User object.
2753      */
registerForCallWaiting(Handler h, int what, Object obj)2754     public void registerForCallWaiting(Handler h, int what, Object obj){
2755     }
2756 
2757     /**
2758      * Unegister for notifications when CDMA Call waiting comes
2759      * @param h Handler to be removed from the registrant list.
2760      */
unregisterForCallWaiting(Handler h)2761     public void unregisterForCallWaiting(Handler h){
2762     }
2763 
2764     /**
2765      * Registration point for Ecm timer reset
2766      * @param h handler to notify
2767      * @param what user-defined message code
2768      * @param obj placed in Message.obj
2769      */
2770     @UnsupportedAppUsage
registerForEcmTimerReset(Handler h, int what, Object obj)2771     public void registerForEcmTimerReset(Handler h, int what, Object obj) {
2772     }
2773 
2774     /**
2775      * Unregister for notification for Ecm timer reset
2776      * @param h Handler to be removed from the registrant list.
2777      */
2778     @UnsupportedAppUsage
unregisterForEcmTimerReset(Handler h)2779     public void unregisterForEcmTimerReset(Handler h) {
2780     }
2781 
2782     /**
2783      * Register for signal information notifications from the network.
2784      * Message.obj will contain an AsyncResult.
2785      * AsyncResult.result will be a SuppServiceNotification instance.
2786      *
2787      * @param h Handler that receives the notification message.
2788      * @param what User-defined message code.
2789      * @param obj User object.
2790      */
registerForSignalInfo(Handler h, int what, Object obj)2791     public void registerForSignalInfo(Handler h, int what, Object obj) {
2792         mCi.registerForSignalInfo(h, what, obj);
2793     }
2794 
2795     /**
2796      * Unregisters for signal information notifications.
2797      * Extraneous calls are tolerated silently
2798      *
2799      * @param h Handler to be removed from the registrant list.
2800      */
unregisterForSignalInfo(Handler h)2801     public void unregisterForSignalInfo(Handler h) {
2802         mCi.unregisterForSignalInfo(h);
2803     }
2804 
2805     /**
2806      * Register for display information notifications from the network.
2807      * Message.obj will contain an AsyncResult.
2808      * AsyncResult.result will be a SuppServiceNotification instance.
2809      *
2810      * @param h Handler that receives the notification message.
2811      * @param what User-defined message code.
2812      * @param obj User object.
2813      */
registerForDisplayInfo(Handler h, int what, Object obj)2814     public void registerForDisplayInfo(Handler h, int what, Object obj) {
2815         mCi.registerForDisplayInfo(h, what, obj);
2816     }
2817 
2818     /**
2819      * Unregisters for display information notifications.
2820      * Extraneous calls are tolerated silently
2821      *
2822      * @param h Handler to be removed from the registrant list.
2823      */
unregisterForDisplayInfo(Handler h)2824     public void unregisterForDisplayInfo(Handler h) {
2825          mCi.unregisterForDisplayInfo(h);
2826     }
2827 
2828     /**
2829      * Register for CDMA number information record notification from the network.
2830      * Message.obj will contain an AsyncResult.
2831      * AsyncResult.result will be a CdmaInformationRecords.CdmaNumberInfoRec
2832      * instance.
2833      *
2834      * @param h Handler that receives the notification message.
2835      * @param what User-defined message code.
2836      * @param obj User object.
2837      */
registerForNumberInfo(Handler h, int what, Object obj)2838     public void registerForNumberInfo(Handler h, int what, Object obj) {
2839         mCi.registerForNumberInfo(h, what, obj);
2840     }
2841 
2842     /**
2843      * Unregisters for number information record notifications.
2844      * Extraneous calls are tolerated silently
2845      *
2846      * @param h Handler to be removed from the registrant list.
2847      */
unregisterForNumberInfo(Handler h)2848     public void unregisterForNumberInfo(Handler h) {
2849         mCi.unregisterForNumberInfo(h);
2850     }
2851 
2852     /**
2853      * Register for CDMA redirected number information record notification
2854      * from the network.
2855      * Message.obj will contain an AsyncResult.
2856      * AsyncResult.result will be a CdmaInformationRecords.CdmaRedirectingNumberInfoRec
2857      * instance.
2858      *
2859      * @param h Handler that receives the notification message.
2860      * @param what User-defined message code.
2861      * @param obj User object.
2862      */
registerForRedirectedNumberInfo(Handler h, int what, Object obj)2863     public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
2864         mCi.registerForRedirectedNumberInfo(h, what, obj);
2865     }
2866 
2867     /**
2868      * Unregisters for redirected number information record notification.
2869      * Extraneous calls are tolerated silently
2870      *
2871      * @param h Handler to be removed from the registrant list.
2872      */
unregisterForRedirectedNumberInfo(Handler h)2873     public void unregisterForRedirectedNumberInfo(Handler h) {
2874         mCi.unregisterForRedirectedNumberInfo(h);
2875     }
2876 
2877     /**
2878      * Register for CDMA line control information record notification
2879      * from the network.
2880      * Message.obj will contain an AsyncResult.
2881      * AsyncResult.result will be a CdmaInformationRecords.CdmaLineControlInfoRec
2882      * instance.
2883      *
2884      * @param h Handler that receives the notification message.
2885      * @param what User-defined message code.
2886      * @param obj User object.
2887      */
registerForLineControlInfo(Handler h, int what, Object obj)2888     public void registerForLineControlInfo(Handler h, int what, Object obj) {
2889         mCi.registerForLineControlInfo(h, what, obj);
2890     }
2891 
2892     /**
2893      * Unregisters for line control information notifications.
2894      * Extraneous calls are tolerated silently
2895      *
2896      * @param h Handler to be removed from the registrant list.
2897      */
unregisterForLineControlInfo(Handler h)2898     public void unregisterForLineControlInfo(Handler h) {
2899         mCi.unregisterForLineControlInfo(h);
2900     }
2901 
2902     /**
2903      * Register for CDMA T53 CLIR information record notifications
2904      * from the network.
2905      * Message.obj will contain an AsyncResult.
2906      * AsyncResult.result will be a CdmaInformationRecords.CdmaT53ClirInfoRec
2907      * instance.
2908      *
2909      * @param h Handler that receives the notification message.
2910      * @param what User-defined message code.
2911      * @param obj User object.
2912      */
registerFoT53ClirlInfo(Handler h, int what, Object obj)2913     public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
2914         mCi.registerFoT53ClirlInfo(h, what, obj);
2915     }
2916 
2917     /**
2918      * Unregisters for T53 CLIR information record notification
2919      * Extraneous calls are tolerated silently
2920      *
2921      * @param h Handler to be removed from the registrant list.
2922      */
unregisterForT53ClirInfo(Handler h)2923     public void unregisterForT53ClirInfo(Handler h) {
2924         mCi.unregisterForT53ClirInfo(h);
2925     }
2926 
2927     /**
2928      * Register for CDMA T53 audio control information record notifications
2929      * from the network.
2930      * Message.obj will contain an AsyncResult.
2931      * AsyncResult.result will be a CdmaInformationRecords.CdmaT53AudioControlInfoRec
2932      * instance.
2933      *
2934      * @param h Handler that receives the notification message.
2935      * @param what User-defined message code.
2936      * @param obj User object.
2937      */
registerForT53AudioControlInfo(Handler h, int what, Object obj)2938     public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
2939         mCi.registerForT53AudioControlInfo(h, what, obj);
2940     }
2941 
2942     /**
2943      * Unregisters for T53 audio control information record notifications.
2944      * Extraneous calls are tolerated silently
2945      *
2946      * @param h Handler to be removed from the registrant list.
2947      */
unregisterForT53AudioControlInfo(Handler h)2948     public void unregisterForT53AudioControlInfo(Handler h) {
2949         mCi.unregisterForT53AudioControlInfo(h);
2950     }
2951 
2952     /**
2953      * registers for exit emergency call back mode request response
2954      *
2955      * @param h Handler that receives the notification message.
2956      * @param what User-defined message code.
2957      * @param obj User object.
2958      */
2959     @UnsupportedAppUsage
setOnEcbModeExitResponse(Handler h, int what, Object obj)2960     public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
2961     }
2962 
2963     /**
2964      * Unregisters for exit emergency call back mode request response
2965      *
2966      * @param h Handler to be removed from the registrant list.
2967      */
2968     @UnsupportedAppUsage
unsetOnEcbModeExitResponse(Handler h)2969     public void unsetOnEcbModeExitResponse(Handler h){
2970     }
2971 
2972     /**
2973      * Register for radio off or not available
2974      *
2975      * @param h Handler that receives the notification message.
2976      * @param what User-defined message code.
2977      * @param obj User object.
2978      */
registerForRadioOffOrNotAvailable(Handler h, int what, Object obj)2979     public void registerForRadioOffOrNotAvailable(Handler h, int what, Object obj) {
2980         mRadioOffOrNotAvailableRegistrants.addUnique(h, what, obj);
2981     }
2982 
2983     /**
2984      * Unregisters for radio off or not available
2985      *
2986      * @param h Handler to be removed from the registrant list.
2987      */
unregisterForRadioOffOrNotAvailable(Handler h)2988     public void unregisterForRadioOffOrNotAvailable(Handler h) {
2989         mRadioOffOrNotAvailableRegistrants.remove(h);
2990     }
2991 
2992     /**
2993      * Returns an array of string identifiers for the APN types serviced by the
2994      * currently active.
2995      *
2996      * @return The string array of APN types. Return null if no active APN types.
2997      */
2998     @UnsupportedAppUsage
2999     @Nullable
getActiveApnTypes()3000     public String[] getActiveApnTypes() {
3001         if (mTransportManager != null) {
3002             List<String> typesList = new ArrayList<>();
3003             for (int transportType : mTransportManager.getAvailableTransports()) {
3004                 if (getDcTracker(transportType) != null) {
3005                     typesList.addAll(Arrays.asList(
3006                             getDcTracker(transportType).getActiveApnTypes()));
3007                 }
3008             }
3009 
3010             return typesList.toArray(new String[typesList.size()]);
3011         }
3012 
3013         return null;
3014     }
3015 
3016     /**
3017      * Check if there are matching tethering (i.e DUN) for the carrier.
3018      * @return true if there is a matching DUN APN.
3019      */
hasMatchedTetherApnSetting()3020     public boolean hasMatchedTetherApnSetting() {
3021         if (getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) != null) {
3022             return getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
3023                     .hasMatchedTetherApnSetting();
3024         }
3025         return false;
3026     }
3027 
3028     /**
3029      * Returns string for the active APN host.
3030      *  @return type as a string or null if none.
3031      */
getActiveApnHost(String apnType)3032     public String getActiveApnHost(String apnType) {
3033         if (mTransportManager != null) {
3034             int transportType = mTransportManager.getCurrentTransport(
3035                     ApnSetting.getApnTypesBitmaskFromString(apnType));
3036             if (getDcTracker(transportType) != null) {
3037                 return getDcTracker(transportType).getActiveApnString(apnType);
3038             }
3039         }
3040 
3041         return null;
3042     }
3043 
3044     /**
3045      * Return the LinkProperties for the named apn or null if not available
3046      */
getLinkProperties(String apnType)3047     public LinkProperties getLinkProperties(String apnType) {
3048         if (mTransportManager != null) {
3049             int transport = mTransportManager.getCurrentTransport(
3050                     ApnSetting.getApnTypesBitmaskFromString(apnType));
3051             if (getDcTracker(transport) != null) {
3052                 return getDcTracker(transport).getLinkProperties(apnType);
3053             }
3054         }
3055         return null;
3056     }
3057 
3058     /**
3059      * Return the NetworkCapabilities
3060      */
getNetworkCapabilities(String apnType)3061     public NetworkCapabilities getNetworkCapabilities(String apnType) {
3062         if (mTransportManager != null) {
3063             int transportType = mTransportManager.getCurrentTransport(
3064                     ApnSetting.getApnTypesBitmaskFromString(apnType));
3065             if (getDcTracker(transportType) != null) {
3066                 return getDcTracker(transportType).getNetworkCapabilities(apnType);
3067             }
3068         }
3069         return null;
3070     }
3071 
3072     /**
3073      * Report on whether data connectivity is allowed for given APN type.
3074      *
3075      * @param apnType APN type
3076      *
3077      * @return True if data is allowed to be established.
3078      */
isDataAllowed(@pnType int apnType)3079     public boolean isDataAllowed(@ApnType int apnType) {
3080         return isDataAllowed(apnType, null);
3081     }
3082 
3083     /**
3084      * Report on whether data connectivity is allowed.
3085      *
3086      * @param apnType APN type
3087      * @param reasons The reasons that data can/can't be established. This is an output param.
3088      * @return True if data is allowed to be established
3089      */
isDataAllowed(@pnType int apnType, DataConnectionReasons reasons)3090     public boolean isDataAllowed(@ApnType int apnType, DataConnectionReasons reasons) {
3091         if (mTransportManager != null) {
3092             int transport = mTransportManager.getCurrentTransport(apnType);
3093             if (getDcTracker(transport) != null) {
3094                 return getDcTracker(transport).isDataAllowed(reasons);
3095             }
3096         }
3097         return false;
3098     }
3099 
3100 
3101     /**
3102      * Action set from carrier signalling broadcast receivers to enable/disable metered apns.
3103      */
carrierActionSetMeteredApnsEnabled(boolean enabled)3104     public void carrierActionSetMeteredApnsEnabled(boolean enabled) {
3105         mCarrierActionAgent.carrierActionSetMeteredApnsEnabled(enabled);
3106     }
3107 
3108     /**
3109      * Action set from carrier signalling broadcast receivers to enable/disable radio
3110      */
carrierActionSetRadioEnabled(boolean enabled)3111     public void carrierActionSetRadioEnabled(boolean enabled) {
3112         mCarrierActionAgent.carrierActionSetRadioEnabled(enabled);
3113     }
3114 
3115     /**
3116      * Action set from carrier app to start/stop reporting default network condition.
3117      */
carrierActionReportDefaultNetworkStatus(boolean report)3118     public void carrierActionReportDefaultNetworkStatus(boolean report) {
3119         mCarrierActionAgent.carrierActionReportDefaultNetworkStatus(report);
3120     }
3121 
3122     /**
3123      * Action set from carrier signalling broadcast receivers to reset all carrier actions
3124      */
carrierActionResetAll()3125     public void carrierActionResetAll() {
3126         mCarrierActionAgent.carrierActionReset();
3127     }
3128 
3129     /**
3130      * Notify registrants of a new ringing Connection.
3131      * Subclasses of Phone probably want to replace this with a
3132      * version scoped to their packages
3133      */
notifyNewRingingConnectionP(Connection cn)3134     public void notifyNewRingingConnectionP(Connection cn) {
3135         if (!mIsVoiceCapable)
3136             return;
3137         AsyncResult ar = new AsyncResult(null, cn, null);
3138         mNewRingingConnectionRegistrants.notifyRegistrants(ar);
3139     }
3140 
3141     /**
3142      * Notify registrants of a new unknown connection.
3143      */
notifyUnknownConnectionP(Connection cn)3144     public void notifyUnknownConnectionP(Connection cn) {
3145         mUnknownConnectionRegistrants.notifyResult(cn);
3146     }
3147 
3148     /**
3149      * Notify registrants if phone is video capable.
3150      */
notifyForVideoCapabilityChanged(boolean isVideoCallCapable)3151     public void notifyForVideoCapabilityChanged(boolean isVideoCallCapable) {
3152         // Cache the current video capability so that we don't lose the information.
3153         mIsVideoCapable = isVideoCallCapable;
3154 
3155         AsyncResult ar = new AsyncResult(null, isVideoCallCapable, null);
3156         mVideoCapabilityChangedRegistrants.notifyRegistrants(ar);
3157     }
3158 
3159     /**
3160      * Notify registrants of a RING event.
3161      */
notifyIncomingRing()3162     private void notifyIncomingRing() {
3163         if (!mIsVoiceCapable)
3164             return;
3165         AsyncResult ar = new AsyncResult(null, this, null);
3166         mIncomingRingRegistrants.notifyRegistrants(ar);
3167     }
3168 
3169     /**
3170      * Send the incoming call Ring notification if conditions are right.
3171      */
sendIncomingCallRingNotification(int token)3172     private void sendIncomingCallRingNotification(int token) {
3173         if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing &&
3174                 (token == mCallRingContinueToken)) {
3175             Rlog.d(LOG_TAG, "Sending notifyIncomingRing");
3176             notifyIncomingRing();
3177             sendMessageDelayed(
3178                     obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay);
3179         } else {
3180             Rlog.d(LOG_TAG, "Ignoring ring notification request,"
3181                     + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing
3182                     + " token=" + token
3183                     + " mCallRingContinueToken=" + mCallRingContinueToken
3184                     + " mIsVoiceCapable=" + mIsVoiceCapable);
3185         }
3186     }
3187 
3188     /**
3189      * TODO: Adding a function for each property is not good.
3190      * A fucntion of type getPhoneProp(propType) where propType is an
3191      * enum of GSM+CDMA+LTE props would be a better approach.
3192      *
3193      * Get "Restriction of menu options for manual PLMN selection" bit
3194      * status from EF_CSP data, this belongs to "Value Added Services Group".
3195      * @return true if this bit is set or EF_CSP data is unavailable,
3196      * false otherwise
3197      */
3198     @UnsupportedAppUsage
isCspPlmnEnabled()3199     public boolean isCspPlmnEnabled() {
3200         return false;
3201     }
3202 
3203     /**
3204      * Return an interface to retrieve the ISIM records for IMS, if available.
3205      * @return the interface to retrieve the ISIM records, or null if not supported
3206      */
3207     @UnsupportedAppUsage
getIsimRecords()3208     public IsimRecords getIsimRecords() {
3209         Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
3210         return null;
3211     }
3212 
3213     /**
3214      * Retrieves the MSISDN from the UICC. For GSM/UMTS phones, this is equivalent to
3215      * {@link #getLine1Number()}. For CDMA phones, {@link #getLine1Number()} returns
3216      * the MDN, so this method is provided to return the MSISDN on CDMA/LTE phones.
3217      */
3218     @UnsupportedAppUsage
getMsisdn()3219     public String getMsisdn() {
3220         return null;
3221     }
3222 
3223     /**
3224      * Retrieves the EF_PNN from the UICC For GSM/UMTS phones.
3225      */
getPlmn()3226     public String getPlmn() {
3227         return null;
3228     }
3229 
3230     /**
3231      * Get the current for the default apn DataState. No change notification
3232      * exists at this interface -- use
3233      * {@link android.telephony.PhoneStateListener} instead.
3234      */
3235     @UnsupportedAppUsage
getDataConnectionState()3236     public PhoneConstants.DataState getDataConnectionState() {
3237         return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT);
3238     }
3239 
notifyCallForwardingIndicator()3240     public void notifyCallForwardingIndicator() {
3241     }
3242 
notifyDataConnectionFailed(String apnType)3243     public void notifyDataConnectionFailed(String apnType) {
3244         mNotifier.notifyDataConnectionFailed(this, apnType);
3245     }
3246 
notifyPreciseDataConnectionFailed(String apnType, String apn, @DataFailCause.FailCause int failCause)3247     public void notifyPreciseDataConnectionFailed(String apnType, String apn,
3248             @DataFailCause.FailCause int failCause) {
3249         mNotifier.notifyPreciseDataConnectionFailed(this, apnType, apn, failCause);
3250     }
3251 
3252     /**
3253      * Return if the current radio is LTE on CDMA. This
3254      * is a tri-state return value as for a period of time
3255      * the mode may be unknown.
3256      *
3257      * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
3258      * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
3259      */
getLteOnCdmaMode()3260     public int getLteOnCdmaMode() {
3261         return mCi.getLteOnCdmaMode();
3262     }
3263 
3264     /**
3265      * Sets the SIM voice message waiting indicator records.
3266      * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
3267      * @param countWaiting The number of messages waiting, if known. Use
3268      *                     -1 to indicate that an unknown number of
3269      *                      messages are waiting
3270      */
setVoiceMessageWaiting(int line, int countWaiting)3271     public void setVoiceMessageWaiting(int line, int countWaiting) {
3272         // This function should be overridden by class GsmCdmaPhone.
3273         Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive Phone.");
3274     }
3275 
3276     /**
3277      * Gets the USIM service table from the UICC, if present and available.
3278      * @return an interface to the UsimServiceTable record, or null if not available
3279      */
getUsimServiceTable()3280     public UsimServiceTable getUsimServiceTable() {
3281         IccRecords r = mIccRecords.get();
3282         return (r != null) ? r.getUsimServiceTable() : null;
3283     }
3284 
3285     /**
3286      * Gets the Uicc card corresponding to this phone.
3287      * @return the UiccCard object corresponding to the phone ID.
3288      */
3289     @UnsupportedAppUsage
getUiccCard()3290     public UiccCard getUiccCard() {
3291         return mUiccController.getUiccCard(mPhoneId);
3292     }
3293 
3294     /**
3295      * Get P-CSCF address from PCO after data connection is established or modified.
3296      * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
3297      */
getPcscfAddress(String apnType)3298     public String[] getPcscfAddress(String apnType) {
3299         if (mTransportManager != null) {
3300             int transportType = mTransportManager.getCurrentTransport(
3301                     ApnSetting.getApnTypesBitmaskFromString(apnType));
3302             if (getDcTracker(transportType) != null) {
3303                 return getDcTracker(transportType).getPcscfAddress(apnType);
3304             }
3305         }
3306 
3307         return null;
3308     }
3309 
3310     /**
3311      * Set IMS registration state
3312      */
setImsRegistrationState(boolean registered)3313     public void setImsRegistrationState(boolean registered) {
3314     }
3315 
3316     /**
3317      * Return an instance of a IMS phone
3318      */
3319     @UnsupportedAppUsage
getImsPhone()3320     public Phone getImsPhone() {
3321         return mImsPhone;
3322     }
3323 
3324     /**
3325      * Returns Carrier specific information that will be used to encrypt the IMSI and IMPI.
3326      * @param keyType whether the key is being used for WLAN or ePDG.
3327      * @return ImsiEncryptionInfo which includes the Key Type, the Public Key
3328      *        {@link java.security.PublicKey} and the Key Identifier.
3329      *        The keyIdentifier This is used by the server to help it locate the private key to
3330      *        decrypt the permanent identity.
3331      */
getCarrierInfoForImsiEncryption(int keyType)3332     public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType) {
3333         return null;
3334     }
3335 
3336     /**
3337      * Sets the carrier information needed to encrypt the IMSI and IMPI.
3338      * @param imsiEncryptionInfo Carrier specific information that will be used to encrypt the
3339      *        IMSI and IMPI. This includes the Key type, the Public key
3340      *        {@link java.security.PublicKey} and the Key identifier.
3341      */
setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo)3342     public void setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo) {
3343         return;
3344     }
3345 
getCarrierId()3346     public int getCarrierId() {
3347         return TelephonyManager.UNKNOWN_CARRIER_ID;
3348     }
3349 
getCarrierName()3350     public String getCarrierName() {
3351         return null;
3352     }
3353 
getMNOCarrierId()3354     public int getMNOCarrierId() {
3355         return TelephonyManager.UNKNOWN_CARRIER_ID;
3356     }
3357 
getSpecificCarrierId()3358     public int getSpecificCarrierId() {
3359         return TelephonyManager.UNKNOWN_CARRIER_ID;
3360     }
3361 
getSpecificCarrierName()3362     public String getSpecificCarrierName() {
3363         return null;
3364     }
3365 
getCarrierIdListVersion()3366     public int getCarrierIdListVersion() {
3367         return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
3368     }
3369 
resolveSubscriptionCarrierId(String simState)3370     public void resolveSubscriptionCarrierId(String simState) {
3371     }
3372 
3373     /**
3374      *  Resets the Carrier Keys in the database. This involves 2 steps:
3375      *  1. Delete the keys from the database.
3376      *  2. Send an intent to download new Certificates.
3377      */
resetCarrierKeysForImsiEncryption()3378     public void resetCarrierKeysForImsiEncryption() {
3379         return;
3380     }
3381 
3382     /**
3383      * Return if UT capability of ImsPhone is enabled or not
3384      */
3385     @UnsupportedAppUsage
isUtEnabled()3386     public boolean isUtEnabled() {
3387         if (mImsPhone != null) {
3388             return mImsPhone.isUtEnabled();
3389         }
3390         return false;
3391     }
3392 
3393     @UnsupportedAppUsage
dispose()3394     public void dispose() {
3395     }
3396 
updateImsPhone()3397     private void updateImsPhone() {
3398         Rlog.d(LOG_TAG, "updateImsPhone"
3399                 + " mImsServiceReady=" + mImsServiceReady);
3400 
3401         if (mImsServiceReady && (mImsPhone == null)) {
3402             mImsPhone = PhoneFactory.makeImsPhone(mNotifier, this);
3403             CallManager.getInstance().registerPhone(mImsPhone);
3404             mImsPhone.registerForSilentRedial(
3405                     this, EVENT_INITIATE_SILENT_REDIAL, null);
3406         } else if (!mImsServiceReady && (mImsPhone != null)) {
3407             CallManager.getInstance().unregisterPhone(mImsPhone);
3408             mImsPhone.unregisterForSilentRedial(this);
3409 
3410             mImsPhone.dispose();
3411             // Potential GC issue if someone keeps a reference to ImsPhone.
3412             // However: this change will make sure that such a reference does
3413             // not access functions through NULL pointer.
3414             //mImsPhone.removeReferences();
3415             mImsPhone = null;
3416         }
3417     }
3418 
3419     /**
3420      * Dials a number.
3421      *
3422      * @param dialString The number to dial.
3423      * @param dialArgs Parameters to dial with.
3424      * @return The Connection.
3425      * @throws CallStateException
3426      */
dialInternal(String dialString, DialArgs dialArgs)3427     protected Connection dialInternal(String dialString, DialArgs dialArgs)
3428             throws CallStateException {
3429         // dialInternal shall be overriden by GsmCdmaPhone
3430         return null;
3431     }
3432 
3433     /*
3434      * Returns the subscription id.
3435      */
3436     @UnsupportedAppUsage
getSubId()3437     public int getSubId() {
3438         if (SubscriptionController.getInstance() == null) {
3439             // TODO b/78359408 getInstance sometimes returns null in Treehugger tests, which causes
3440             // flakiness. Even though we haven't seen this crash in the wild we should keep this
3441             // check in until we've figured out the root cause.
3442             Rlog.e(LOG_TAG, "SubscriptionController.getInstance = null! Returning default subId");
3443             return SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
3444         }
3445         return SubscriptionController.getInstance().getSubIdUsingPhoneId(mPhoneId);
3446     }
3447 
3448     /**
3449      * Returns the phone id.
3450      */
3451     @UnsupportedAppUsage
getPhoneId()3452     public int getPhoneId() {
3453         return mPhoneId;
3454     }
3455 
3456     /**
3457      * Return the service state of mImsPhone if it is STATE_IN_SERVICE
3458      * otherwise return the current voice service state
3459      */
getVoicePhoneServiceState()3460     public int getVoicePhoneServiceState() {
3461         Phone imsPhone = mImsPhone;
3462         if (imsPhone != null
3463                 && imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) {
3464             return ServiceState.STATE_IN_SERVICE;
3465         }
3466         return getServiceState().getState();
3467     }
3468 
3469     /**
3470      * Override the service provider name and the operator name for the current ICCID.
3471      */
setOperatorBrandOverride(String brand)3472     public boolean setOperatorBrandOverride(String brand) {
3473         return false;
3474     }
3475 
3476     /**
3477      * Override the roaming indicator for the current ICCID.
3478      */
setRoamingOverride(List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList)3479     public boolean setRoamingOverride(List<String> gsmRoamingList,
3480             List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
3481             List<String> cdmaNonRoamingList) {
3482         String iccId = getIccSerialNumber();
3483         if (TextUtils.isEmpty(iccId)) {
3484             return false;
3485         }
3486 
3487         setRoamingOverrideHelper(gsmRoamingList, GSM_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
3488         setRoamingOverrideHelper(gsmNonRoamingList, GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
3489         setRoamingOverrideHelper(cdmaRoamingList, CDMA_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
3490         setRoamingOverrideHelper(cdmaNonRoamingList, CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
3491 
3492         // Refresh.
3493         ServiceStateTracker tracker = getServiceStateTracker();
3494         if (tracker != null) {
3495             tracker.pollState();
3496         }
3497         return true;
3498     }
3499 
setRoamingOverrideHelper(List<String> list, String prefix, String iccId)3500     private void setRoamingOverrideHelper(List<String> list, String prefix, String iccId) {
3501         SharedPreferences.Editor spEditor =
3502                 PreferenceManager.getDefaultSharedPreferences(mContext).edit();
3503         String key = prefix + iccId;
3504         if (list == null || list.isEmpty()) {
3505             spEditor.remove(key).commit();
3506         } else {
3507             spEditor.putStringSet(key, new HashSet<String>(list)).commit();
3508         }
3509     }
3510 
isMccMncMarkedAsRoaming(String mccMnc)3511     public boolean isMccMncMarkedAsRoaming(String mccMnc) {
3512         return getRoamingOverrideHelper(GSM_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc);
3513     }
3514 
isMccMncMarkedAsNonRoaming(String mccMnc)3515     public boolean isMccMncMarkedAsNonRoaming(String mccMnc) {
3516         return getRoamingOverrideHelper(GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc);
3517     }
3518 
isSidMarkedAsRoaming(int SID)3519     public boolean isSidMarkedAsRoaming(int SID) {
3520         return getRoamingOverrideHelper(CDMA_ROAMING_LIST_OVERRIDE_PREFIX,
3521                 Integer.toString(SID));
3522     }
3523 
isSidMarkedAsNonRoaming(int SID)3524     public boolean isSidMarkedAsNonRoaming(int SID) {
3525         return getRoamingOverrideHelper(CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX,
3526                 Integer.toString(SID));
3527     }
3528 
3529     /**
3530      * Query the IMS Registration Status.
3531      *
3532      * @return true if IMS is Registered
3533      */
isImsRegistered()3534     public boolean isImsRegistered() {
3535         Phone imsPhone = mImsPhone;
3536         boolean isImsRegistered = false;
3537         if (imsPhone != null) {
3538             isImsRegistered = imsPhone.isImsRegistered();
3539         } else {
3540             ServiceStateTracker sst = getServiceStateTracker();
3541             if (sst != null) {
3542                 isImsRegistered = sst.isImsRegistered();
3543             }
3544         }
3545         Rlog.d(LOG_TAG, "isImsRegistered =" + isImsRegistered);
3546         return isImsRegistered;
3547     }
3548 
3549     /**
3550      * Get Wifi Calling Feature Availability
3551      */
3552     @UnsupportedAppUsage
isWifiCallingEnabled()3553     public boolean isWifiCallingEnabled() {
3554         Phone imsPhone = mImsPhone;
3555         boolean isWifiCallingEnabled = false;
3556         if (imsPhone != null) {
3557             isWifiCallingEnabled = imsPhone.isWifiCallingEnabled();
3558         }
3559         Rlog.d(LOG_TAG, "isWifiCallingEnabled =" + isWifiCallingEnabled);
3560         return isWifiCallingEnabled;
3561     }
3562 
3563     /**
3564      * @return true if the IMS capability for the registration technology specified is available,
3565      * false otherwise.
3566      */
isImsCapabilityAvailable(int capability, int regTech)3567     public boolean isImsCapabilityAvailable(int capability, int regTech) {
3568         Phone imsPhone = mImsPhone;
3569         boolean isAvailable = false;
3570         if (imsPhone != null) {
3571             isAvailable = imsPhone.isImsCapabilityAvailable(capability, regTech);
3572         }
3573         Rlog.d(LOG_TAG, "isImsRegistered =" + isAvailable);
3574         return isAvailable;
3575     }
3576 
3577     /**
3578      * Get Volte Feature Availability
3579      */
3580     @UnsupportedAppUsage
isVolteEnabled()3581     public boolean isVolteEnabled() {
3582         Phone imsPhone = mImsPhone;
3583         boolean isVolteEnabled = false;
3584         if (imsPhone != null) {
3585             isVolteEnabled = imsPhone.isVolteEnabled();
3586         }
3587         Rlog.d(LOG_TAG, "isImsRegistered =" + isVolteEnabled);
3588         return isVolteEnabled;
3589     }
3590 
3591     /**
3592      * @return the IMS MmTel Registration technology for this Phone, defined in
3593      * {@link ImsRegistrationImplBase}.
3594      */
getImsRegistrationTech()3595     public int getImsRegistrationTech() {
3596         Phone imsPhone = mImsPhone;
3597         int regTech = ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
3598         if (imsPhone != null) {
3599             regTech = imsPhone.getImsRegistrationTech();
3600         }
3601         Rlog.d(LOG_TAG, "getImsRegistrationTechnology =" + regTech);
3602         return regTech;
3603     }
3604 
getRoamingOverrideHelper(String prefix, String key)3605     private boolean getRoamingOverrideHelper(String prefix, String key) {
3606         String iccId = getIccSerialNumber();
3607         if (TextUtils.isEmpty(iccId) || TextUtils.isEmpty(key)) {
3608             return false;
3609         }
3610 
3611         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
3612         Set<String> value = sp.getStringSet(prefix + iccId, null);
3613         if (value == null) {
3614             return false;
3615         }
3616         return value.contains(key);
3617     }
3618 
3619     /**
3620      * @return returns the latest radio state from the modem
3621      */
getRadioPowerState()3622     public int getRadioPowerState() {
3623         return mCi.getRadioState();
3624     }
3625 
3626     /**
3627      * Is Radio Present on the device and is it accessible
3628      */
isRadioAvailable()3629     public boolean isRadioAvailable() {
3630         return mCi.getRadioState() != TelephonyManager.RADIO_POWER_UNAVAILABLE;
3631     }
3632 
3633     /**
3634      * Is Radio turned on
3635      */
isRadioOn()3636     public boolean isRadioOn() {
3637         return mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON;
3638     }
3639 
3640     /**
3641      * shutdown Radio gracefully
3642      */
shutdownRadio()3643     public void shutdownRadio() {
3644         getServiceStateTracker().requestShutdown();
3645     }
3646 
3647     /**
3648      * Return true if the device is shutting down.
3649      */
isShuttingDown()3650     public boolean isShuttingDown() {
3651         return getServiceStateTracker().isDeviceShuttingDown();
3652     }
3653 
3654     /**
3655      *  Set phone radio capability
3656      *
3657      *  @param rc the phone radio capability defined in
3658      *         RadioCapability. It's a input object used to transfer parameter to logic modem
3659      *  @param response Callback message.
3660      */
setRadioCapability(RadioCapability rc, Message response)3661     public void setRadioCapability(RadioCapability rc, Message response) {
3662         mCi.setRadioCapability(rc, response);
3663     }
3664 
3665     /**
3666      *  Get phone radio access family
3667      *
3668      *  @return a bit mask to identify the radio access family.
3669      */
getRadioAccessFamily()3670     public int getRadioAccessFamily() {
3671         final RadioCapability rc = getRadioCapability();
3672         return (rc == null ? RadioAccessFamily.RAF_UNKNOWN : rc.getRadioAccessFamily());
3673     }
3674 
3675     /**
3676      *  Get the associated data modems Id.
3677      *
3678      *  @return a String containing the id of the data modem
3679      */
getModemUuId()3680     public String getModemUuId() {
3681         final RadioCapability rc = getRadioCapability();
3682         return (rc == null ? "" : rc.getLogicalModemUuid());
3683     }
3684 
3685     /**
3686      *  Get phone radio capability
3687      *
3688      *  @return the capability of the radio defined in RadioCapability
3689      */
getRadioCapability()3690     public RadioCapability getRadioCapability() {
3691         return mRadioCapability.get();
3692     }
3693 
3694     /**
3695      *  The RadioCapability has changed. This comes up from the RIL and is called when radios first
3696      *  become available or after a capability switch.  The flow is we use setRadioCapability to
3697      *  request a change with the RIL and get an UNSOL response with the new data which gets set
3698      *  here.
3699      *
3700      *  @param rc the phone radio capability currently in effect for this phone.
3701      */
radioCapabilityUpdated(RadioCapability rc)3702     public void radioCapabilityUpdated(RadioCapability rc) {
3703         // Called when radios first become available or after a capability switch
3704         // Update the cached value
3705         mRadioCapability.set(rc);
3706 
3707         if (SubscriptionManager.isValidSubscriptionId(getSubId())) {
3708             boolean restoreSelection = !mContext.getResources().getBoolean(
3709                     com.android.internal.R.bool.skip_restoring_network_selection);
3710             sendSubscriptionSettings(restoreSelection);
3711         }
3712     }
3713 
sendSubscriptionSettings(boolean restoreNetworkSelection)3714     public void sendSubscriptionSettings(boolean restoreNetworkSelection) {
3715         // Send settings down
3716         int type = PhoneFactory.calculatePreferredNetworkType(mContext, getSubId());
3717         setPreferredNetworkType(type, null);
3718 
3719         if (restoreNetworkSelection) {
3720             restoreSavedNetworkSelection(null);
3721         }
3722     }
3723 
setPreferredNetworkTypeIfSimLoaded()3724     protected void setPreferredNetworkTypeIfSimLoaded() {
3725         int subId = getSubId();
3726         if (SubscriptionManager.isValidSubscriptionId(subId)) {
3727             int type = PhoneFactory.calculatePreferredNetworkType(mContext, getSubId());
3728             setPreferredNetworkType(type, null);
3729         }
3730     }
3731 
3732     /**
3733      * Registers the handler when phone radio  capability is changed.
3734      *
3735      * @param h Handler for notification message.
3736      * @param what User-defined message code.
3737      * @param obj User object.
3738      */
registerForRadioCapabilityChanged(Handler h, int what, Object obj)3739     public void registerForRadioCapabilityChanged(Handler h, int what, Object obj) {
3740         mCi.registerForRadioCapabilityChanged(h, what, obj);
3741     }
3742 
3743     /**
3744      * Unregister for notifications when phone radio type and access technology is changed.
3745      *
3746      * @param h Handler to be removed from the registrant list.
3747      */
unregisterForRadioCapabilityChanged(Handler h)3748     public void unregisterForRadioCapabilityChanged(Handler h) {
3749         mCi.unregisterForRadioCapabilityChanged(this);
3750     }
3751 
3752     /**
3753      * Determines if  IMS is enabled for call.
3754      *
3755      * @return {@code true} if IMS calling is enabled.
3756      */
isImsUseEnabled()3757     public boolean isImsUseEnabled() {
3758         ImsManager imsManager = ImsManager.getInstance(mContext, mPhoneId);
3759         boolean imsUseEnabled = ((imsManager.isVolteEnabledByPlatform()
3760                 && imsManager.isEnhanced4gLteModeSettingEnabledByUser())
3761                 || (imsManager.isWfcEnabledByPlatform() && imsManager.isWfcEnabledByUser())
3762                 && imsManager.isNonTtyOrTtyOnVolteEnabled());
3763         return imsUseEnabled;
3764     }
3765 
3766     /**
3767      * Determines if the connection to IMS services are available yet.
3768      * @return {@code true} if the connection to IMS services are available.
3769      */
isImsAvailable()3770     public boolean isImsAvailable() {
3771         if (mImsPhone == null) {
3772             return false;
3773         }
3774 
3775         return mImsPhone.isImsAvailable();
3776     }
3777 
3778     /**
3779      * Determines if video calling is enabled for the phone.
3780      *
3781      * @return {@code true} if video calling is enabled, {@code false} otherwise.
3782      */
3783     @UnsupportedAppUsage
isVideoEnabled()3784     public boolean isVideoEnabled() {
3785         Phone imsPhone = mImsPhone;
3786         if (imsPhone != null) {
3787             return imsPhone.isVideoEnabled();
3788         }
3789         return false;
3790     }
3791 
3792     /**
3793      * Returns the status of Link Capacity Estimation (LCE) service.
3794      */
getLceStatus()3795     public int getLceStatus() {
3796         return mLceStatus;
3797     }
3798 
3799     /**
3800      * Returns the modem activity information
3801      */
getModemActivityInfo(Message response, WorkSource workSource)3802     public void getModemActivityInfo(Message response, WorkSource workSource)  {
3803         mCi.getModemActivityInfo(response, workSource);
3804     }
3805 
3806     /**
3807      * Starts LCE service after radio becomes available.
3808      * LCE service state may get destroyed on the modem when radio becomes unavailable.
3809      */
startLceAfterRadioIsAvailable()3810     public void startLceAfterRadioIsAvailable() {
3811         mCi.startLceService(DEFAULT_REPORT_INTERVAL_MS, LCE_PULL_MODE,
3812                 obtainMessage(EVENT_CONFIG_LCE));
3813     }
3814 
3815     /**
3816      * Set allowed carriers
3817      */
setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules, Message response, WorkSource workSource)3818     public void setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules,
3819             Message response, WorkSource workSource) {
3820         mCi.setAllowedCarriers(carrierRestrictionRules, response, workSource);
3821     }
3822 
3823     /** Sets the SignalStrength reporting criteria. */
setSignalStrengthReportingCriteria(int[] thresholds, int ran)3824     public void setSignalStrengthReportingCriteria(int[] thresholds, int ran) {
3825         // no-op default implementation
3826     }
3827 
3828     /** Sets the SignalStrength reporting criteria. */
setLinkCapacityReportingCriteria(int[] dlThresholds, int[] ulThresholds, int ran)3829     public void setLinkCapacityReportingCriteria(int[] dlThresholds, int[] ulThresholds, int ran) {
3830         // no-op default implementation
3831     }
3832 
3833     /**
3834      * Get allowed carriers
3835      */
getAllowedCarriers(Message response, WorkSource workSource)3836     public void getAllowedCarriers(Message response, WorkSource workSource) {
3837         mCi.getAllowedCarriers(response, workSource);
3838     }
3839 
3840     /**
3841      * Returns the locale based on the carrier properties (such as {@code ro.carrier}) and
3842      * SIM preferences.
3843      */
getLocaleFromSimAndCarrierPrefs()3844     public Locale getLocaleFromSimAndCarrierPrefs() {
3845         final IccRecords records = mIccRecords.get();
3846         if (records != null && records.getSimLanguage() != null) {
3847             return new Locale(records.getSimLanguage());
3848         }
3849 
3850         return getLocaleFromCarrierProperties(mContext);
3851     }
3852 
updateDataConnectionTracker()3853     public void updateDataConnectionTracker() {
3854         if (mTransportManager != null) {
3855             for (int transport : mTransportManager.getAvailableTransports()) {
3856                 if (getDcTracker(transport) != null) {
3857                     getDcTracker(transport).update();
3858                 }
3859             }
3860         }
3861     }
3862 
updateCurrentCarrierInProvider()3863     public boolean updateCurrentCarrierInProvider() {
3864         return false;
3865     }
3866 
3867     /**
3868      * @return True if all data connections are disconnected.
3869      */
areAllDataDisconnected()3870     public boolean areAllDataDisconnected() {
3871         if (mTransportManager != null) {
3872             for (int transport : mTransportManager.getAvailableTransports()) {
3873                 if (getDcTracker(transport) != null && !getDcTracker(transport).isDisconnected()) {
3874                     return false;
3875                 }
3876             }
3877         }
3878         return true;
3879     }
3880 
registerForAllDataDisconnected(Handler h, int what)3881     public void registerForAllDataDisconnected(Handler h, int what) {
3882         mAllDataDisconnectedRegistrants.addUnique(h, what, null);
3883         if (mTransportManager != null) {
3884             for (int transport : mTransportManager.getAvailableTransports()) {
3885                 if (getDcTracker(transport) != null && !getDcTracker(transport).isDisconnected()) {
3886                     getDcTracker(transport).registerForAllDataDisconnected(
3887                             this, EVENT_ALL_DATA_DISCONNECTED);
3888                 }
3889             }
3890         }
3891     }
3892 
unregisterForAllDataDisconnected(Handler h)3893     public void unregisterForAllDataDisconnected(Handler h) {
3894         mAllDataDisconnectedRegistrants.remove(h);
3895     }
3896 
getDataEnabledSettings()3897     public DataEnabledSettings getDataEnabledSettings() {
3898         return mDataEnabledSettings;
3899     }
3900 
3901     @UnsupportedAppUsage
getIccSmsInterfaceManager()3902     public IccSmsInterfaceManager getIccSmsInterfaceManager(){
3903         return null;
3904     }
3905 
isMatchGid(String gid)3906     protected boolean isMatchGid(String gid) {
3907         String gid1 = getGroupIdLevel1();
3908         int gidLength = gid.length();
3909         if (!TextUtils.isEmpty(gid1) && (gid1.length() >= gidLength)
3910                 && gid1.substring(0, gidLength).equalsIgnoreCase(gid)) {
3911             return true;
3912         }
3913         return false;
3914     }
3915 
checkWfcWifiOnlyModeBeforeDial(Phone imsPhone, int phoneId, Context context)3916     public static void checkWfcWifiOnlyModeBeforeDial(Phone imsPhone, int phoneId, Context context)
3917             throws CallStateException {
3918         if (imsPhone == null || !imsPhone.isWifiCallingEnabled()) {
3919             ImsManager imsManager = ImsManager.getInstance(context, phoneId);
3920             boolean wfcWiFiOnly = (imsManager.isWfcEnabledByPlatform()
3921                     && imsManager.isWfcEnabledByUser() && (imsManager.getWfcMode()
3922                     == ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY));
3923             if (wfcWiFiOnly) {
3924                 throw new CallStateException(
3925                         CallStateException.ERROR_OUT_OF_SERVICE,
3926                         "WFC Wi-Fi Only Mode: IMS not registered");
3927             }
3928         }
3929     }
3930 
startRingbackTone()3931     public void startRingbackTone() {
3932     }
3933 
stopRingbackTone()3934     public void stopRingbackTone() {
3935     }
3936 
callEndCleanupHandOverCallIfAny()3937     public void callEndCleanupHandOverCallIfAny() {
3938     }
3939 
3940     /**
3941      * Cancel USSD session.
3942      *
3943      * @param msg The message to dispatch when the USSD session terminated.
3944      */
cancelUSSD(Message msg)3945     public void cancelUSSD(Message msg) {
3946     }
3947 
3948     /**
3949      * Set boolean broadcastEmergencyCallStateChanges
3950      */
setBroadcastEmergencyCallStateChanges(boolean broadcast)3951     public abstract void setBroadcastEmergencyCallStateChanges(boolean broadcast);
3952 
sendEmergencyCallStateChange(boolean callActive)3953     public abstract void sendEmergencyCallStateChange(boolean callActive);
3954 
3955     /**
3956      * This function returns the parent phone of the current phone. It is applicable
3957      * only for IMS phone (function is overridden by ImsPhone). For others the phone
3958      * object itself is returned.
3959      * @return
3960      */
getDefaultPhone()3961     public Phone getDefaultPhone() {
3962         return this;
3963     }
3964 
3965     /**
3966      * Get aggregated video call data usage since boot.
3967      * Permissions android.Manifest.permission.READ_NETWORK_USAGE_HISTORY is required.
3968      *
3969      * @param perUidStats True if requesting data usage per uid, otherwise overall usage.
3970      * @return Snapshot of video call data usage
3971      */
getVtDataUsage(boolean perUidStats)3972     public NetworkStats getVtDataUsage(boolean perUidStats) {
3973         if (mImsPhone == null) return null;
3974         return mImsPhone.getVtDataUsage(perUidStats);
3975     }
3976 
3977     /**
3978      * SIP URIs aliased to the current subscriber given by the IMS implementation.
3979      * Applicable only on IMS; used in absence of line1number.
3980      * @return array of SIP URIs aliased to the current subscriber
3981      */
getCurrentSubscriberUris()3982     public Uri[] getCurrentSubscriberUris() {
3983         return null;
3984     }
3985 
getAppSmsManager()3986     public AppSmsManager getAppSmsManager() {
3987         return mAppSmsManager;
3988     }
3989 
3990     /**
3991      * Set SIM card power state.
3992      * @param state State of SIM (power down, power up, pass through)
3993      * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
3994      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
3995      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
3996      **/
setSimPowerState(int state, WorkSource workSource)3997     public void setSimPowerState(int state, WorkSource workSource) {
3998         mCi.setSimCardPower(state, null, workSource);
3999     }
4000 
setRadioIndicationUpdateMode(int filters, int mode)4001     public void setRadioIndicationUpdateMode(int filters, int mode) {
4002         if (mDeviceStateMonitor != null) {
4003             mDeviceStateMonitor.setIndicationUpdateMode(filters, mode);
4004         }
4005     }
4006 
setCarrierTestOverride(String mccmnc, String imsi, String iccid, String gid1, String gid2, String pnn, String spn, String carrierPrivilegeRules, String apn)4007     public void setCarrierTestOverride(String mccmnc, String imsi, String iccid, String gid1,
4008             String gid2, String pnn, String spn, String carrierPrivilegeRules, String apn) {
4009     }
4010 
4011     /**
4012      * Get data connection tracker based on the transport type
4013      *
4014      * @param transportType Transport type defined in AccessNetworkConstants.TransportType
4015      * @return The data connection tracker. Null if not found.
4016      */
getDcTracker(int transportType)4017     public @Nullable DcTracker getDcTracker(int transportType) {
4018         return mDcTrackers.get(transportType);
4019     }
4020 
4021     // Return true if either CSIM or RUIM app is present. By default it returns false.
isCdmaSubscriptionAppPresent()4022     public boolean isCdmaSubscriptionAppPresent() {
4023         return false;
4024     }
4025 
4026     /**
4027      * Get the HAL version.
4028      *
4029      * @return the current HalVersion
4030      */
getHalVersion()4031     public HalVersion getHalVersion() {
4032         if (mCi != null && mCi instanceof RIL) {
4033             return ((RIL) mCi).getHalVersion();
4034         }
4035         return RIL.RADIO_HAL_VERSION_UNKNOWN;
4036     }
4037 
dump(FileDescriptor fd, PrintWriter pw, String[] args)4038     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
4039         pw.println("Phone: subId=" + getSubId());
4040         pw.println(" mPhoneId=" + mPhoneId);
4041         pw.println(" mCi=" + mCi);
4042         pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled);
4043         pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
4044         pw.println(" mCallRingContinueToken=" + mCallRingContinueToken);
4045         pw.println(" mCallRingDelay=" + mCallRingDelay);
4046         pw.println(" mIsVoiceCapable=" + mIsVoiceCapable);
4047         pw.println(" mIccRecords=" + mIccRecords.get());
4048         pw.println(" mUiccApplication=" + mUiccApplication.get());
4049         pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor);
4050         pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor);
4051         pw.flush();
4052         pw.println(" mLooper=" + mLooper);
4053         pw.println(" mContext=" + mContext);
4054         pw.println(" mNotifier=" + mNotifier);
4055         pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl);
4056         pw.println(" mUnitTestMode=" + mUnitTestMode);
4057         pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled());
4058         pw.println(" getUnitTestMode()=" + getUnitTestMode());
4059         pw.println(" getState()=" + getState());
4060         pw.println(" getIccSerialNumber()=" + getIccSerialNumber());
4061         pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded());
4062         pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator());
4063         pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator());
4064         pw.println(" isInEmergencyCall()=" + isInEmergencyCall());
4065         pw.flush();
4066         pw.println(" isInEcm()=" + isInEcm());
4067         pw.println(" getPhoneName()=" + getPhoneName());
4068         pw.println(" getPhoneType()=" + getPhoneType());
4069         pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount());
4070         pw.println(" getActiveApnTypes()=" + getActiveApnTypes());
4071         pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning());
4072         pw.println(" isInEmergencySmsMode=" + isInEmergencySmsMode());
4073         pw.flush();
4074         pw.println("++++++++++++++++++++++++++++++++");
4075 
4076         if (mImsPhone != null) {
4077             try {
4078                 mImsPhone.dump(fd, pw, args);
4079             } catch (Exception e) {
4080                 e.printStackTrace();
4081             }
4082 
4083             pw.flush();
4084             pw.println("++++++++++++++++++++++++++++++++");
4085         }
4086 
4087         if (mTransportManager != null) {
4088             for (int transport : mTransportManager.getAvailableTransports()) {
4089                 if (getDcTracker(transport) != null) {
4090                     getDcTracker(transport).dump(fd, pw, args);
4091                     pw.flush();
4092                     pw.println("++++++++++++++++++++++++++++++++");
4093                 }
4094             }
4095         }
4096 
4097         if (getServiceStateTracker() != null) {
4098             try {
4099                 getServiceStateTracker().dump(fd, pw, args);
4100             } catch (Exception e) {
4101                 e.printStackTrace();
4102             }
4103 
4104             pw.flush();
4105             pw.println("++++++++++++++++++++++++++++++++");
4106         }
4107 
4108         if (getEmergencyNumberTracker() != null) {
4109             try {
4110                 getEmergencyNumberTracker().dump(fd, pw, args);
4111             } catch (Exception e) {
4112                 e.printStackTrace();
4113             }
4114 
4115             pw.flush();
4116             pw.println("++++++++++++++++++++++++++++++++");
4117         }
4118 
4119         if (mCarrierResolver != null) {
4120             try {
4121                 mCarrierResolver.dump(fd, pw, args);
4122             } catch (Exception e) {
4123                 e.printStackTrace();
4124             }
4125 
4126             pw.flush();
4127             pw.println("++++++++++++++++++++++++++++++++");
4128         }
4129 
4130         if (mCarrierActionAgent != null) {
4131             try {
4132                 mCarrierActionAgent.dump(fd, pw, args);
4133             } catch (Exception e) {
4134                 e.printStackTrace();
4135             }
4136 
4137             pw.flush();
4138             pw.println("++++++++++++++++++++++++++++++++");
4139         }
4140 
4141         if (mCarrierSignalAgent != null) {
4142             try {
4143                 mCarrierSignalAgent.dump(fd, pw, args);
4144             } catch (Exception e) {
4145                 e.printStackTrace();
4146             }
4147 
4148             pw.flush();
4149             pw.println("++++++++++++++++++++++++++++++++");
4150         }
4151 
4152         if (getCallTracker() != null) {
4153             try {
4154                 getCallTracker().dump(fd, pw, args);
4155             } catch (Exception e) {
4156                 e.printStackTrace();
4157             }
4158 
4159             pw.flush();
4160             pw.println("++++++++++++++++++++++++++++++++");
4161         }
4162 
4163         if (mSimActivationTracker != null) {
4164             try {
4165                 mSimActivationTracker.dump(fd, pw, args);
4166             } catch (Exception e) {
4167                 e.printStackTrace();
4168             }
4169 
4170             pw.flush();
4171             pw.println("++++++++++++++++++++++++++++++++");
4172         }
4173 
4174         if (mDeviceStateMonitor != null) {
4175             pw.println("DeviceStateMonitor:");
4176             mDeviceStateMonitor.dump(fd, pw, args);
4177             pw.println("++++++++++++++++++++++++++++++++");
4178         }
4179 
4180         if (mTransportManager != null) {
4181             mTransportManager.dump(fd, pw, args);
4182         }
4183 
4184         if (mCi != null && mCi instanceof RIL) {
4185             try {
4186                 ((RIL)mCi).dump(fd, pw, args);
4187             } catch (Exception e) {
4188                 e.printStackTrace();
4189             }
4190 
4191             pw.flush();
4192             pw.println("++++++++++++++++++++++++++++++++");
4193         }
4194 
4195         pw.println("Phone Local Log: ");
4196         if (mLocalLog != null) {
4197             try {
4198                 mLocalLog.dump(fd, pw, args);
4199             } catch (Exception e) {
4200                 e.printStackTrace();
4201             }
4202             pw.flush();
4203             pw.println("++++++++++++++++++++++++++++++++");
4204         }
4205     }
4206 }
4207