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.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.content.SharedPreferences;
24 import android.net.LinkProperties;
25 import android.net.NetworkCapabilities;
26 import android.net.wifi.WifiManager;
27 import android.os.AsyncResult;
28 import android.os.Build;
29 import android.os.Bundle;
30 import android.os.Handler;
31 import android.os.Looper;
32 import android.os.Message;
33 import android.os.Registrant;
34 import android.os.RegistrantList;
35 import android.os.SystemProperties;
36 import android.preference.PreferenceManager;
37 import android.provider.Settings;
38 import android.telecom.VideoProfile;
39 import android.telephony.CellIdentityCdma;
40 import android.telephony.CellInfo;
41 import android.telephony.CellInfoCdma;
42 import android.telephony.PhoneStateListener;
43 import android.telephony.RadioAccessFamily;
44 import android.telephony.Rlog;
45 import android.telephony.ServiceState;
46 import android.telephony.SignalStrength;
47 import android.telephony.SubscriptionManager;
48 import android.telephony.VoLteServiceState;
49 import android.text.TextUtils;
50 
51 import com.android.ims.ImsConfig;
52 import com.android.ims.ImsManager;
53 import com.android.internal.R;
54 import com.android.internal.telephony.dataconnection.DcTracker;
55 import com.android.internal.telephony.test.SimulatedRadioControl;
56 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
57 import com.android.internal.telephony.uicc.IccFileHandler;
58 import com.android.internal.telephony.uicc.IccRecords;
59 import com.android.internal.telephony.uicc.IsimRecords;
60 import com.android.internal.telephony.uicc.UiccCard;
61 import com.android.internal.telephony.uicc.UiccCardApplication;
62 import com.android.internal.telephony.uicc.UiccController;
63 import com.android.internal.telephony.uicc.UsimServiceTable;
64 
65 import java.io.FileDescriptor;
66 import java.io.PrintWriter;
67 import java.util.ArrayList;
68 import java.util.HashSet;
69 import java.util.List;
70 import java.util.Locale;
71 import java.util.Set;
72 import java.util.concurrent.atomic.AtomicReference;
73 
74 /**
75  * (<em>Not for SDK use</em>)
76  * A base implementation for the com.android.internal.telephony.Phone interface.
77  *
78  * Note that implementations of Phone.java are expected to be used
79  * from a single application thread. This should be the same thread that
80  * originally called PhoneFactory to obtain the interface.
81  *
82  *  {@hide}
83  *
84  */
85 
86 public abstract class Phone extends Handler implements PhoneInternalInterface {
87     private static final String LOG_TAG = "Phone";
88 
89     protected final static Object lockForRadioTechnologyChange = new Object();
90 
91     private BroadcastReceiver mImsIntentReceiver = new BroadcastReceiver() {
92         @Override
93         public void onReceive(Context context, Intent intent) {
94             Rlog.d(LOG_TAG, "mImsIntentReceiver: action " + intent.getAction());
95             if (intent.hasExtra(ImsManager.EXTRA_PHONE_ID)) {
96                 int extraPhoneId = intent.getIntExtra(ImsManager.EXTRA_PHONE_ID,
97                         SubscriptionManager.INVALID_PHONE_INDEX);
98                 Rlog.d(LOG_TAG, "mImsIntentReceiver: extraPhoneId = " + extraPhoneId);
99                 if (extraPhoneId == SubscriptionManager.INVALID_PHONE_INDEX ||
100                         extraPhoneId != getPhoneId()) {
101                     return;
102                 }
103             }
104 
105             synchronized (Phone.lockForRadioTechnologyChange) {
106                 if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_UP)) {
107                     mImsServiceReady = true;
108                     updateImsPhone();
109                     ImsManager.updateImsServiceConfig(mContext, mPhoneId, false);
110                 } else if (intent.getAction().equals(ImsManager.ACTION_IMS_SERVICE_DOWN)) {
111                     mImsServiceReady = false;
112                     updateImsPhone();
113                 }
114             }
115         }
116     };
117 
118     // Key used to read and write the saved network selection numeric value
119     public static final String NETWORK_SELECTION_KEY = "network_selection_key";
120     // Key used to read and write the saved network selection operator name
121     public static final String NETWORK_SELECTION_NAME_KEY = "network_selection_name_key";
122     // Key used to read and write the saved network selection operator short name
123     public static final String NETWORK_SELECTION_SHORT_KEY = "network_selection_short_key";
124 
125 
126     // Key used to read/write "disable data connection on boot" pref (used for testing)
127     public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";
128 
129     /* Event Constants */
130     protected static final int EVENT_RADIO_AVAILABLE             = 1;
131     /** Supplementary Service Notification received. */
132     protected static final int EVENT_SSN                         = 2;
133     protected static final int EVENT_SIM_RECORDS_LOADED          = 3;
134     private static final int EVENT_MMI_DONE                      = 4;
135     protected static final int EVENT_RADIO_ON                    = 5;
136     protected static final int EVENT_GET_BASEBAND_VERSION_DONE   = 6;
137     protected static final int EVENT_USSD                        = 7;
138     protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE  = 8;
139     protected static final int EVENT_GET_IMEI_DONE               = 9;
140     protected static final int EVENT_GET_IMEISV_DONE             = 10;
141     private static final int EVENT_GET_SIM_STATUS_DONE           = 11;
142     protected static final int EVENT_SET_CALL_FORWARD_DONE       = 12;
143     protected static final int EVENT_GET_CALL_FORWARD_DONE       = 13;
144     protected static final int EVENT_CALL_RING                   = 14;
145     private static final int EVENT_CALL_RING_CONTINUE            = 15;
146 
147     // Used to intercept the carrier selection calls so that
148     // we can save the values.
149     private static final int EVENT_SET_NETWORK_MANUAL_COMPLETE      = 16;
150     private static final int EVENT_SET_NETWORK_AUTOMATIC_COMPLETE   = 17;
151     protected static final int EVENT_SET_CLIR_COMPLETE              = 18;
152     protected static final int EVENT_REGISTERED_TO_NETWORK          = 19;
153     protected static final int EVENT_SET_VM_NUMBER_DONE             = 20;
154     // Events for CDMA support
155     protected static final int EVENT_GET_DEVICE_IDENTITY_DONE       = 21;
156     protected static final int EVENT_RUIM_RECORDS_LOADED            = 22;
157     protected static final int EVENT_NV_READY                       = 23;
158     private static final int EVENT_SET_ENHANCED_VP                  = 24;
159     protected static final int EVENT_EMERGENCY_CALLBACK_MODE_ENTER  = 25;
160     protected static final int EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE = 26;
161     protected static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = 27;
162     // other
163     protected static final int EVENT_SET_NETWORK_AUTOMATIC          = 28;
164     protected static final int EVENT_ICC_RECORD_EVENTS              = 29;
165     private static final int EVENT_ICC_CHANGED                      = 30;
166     // Single Radio Voice Call Continuity
167     private static final int EVENT_SRVCC_STATE_CHANGED              = 31;
168     private static final int EVENT_INITIATE_SILENT_REDIAL           = 32;
169     private static final int EVENT_RADIO_NOT_AVAILABLE              = 33;
170     private static final int EVENT_UNSOL_OEM_HOOK_RAW               = 34;
171     protected static final int EVENT_GET_RADIO_CAPABILITY           = 35;
172     protected static final int EVENT_SS                             = 36;
173     private static final int EVENT_CONFIG_LCE                       = 37;
174     private static final int EVENT_CHECK_FOR_NETWORK_AUTOMATIC      = 38;
175     protected static final int EVENT_VOICE_RADIO_TECH_CHANGED       = 39;
176     protected static final int EVENT_REQUEST_VOICE_RADIO_TECH_DONE  = 40;
177     protected static final int EVENT_RIL_CONNECTED                  = 41;
178     protected static final int EVENT_UPDATE_PHONE_OBJECT            = 42;
179     protected static final int EVENT_CARRIER_CONFIG_CHANGED         = 43;
180     // Carrier's CDMA prefer mode setting
181     protected static final int EVENT_SET_ROAMING_PREFERENCE_DONE    = 44;
182 
183     protected static final int EVENT_LAST                           = EVENT_CARRIER_CONFIG_CHANGED;
184 
185     // For shared prefs.
186     private static final String GSM_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_roaming_list_";
187     private static final String GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_non_roaming_list_";
188     private static final String CDMA_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_roaming_list_";
189     private static final String CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX = "cdma_non_roaming_list_";
190 
191     // Key used to read/write current CLIR setting
192     public static final String CLIR_KEY = "clir_key";
193 
194     // Key used for storing voice mail count
195     private static final String VM_COUNT = "vm_count_key";
196     // Key used to read/write the ID for storing the voice mail
197     private static final String VM_ID = "vm_id_key";
198 
199     // Key used for storing call forwarding status
200     public static final String CF_STATUS = "cf_status_key";
201     // Key used to read/write the ID for storing the call forwarding status
202     public static final String CF_ID = "cf_id_key";
203 
204     // Key used to read/write "disable DNS server check" pref (used for testing)
205     private static final String DNS_SERVER_CHECK_DISABLED_KEY = "dns_server_check_disabled_key";
206 
207     /**
208      * Small container class used to hold information relevant to
209      * the carrier selection process. operatorNumeric can be ""
210      * if we are looking for automatic selection. operatorAlphaLong is the
211      * corresponding operator name.
212      */
213     private static class NetworkSelectMessage {
214         public Message message;
215         public String operatorNumeric;
216         public String operatorAlphaLong;
217         public String operatorAlphaShort;
218     }
219 
220     /* Instance Variables */
221     public CommandsInterface mCi;
222     protected int mVmCount = 0;
223     private boolean mDnsCheckDisabled;
224     public DcTracker mDcTracker;
225     private boolean mDoesRilSendMultipleCallRing;
226     private int mCallRingContinueToken;
227     private int mCallRingDelay;
228     private boolean mIsVoiceCapable = true;
229 
230     // Variable to cache the video capability. When RAT changes, we lose this info and are unable
231     // to recover from the state. We cache it and notify listeners when they register.
232     protected boolean mIsVideoCapable = false;
233     protected UiccController mUiccController = null;
234     protected final AtomicReference<IccRecords> mIccRecords = new AtomicReference<IccRecords>();
235     public SmsStorageMonitor mSmsStorageMonitor;
236     public SmsUsageMonitor mSmsUsageMonitor;
237     protected AtomicReference<UiccCardApplication> mUiccApplication =
238             new AtomicReference<UiccCardApplication>();
239 
240     private TelephonyTester mTelephonyTester;
241     private String mName;
242     private final String mActionDetached;
243     private final String mActionAttached;
244 
245     protected int mPhoneId;
246 
247     private boolean mImsServiceReady = false;
248     protected Phone mImsPhone = null;
249 
250     private final AtomicReference<RadioCapability> mRadioCapability =
251             new AtomicReference<RadioCapability>();
252 
253     private static final int DEFAULT_REPORT_INTERVAL_MS = 200;
254     private static final boolean LCE_PULL_MODE = true;
255     private int mLceStatus = RILConstants.LCE_NOT_AVAILABLE;
256     protected TelephonyComponentFactory mTelephonyComponentFactory;
257 
258     //IMS
259     public static final String CS_FALLBACK = "cs_fallback";
260     public static final String EXTRA_KEY_ALERT_TITLE = "alertTitle";
261     public static final String EXTRA_KEY_ALERT_MESSAGE = "alertMessage";
262     public static final String EXTRA_KEY_ALERT_SHOW = "alertShow";
263     protected static final String EXTRA_KEY_NOTIFICATION_MESSAGE = "notificationMessage";
264 
265     private final RegistrantList mPreciseCallStateRegistrants
266             = new RegistrantList();
267 
268     private final RegistrantList mHandoverRegistrants
269             = new RegistrantList();
270 
271     private final RegistrantList mNewRingingConnectionRegistrants
272             = new RegistrantList();
273 
274     private final RegistrantList mIncomingRingRegistrants
275             = new RegistrantList();
276 
277     protected final RegistrantList mDisconnectRegistrants
278             = new RegistrantList();
279 
280     private final RegistrantList mServiceStateRegistrants
281             = new RegistrantList();
282 
283     protected final RegistrantList mMmiCompleteRegistrants
284             = new RegistrantList();
285 
286     protected final RegistrantList mMmiRegistrants
287             = new RegistrantList();
288 
289     protected final RegistrantList mUnknownConnectionRegistrants
290             = new RegistrantList();
291 
292     protected final RegistrantList mSuppServiceFailedRegistrants
293             = new RegistrantList();
294 
295     protected final RegistrantList mRadioOffOrNotAvailableRegistrants
296             = new RegistrantList();
297 
298     protected final RegistrantList mSimRecordsLoadedRegistrants
299             = new RegistrantList();
300 
301     private final RegistrantList mVideoCapabilityChangedRegistrants
302             = new RegistrantList();
303 
304     protected final RegistrantList mEmergencyCallToggledRegistrants
305             = new RegistrantList();
306 
307     protected Registrant mPostDialHandler;
308 
309     private Looper mLooper; /* to insure registrants are in correct thread*/
310 
311     protected final Context mContext;
312 
313     /**
314      * PhoneNotifier is an abstraction for all system-wide
315      * state change notification. DefaultPhoneNotifier is
316      * used here unless running we're inside a unit test.
317      */
318     protected PhoneNotifier mNotifier;
319 
320     protected SimulatedRadioControl mSimulatedRadioControl;
321 
322     private boolean mUnitTestMode;
323 
getIccRecords()324     public IccRecords getIccRecords() {
325         return mIccRecords.get();
326     }
327 
328     /**
329      * Returns a string identifier for this phone interface for parties
330      *  outside the phone app process.
331      *  @return The string name.
332      */
getPhoneName()333     public String getPhoneName() {
334         return mName;
335     }
336 
setPhoneName(String name)337     protected void setPhoneName(String name) {
338         mName = name;
339     }
340 
341     /**
342      * Retrieves Nai for phones. Returns null if Nai is not set.
343      */
getNai()344     public String getNai(){
345          return null;
346     }
347 
348     /**
349      * Return the ActionDetached string. When this action is received by components
350      * they are to simulate detaching from the network.
351      *
352      * @return com.android.internal.telephony.{mName}.action_detached
353      *          {mName} is GSM, CDMA ...
354      */
getActionDetached()355     public String getActionDetached() {
356         return mActionDetached;
357     }
358 
359     /**
360      * Return the ActionAttached string. When this action is received by components
361      * they are to simulate attaching to the network.
362      *
363      * @return com.android.internal.telephony.{mName}.action_detached
364      *          {mName} is GSM, CDMA ...
365      */
getActionAttached()366     public String getActionAttached() {
367         return mActionAttached;
368     }
369 
370     /**
371      * Set a system property, unless we're in unit test mode
372      */
373     // CAF_MSIM TODO this need to be replated with TelephonyManager API ?
setSystemProperty(String property, String value)374     public void setSystemProperty(String property, String value) {
375         if(getUnitTestMode()) {
376             return;
377         }
378         SystemProperties.set(property, value);
379     }
380 
381     /**
382      * Set a system property, unless we're in unit test mode
383      */
384     // CAF_MSIM TODO this need to be replated with TelephonyManager API ?
getSystemProperty(String property, String defValue)385     public String getSystemProperty(String property, String defValue) {
386         if(getUnitTestMode()) {
387             return null;
388         }
389         return SystemProperties.get(property, defValue);
390     }
391 
392     /**
393      * Constructs a Phone in normal (non-unit test) mode.
394      *
395      * @param notifier An instance of DefaultPhoneNotifier,
396      * @param context Context object from hosting application
397      * unless unit testing.
398      * @param ci is CommandsInterface
399      * @param unitTestMode when true, prevents notifications
400      * of state change events
401      */
Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode)402     protected Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci,
403                     boolean unitTestMode) {
404         this(name, notifier, context, ci, unitTestMode, SubscriptionManager.DEFAULT_PHONE_INDEX,
405                 TelephonyComponentFactory.getInstance());
406     }
407 
408     /**
409      * Constructs a Phone in normal (non-unit test) mode.
410      *
411      * @param notifier An instance of DefaultPhoneNotifier,
412      * @param context Context object from hosting application
413      * unless unit testing.
414      * @param ci is CommandsInterface
415      * @param unitTestMode when true, prevents notifications
416      * of state change events
417      * @param phoneId the phone-id of this phone.
418      */
Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode, int phoneId, TelephonyComponentFactory telephonyComponentFactory)419     protected Phone(String name, PhoneNotifier notifier, Context context, CommandsInterface ci,
420                     boolean unitTestMode, int phoneId,
421                     TelephonyComponentFactory telephonyComponentFactory) {
422         mPhoneId = phoneId;
423         mName = name;
424         mNotifier = notifier;
425         mContext = context;
426         mLooper = Looper.myLooper();
427         mCi = ci;
428         mActionDetached = this.getClass().getPackage().getName() + ".action_detached";
429         mActionAttached = this.getClass().getPackage().getName() + ".action_attached";
430 
431         if (Build.IS_DEBUGGABLE) {
432             mTelephonyTester = new TelephonyTester(this);
433         }
434 
435         setUnitTestMode(unitTestMode);
436 
437         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
438         mDnsCheckDisabled = sp.getBoolean(DNS_SERVER_CHECK_DISABLED_KEY, false);
439         mCi.setOnCallRing(this, EVENT_CALL_RING, null);
440 
441         /* "Voice capable" means that this device supports circuit-switched
442         * (i.e. voice) phone calls over the telephony network, and is allowed
443         * to display the in-call UI while a cellular voice call is active.
444         * This will be false on "data only" devices which can't make voice
445         * calls and don't support any in-call UI.
446         */
447         mIsVoiceCapable = mContext.getResources().getBoolean(
448                 com.android.internal.R.bool.config_voice_capable);
449 
450         /**
451          *  Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs
452          *  to be generated locally. Ideally all ring tones should be loops
453          * and this wouldn't be necessary. But to minimize changes to upper
454          * layers it is requested that it be generated by lower layers.
455          *
456          * By default old phones won't have the property set but do generate
457          * the RIL_UNSOL_CALL_RING so the default if there is no property is
458          * true.
459          */
460         mDoesRilSendMultipleCallRing = SystemProperties.getBoolean(
461                 TelephonyProperties.PROPERTY_RIL_SENDS_MULTIPLE_CALL_RING, true);
462         Rlog.d(LOG_TAG, "mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
463 
464         mCallRingDelay = SystemProperties.getInt(
465                 TelephonyProperties.PROPERTY_CALL_RING_DELAY, 3000);
466         Rlog.d(LOG_TAG, "mCallRingDelay=" + mCallRingDelay);
467 
468         if (getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
469             return;
470         }
471 
472         // The locale from the "ro.carrier" system property or R.array.carrier_properties.
473         // This will be overwritten by the Locale from the SIM language settings (EF-PL, EF-LI)
474         // if applicable.
475         final Locale carrierLocale = getLocaleFromCarrierProperties(mContext);
476         if (carrierLocale != null && !TextUtils.isEmpty(carrierLocale.getCountry())) {
477             final String country = carrierLocale.getCountry();
478             try {
479                 Settings.Global.getInt(mContext.getContentResolver(),
480                         Settings.Global.WIFI_COUNTRY_CODE);
481             } catch (Settings.SettingNotFoundException e) {
482                 // note this is not persisting
483                 WifiManager wM = (WifiManager)
484                         mContext.getSystemService(Context.WIFI_SERVICE);
485                 wM.setCountryCode(country, false);
486             }
487         }
488 
489         // Initialize device storage and outgoing SMS usage monitors for SMSDispatchers.
490         mTelephonyComponentFactory = telephonyComponentFactory;
491         mSmsStorageMonitor = mTelephonyComponentFactory.makeSmsStorageMonitor(this);
492         mSmsUsageMonitor = mTelephonyComponentFactory.makeSmsUsageMonitor(context);
493         mUiccController = UiccController.getInstance();
494         mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
495         if (getPhoneType() != PhoneConstants.PHONE_TYPE_SIP) {
496             mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null);
497         }
498         mCi.setOnUnsolOemHookRaw(this, EVENT_UNSOL_OEM_HOOK_RAW, null);
499         mCi.startLceService(DEFAULT_REPORT_INTERVAL_MS, LCE_PULL_MODE,
500                 obtainMessage(EVENT_CONFIG_LCE));
501     }
502 
503     /**
504      * Start listening for IMS service UP/DOWN events.
505      */
startMonitoringImsService()506     public void startMonitoringImsService() {
507         if (getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) {
508             return;
509         }
510 
511         synchronized(Phone.lockForRadioTechnologyChange) {
512             IntentFilter filter = new IntentFilter();
513             filter.addAction(ImsManager.ACTION_IMS_SERVICE_UP);
514             filter.addAction(ImsManager.ACTION_IMS_SERVICE_DOWN);
515             mContext.registerReceiver(mImsIntentReceiver, filter);
516 
517             // Monitor IMS service - but first poll to see if already up (could miss
518             // intent)
519             ImsManager imsManager = ImsManager.getInstance(mContext, getPhoneId());
520             if (imsManager != null && imsManager.isServiceAvailable()) {
521                 mImsServiceReady = true;
522                 updateImsPhone();
523                 ImsManager.updateImsServiceConfig(mContext, mPhoneId, false);
524             }
525         }
526     }
527 
528     /**
529      * When overridden the derived class needs to call
530      * super.handleMessage(msg) so this method has a
531      * a chance to process the message.
532      *
533      * @param msg
534      */
535     @Override
handleMessage(Message msg)536     public void handleMessage(Message msg) {
537         AsyncResult ar;
538 
539         // messages to be handled whether or not the phone is being destroyed
540         // should only include messages which are being re-directed and do not use
541         // resources of the phone being destroyed
542         switch (msg.what) {
543             // handle the select network completion callbacks.
544             case EVENT_SET_NETWORK_MANUAL_COMPLETE:
545             case EVENT_SET_NETWORK_AUTOMATIC_COMPLETE:
546                 handleSetSelectNetwork((AsyncResult) msg.obj);
547                 return;
548         }
549 
550         switch(msg.what) {
551             case EVENT_CALL_RING:
552                 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING Received state=" + getState());
553                 ar = (AsyncResult)msg.obj;
554                 if (ar.exception == null) {
555                     PhoneConstants.State state = getState();
556                     if ((!mDoesRilSendMultipleCallRing)
557                             && ((state == PhoneConstants.State.RINGING) ||
558                                     (state == PhoneConstants.State.IDLE))) {
559                         mCallRingContinueToken += 1;
560                         sendIncomingCallRingNotification(mCallRingContinueToken);
561                     } else {
562                         notifyIncomingRing();
563                     }
564                 }
565                 break;
566 
567             case EVENT_CALL_RING_CONTINUE:
568                 Rlog.d(LOG_TAG, "Event EVENT_CALL_RING_CONTINUE Received state=" + getState());
569                 if (getState() == PhoneConstants.State.RINGING) {
570                     sendIncomingCallRingNotification(msg.arg1);
571                 }
572                 break;
573 
574             case EVENT_ICC_CHANGED:
575                 onUpdateIccAvailability();
576                 break;
577 
578             case EVENT_INITIATE_SILENT_REDIAL:
579                 Rlog.d(LOG_TAG, "Event EVENT_INITIATE_SILENT_REDIAL Received");
580                 ar = (AsyncResult) msg.obj;
581                 if ((ar.exception == null) && (ar.result != null)) {
582                     String dialString = (String) ar.result;
583                     if (TextUtils.isEmpty(dialString)) return;
584                     try {
585                         dialInternal(dialString, null, VideoProfile.STATE_AUDIO_ONLY, null);
586                     } catch (CallStateException e) {
587                         Rlog.e(LOG_TAG, "silent redial failed: " + e);
588                     }
589                 }
590                 break;
591 
592             case EVENT_SRVCC_STATE_CHANGED:
593                 ar = (AsyncResult)msg.obj;
594                 if (ar.exception == null) {
595                     handleSrvccStateChanged((int[]) ar.result);
596                 } else {
597                     Rlog.e(LOG_TAG, "Srvcc exception: " + ar.exception);
598                 }
599                 break;
600 
601             case EVENT_UNSOL_OEM_HOOK_RAW:
602                 ar = (AsyncResult)msg.obj;
603                 if (ar.exception == null) {
604                     byte[] data = (byte[])ar.result;
605                     mNotifier.notifyOemHookRawEventForSubscriber(getSubId(), data);
606                 } else {
607                     Rlog.e(LOG_TAG, "OEM hook raw exception: " + ar.exception);
608                 }
609                 break;
610 
611             case EVENT_CONFIG_LCE:
612                 ar = (AsyncResult) msg.obj;
613                 if (ar.exception != null) {
614                     Rlog.d(LOG_TAG, "config LCE service failed: " + ar.exception);
615                 } else {
616                     final ArrayList<Integer> statusInfo = (ArrayList<Integer>)ar.result;
617                     mLceStatus = statusInfo.get(0);
618                 }
619                 break;
620 
621             case EVENT_CHECK_FOR_NETWORK_AUTOMATIC: {
622                 onCheckForNetworkSelectionModeAutomatic(msg);
623                 break;
624             }
625             default:
626                 throw new RuntimeException("unexpected event not handled");
627         }
628     }
629 
getHandoverConnection()630     public ArrayList<Connection> getHandoverConnection() {
631         return null;
632     }
633 
notifySrvccState(Call.SrvccState state)634     public void notifySrvccState(Call.SrvccState state) {
635     }
636 
registerForSilentRedial(Handler h, int what, Object obj)637     public void registerForSilentRedial(Handler h, int what, Object obj) {
638     }
639 
unregisterForSilentRedial(Handler h)640     public void unregisterForSilentRedial(Handler h) {
641     }
642 
handleSrvccStateChanged(int[] ret)643     private void handleSrvccStateChanged(int[] ret) {
644         Rlog.d(LOG_TAG, "handleSrvccStateChanged");
645 
646         ArrayList<Connection> conn = null;
647         Phone imsPhone = mImsPhone;
648         Call.SrvccState srvccState = Call.SrvccState.NONE;
649         if (ret != null && ret.length != 0) {
650             int state = ret[0];
651             switch(state) {
652                 case VoLteServiceState.HANDOVER_STARTED:
653                     srvccState = Call.SrvccState.STARTED;
654                     if (imsPhone != null) {
655                         conn = imsPhone.getHandoverConnection();
656                         migrateFrom(imsPhone);
657                     } else {
658                         Rlog.d(LOG_TAG, "HANDOVER_STARTED: mImsPhone null");
659                     }
660                     break;
661                 case VoLteServiceState.HANDOVER_COMPLETED:
662                     srvccState = Call.SrvccState.COMPLETED;
663                     if (imsPhone != null) {
664                         imsPhone.notifySrvccState(srvccState);
665                     } else {
666                         Rlog.d(LOG_TAG, "HANDOVER_COMPLETED: mImsPhone null");
667                     }
668                     break;
669                 case VoLteServiceState.HANDOVER_FAILED:
670                 case VoLteServiceState.HANDOVER_CANCELED:
671                     srvccState = Call.SrvccState.FAILED;
672                     break;
673 
674                 default:
675                     //ignore invalid state
676                     return;
677             }
678 
679             getCallTracker().notifySrvccState(srvccState, conn);
680 
681             VoLteServiceState lteState = new VoLteServiceState(state);
682             notifyVoLteServiceStateChanged(lteState);
683         }
684     }
685 
686     /**
687      * Gets the context for the phone, as set at initialization time.
688      */
getContext()689     public Context getContext() {
690         return mContext;
691     }
692 
693     // Will be called when icc changed
onUpdateIccAvailability()694     protected abstract void onUpdateIccAvailability();
695 
696     /**
697      * Disables the DNS check (i.e., allows "0.0.0.0").
698      * Useful for lab testing environment.
699      * @param b true disables the check, false enables.
700      */
disableDnsCheck(boolean b)701     public void disableDnsCheck(boolean b) {
702         mDnsCheckDisabled = b;
703         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
704         SharedPreferences.Editor editor = sp.edit();
705         editor.putBoolean(DNS_SERVER_CHECK_DISABLED_KEY, b);
706         editor.apply();
707     }
708 
709     /**
710      * Returns true if the DNS check is currently disabled.
711      */
isDnsCheckDisabled()712     public boolean isDnsCheckDisabled() {
713         return mDnsCheckDisabled;
714     }
715 
716     /**
717      * Register for getting notifications for change in the Call State {@link Call.State}
718      * This is called PreciseCallState because the call state is more precise than the
719      * {@link PhoneConstants.State} which can be obtained using the {@link PhoneStateListener}
720      *
721      * Resulting events will have an AsyncResult in <code>Message.obj</code>.
722      * AsyncResult.userData will be set to the obj argument here.
723      * The <em>h</em> parameter is held only by a weak reference.
724      */
registerForPreciseCallStateChanged(Handler h, int what, Object obj)725     public void registerForPreciseCallStateChanged(Handler h, int what, Object obj) {
726         checkCorrectThread(h);
727 
728         mPreciseCallStateRegistrants.addUnique(h, what, obj);
729     }
730 
731     /**
732      * Unregisters for voice call state change notifications.
733      * Extraneous calls are tolerated silently.
734      */
unregisterForPreciseCallStateChanged(Handler h)735     public void unregisterForPreciseCallStateChanged(Handler h) {
736         mPreciseCallStateRegistrants.remove(h);
737     }
738 
739     /**
740      * Subclasses of Phone probably want to replace this with a
741      * version scoped to their packages
742      */
notifyPreciseCallStateChangedP()743     protected void notifyPreciseCallStateChangedP() {
744         AsyncResult ar = new AsyncResult(null, this, null);
745         mPreciseCallStateRegistrants.notifyRegistrants(ar);
746 
747         mNotifier.notifyPreciseCallState(this);
748     }
749 
750     /**
751      * Notifies when a Handover happens due to SRVCC or Silent Redial
752      */
registerForHandoverStateChanged(Handler h, int what, Object obj)753     public void registerForHandoverStateChanged(Handler h, int what, Object obj) {
754         checkCorrectThread(h);
755         mHandoverRegistrants.addUnique(h, what, obj);
756     }
757 
758     /**
759      * Unregisters for handover state notifications
760      */
unregisterForHandoverStateChanged(Handler h)761     public void unregisterForHandoverStateChanged(Handler h) {
762         mHandoverRegistrants.remove(h);
763     }
764 
765     /**
766      * Subclasses of Phone probably want to replace this with a
767      * version scoped to their packages
768      */
notifyHandoverStateChanged(Connection cn)769     public void notifyHandoverStateChanged(Connection cn) {
770        AsyncResult ar = new AsyncResult(null, cn, null);
771        mHandoverRegistrants.notifyRegistrants(ar);
772     }
773 
setIsInEmergencyCall()774     protected void setIsInEmergencyCall() {
775     }
776 
migrateFrom(Phone from)777     protected void migrateFrom(Phone from) {
778         migrate(mHandoverRegistrants, from.mHandoverRegistrants);
779         migrate(mPreciseCallStateRegistrants, from.mPreciseCallStateRegistrants);
780         migrate(mNewRingingConnectionRegistrants, from.mNewRingingConnectionRegistrants);
781         migrate(mIncomingRingRegistrants, from.mIncomingRingRegistrants);
782         migrate(mDisconnectRegistrants, from.mDisconnectRegistrants);
783         migrate(mServiceStateRegistrants, from.mServiceStateRegistrants);
784         migrate(mMmiCompleteRegistrants, from.mMmiCompleteRegistrants);
785         migrate(mMmiRegistrants, from.mMmiRegistrants);
786         migrate(mUnknownConnectionRegistrants, from.mUnknownConnectionRegistrants);
787         migrate(mSuppServiceFailedRegistrants, from.mSuppServiceFailedRegistrants);
788         if (from.isInEmergencyCall()) {
789             setIsInEmergencyCall();
790         }
791     }
792 
migrate(RegistrantList to, RegistrantList from)793     protected void migrate(RegistrantList to, RegistrantList from) {
794         from.removeCleared();
795         for (int i = 0, n = from.size(); i < n; i++) {
796             Registrant r = (Registrant) from.get(i);
797             Message msg = r.messageForRegistrant();
798             // Since CallManager has already registered with both CS and IMS phones,
799             // the migrate should happen only for those registrants which are not
800             // registered with CallManager.Hence the below check is needed to add
801             // only those registrants to the registrant list which are not
802             // coming from the CallManager.
803             if (msg != null) {
804                 if (msg.obj == CallManager.getInstance().getRegistrantIdentifier()) {
805                     continue;
806                 } else {
807                     to.add((Registrant) from.get(i));
808                 }
809             } else {
810                 Rlog.d(LOG_TAG, "msg is null");
811             }
812         }
813     }
814 
815     /**
816      * Notifies when a previously untracked non-ringing/waiting connection has appeared.
817      * This is likely due to some other entity (eg, SIM card application) initiating a call.
818      */
registerForUnknownConnection(Handler h, int what, Object obj)819     public void registerForUnknownConnection(Handler h, int what, Object obj) {
820         checkCorrectThread(h);
821 
822         mUnknownConnectionRegistrants.addUnique(h, what, obj);
823     }
824 
825     /**
826      * Unregisters for unknown connection notifications.
827      */
unregisterForUnknownConnection(Handler h)828     public void unregisterForUnknownConnection(Handler h) {
829         mUnknownConnectionRegistrants.remove(h);
830     }
831 
832     /**
833      * Notifies when a new ringing or waiting connection has appeared.<p>
834      *
835      *  Messages received from this:
836      *  Message.obj will be an AsyncResult
837      *  AsyncResult.userObj = obj
838      *  AsyncResult.result = a Connection. <p>
839      *  Please check Connection.isRinging() to make sure the Connection
840      *  has not dropped since this message was posted.
841      *  If Connection.isRinging() is true, then
842      *   Connection.getCall() == Phone.getRingingCall()
843      */
registerForNewRingingConnection( Handler h, int what, Object obj)844     public void registerForNewRingingConnection(
845             Handler h, int what, Object obj) {
846         checkCorrectThread(h);
847 
848         mNewRingingConnectionRegistrants.addUnique(h, what, obj);
849     }
850 
851     /**
852      * Unregisters for new ringing connection notification.
853      * Extraneous calls are tolerated silently
854      */
unregisterForNewRingingConnection(Handler h)855     public void unregisterForNewRingingConnection(Handler h) {
856         mNewRingingConnectionRegistrants.remove(h);
857     }
858 
859     /**
860      * Notifies when phone's video capabilities changes <p>
861      *
862      *  Messages received from this:
863      *  Message.obj will be an AsyncResult
864      *  AsyncResult.userObj = obj
865      *  AsyncResult.result = true if phone supports video calling <p>
866      */
registerForVideoCapabilityChanged( Handler h, int what, Object obj)867     public void registerForVideoCapabilityChanged(
868             Handler h, int what, Object obj) {
869         checkCorrectThread(h);
870 
871         mVideoCapabilityChangedRegistrants.addUnique(h, what, obj);
872 
873         // Notify any registrants of the cached video capability as soon as they register.
874         notifyForVideoCapabilityChanged(mIsVideoCapable);
875     }
876 
877     /**
878      * Unregisters for video capability changed notification.
879      * Extraneous calls are tolerated silently
880      */
unregisterForVideoCapabilityChanged(Handler h)881     public void unregisterForVideoCapabilityChanged(Handler h) {
882         mVideoCapabilityChangedRegistrants.remove(h);
883     }
884 
885     /**
886      * Register for notifications when a sInCall VoicePrivacy is enabled
887      *
888      * @param h Handler that receives the notification message.
889      * @param what User-defined message code.
890      * @param obj User object.
891      */
registerForInCallVoicePrivacyOn(Handler h, int what, Object obj)892     public void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj){
893         mCi.registerForInCallVoicePrivacyOn(h, what, obj);
894     }
895 
896     /**
897      * Unegister for notifications when a sInCall VoicePrivacy is enabled
898      *
899      * @param h Handler to be removed from the registrant list.
900      */
unregisterForInCallVoicePrivacyOn(Handler h)901     public void unregisterForInCallVoicePrivacyOn(Handler h){
902         mCi.unregisterForInCallVoicePrivacyOn(h);
903     }
904 
905     /**
906      * Register for notifications when a sInCall VoicePrivacy is disabled
907      *
908      * @param h Handler that receives the notification message.
909      * @param what User-defined message code.
910      * @param obj User object.
911      */
registerForInCallVoicePrivacyOff(Handler h, int what, Object obj)912     public void registerForInCallVoicePrivacyOff(Handler h, int what, Object obj){
913         mCi.registerForInCallVoicePrivacyOff(h, what, obj);
914     }
915 
916     /**
917      * Unregister for notifications when a sInCall VoicePrivacy is disabled
918      *
919      * @param h Handler to be removed from the registrant list.
920      */
unregisterForInCallVoicePrivacyOff(Handler h)921     public void unregisterForInCallVoicePrivacyOff(Handler h){
922         mCi.unregisterForInCallVoicePrivacyOff(h);
923     }
924 
925     /**
926      * Notifies when an incoming call rings.<p>
927      *
928      *  Messages received from this:
929      *  Message.obj will be an AsyncResult
930      *  AsyncResult.userObj = obj
931      *  AsyncResult.result = a Connection. <p>
932      */
registerForIncomingRing( Handler h, int what, Object obj)933     public void registerForIncomingRing(
934             Handler h, int what, Object obj) {
935         checkCorrectThread(h);
936 
937         mIncomingRingRegistrants.addUnique(h, what, obj);
938     }
939 
940     /**
941      * Unregisters for ring notification.
942      * Extraneous calls are tolerated silently
943      */
unregisterForIncomingRing(Handler h)944     public void unregisterForIncomingRing(Handler h) {
945         mIncomingRingRegistrants.remove(h);
946     }
947 
948     /**
949      * Notifies when a voice connection has disconnected, either due to local
950      * or remote hangup or error.
951      *
952      *  Messages received from this will have the following members:<p>
953      *  <ul><li>Message.obj will be an AsyncResult</li>
954      *  <li>AsyncResult.userObj = obj</li>
955      *  <li>AsyncResult.result = a Connection object that is
956      *  no longer connected.</li></ul>
957      */
registerForDisconnect(Handler h, int what, Object obj)958     public void registerForDisconnect(Handler h, int what, Object obj) {
959         checkCorrectThread(h);
960 
961         mDisconnectRegistrants.addUnique(h, what, obj);
962     }
963 
964     /**
965      * Unregisters for voice disconnection notification.
966      * Extraneous calls are tolerated silently
967      */
unregisterForDisconnect(Handler h)968     public void unregisterForDisconnect(Handler h) {
969         mDisconnectRegistrants.remove(h);
970     }
971 
972     /**
973      * Register for notifications when a supplementary service attempt fails.
974      * Message.obj will contain an AsyncResult.
975      *
976      * @param h Handler that receives the notification message.
977      * @param what User-defined message code.
978      * @param obj User object.
979      */
registerForSuppServiceFailed(Handler h, int what, Object obj)980     public void registerForSuppServiceFailed(Handler h, int what, Object obj) {
981         checkCorrectThread(h);
982 
983         mSuppServiceFailedRegistrants.addUnique(h, what, obj);
984     }
985 
986     /**
987      * Unregister for notifications when a supplementary service attempt fails.
988      * Extraneous calls are tolerated silently
989      *
990      * @param h Handler to be removed from the registrant list.
991      */
unregisterForSuppServiceFailed(Handler h)992     public void unregisterForSuppServiceFailed(Handler h) {
993         mSuppServiceFailedRegistrants.remove(h);
994     }
995 
996     /**
997      * Register for notifications of initiation of a new MMI code request.
998      * MMI codes for GSM are discussed in 3GPP TS 22.030.<p>
999      *
1000      * Example: If Phone.dial is called with "*#31#", then the app will
1001      * be notified here.<p>
1002      *
1003      * The returned <code>Message.obj</code> will contain an AsyncResult.
1004      *
1005      * <code>obj.result</code> will be an "MmiCode" object.
1006      */
registerForMmiInitiate(Handler h, int what, Object obj)1007     public void registerForMmiInitiate(Handler h, int what, Object obj) {
1008         checkCorrectThread(h);
1009 
1010         mMmiRegistrants.addUnique(h, what, obj);
1011     }
1012 
1013     /**
1014      * Unregisters for new MMI initiate notification.
1015      * Extraneous calls are tolerated silently
1016      */
unregisterForMmiInitiate(Handler h)1017     public void unregisterForMmiInitiate(Handler h) {
1018         mMmiRegistrants.remove(h);
1019     }
1020 
1021     /**
1022      * Register for notifications that an MMI request has completed
1023      * its network activity and is in its final state. This may mean a state
1024      * of COMPLETE, FAILED, or CANCELLED.
1025      *
1026      * <code>Message.obj</code> will contain an AsyncResult.
1027      * <code>obj.result</code> will be an "MmiCode" object
1028      */
registerForMmiComplete(Handler h, int what, Object obj)1029     public void registerForMmiComplete(Handler h, int what, Object obj) {
1030         checkCorrectThread(h);
1031 
1032         mMmiCompleteRegistrants.addUnique(h, what, obj);
1033     }
1034 
1035     /**
1036      * Unregisters for MMI complete notification.
1037      * Extraneous calls are tolerated silently
1038      */
unregisterForMmiComplete(Handler h)1039     public void unregisterForMmiComplete(Handler h) {
1040         checkCorrectThread(h);
1041 
1042         mMmiCompleteRegistrants.remove(h);
1043     }
1044 
1045     /**
1046      * Registration point for Sim records loaded
1047      * @param h handler to notify
1048      * @param what what code of message when delivered
1049      * @param obj placed in Message.obj
1050      */
registerForSimRecordsLoaded(Handler h, int what, Object obj)1051     public void registerForSimRecordsLoaded(Handler h, int what, Object obj) {
1052     }
1053 
1054     /**
1055      * Unregister for notifications for Sim records loaded
1056      * @param h Handler to be removed from the registrant list.
1057      */
unregisterForSimRecordsLoaded(Handler h)1058     public void unregisterForSimRecordsLoaded(Handler h) {
1059     }
1060 
1061     /**
1062      * Register for TTY mode change notifications from the network.
1063      * Message.obj will contain an AsyncResult.
1064      * AsyncResult.result will be an Integer containing new mode.
1065      *
1066      * @param h Handler that receives the notification message.
1067      * @param what User-defined message code.
1068      * @param obj User object.
1069      */
registerForTtyModeReceived(Handler h, int what, Object obj)1070     public void registerForTtyModeReceived(Handler h, int what, Object obj) {
1071     }
1072 
1073     /**
1074      * Unregisters for TTY mode change notifications.
1075      * Extraneous calls are tolerated silently
1076      *
1077      * @param h Handler to be removed from the registrant list.
1078      */
unregisterForTtyModeReceived(Handler h)1079     public void unregisterForTtyModeReceived(Handler h) {
1080     }
1081 
1082     /**
1083      * Switches network selection mode to "automatic", re-scanning and
1084      * re-selecting a network if appropriate.
1085      *
1086      * @param response The message to dispatch when the network selection
1087      * is complete.
1088      *
1089      * @see #selectNetworkManually(OperatorInfo, boolean, android.os.Message)
1090      */
setNetworkSelectionModeAutomatic(Message response)1091     public void setNetworkSelectionModeAutomatic(Message response) {
1092         Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic, querying current mode");
1093         // we don't want to do this unecesarily - it acutally causes
1094         // the radio to repeate network selection and is costly
1095         // first check if we're already in automatic mode
1096         Message msg = obtainMessage(EVENT_CHECK_FOR_NETWORK_AUTOMATIC);
1097         msg.obj = response;
1098         mCi.getNetworkSelectionMode(msg);
1099     }
1100 
onCheckForNetworkSelectionModeAutomatic(Message fromRil)1101     private void onCheckForNetworkSelectionModeAutomatic(Message fromRil) {
1102         AsyncResult ar = (AsyncResult)fromRil.obj;
1103         Message response = (Message)ar.userObj;
1104         boolean doAutomatic = true;
1105         if (ar.exception == null && ar.result != null) {
1106             try {
1107                 int[] modes = (int[])ar.result;
1108                 if (modes[0] == 0) {
1109                     // already confirmed to be in automatic mode - don't resend
1110                     doAutomatic = false;
1111                 }
1112             } catch (Exception e) {
1113                 // send the setting on error
1114             }
1115         }
1116 
1117         // wrap the response message in our own message along with
1118         // an empty string (to indicate automatic selection) for the
1119         // operator's id.
1120         NetworkSelectMessage nsm = new NetworkSelectMessage();
1121         nsm.message = response;
1122         nsm.operatorNumeric = "";
1123         nsm.operatorAlphaLong = "";
1124         nsm.operatorAlphaShort = "";
1125 
1126         if (doAutomatic) {
1127             Message msg = obtainMessage(EVENT_SET_NETWORK_AUTOMATIC_COMPLETE, nsm);
1128             mCi.setNetworkSelectionModeAutomatic(msg);
1129         } else {
1130             Rlog.d(LOG_TAG, "setNetworkSelectionModeAutomatic - already auto, ignoring");
1131             ar.userObj = nsm;
1132             handleSetSelectNetwork(ar);
1133         }
1134 
1135         updateSavedNetworkOperator(nsm);
1136     }
1137 
1138     /**
1139      * Query the radio for the current network selection mode.
1140      *
1141      * Return values:
1142      *     0 - automatic.
1143      *     1 - manual.
1144      */
getNetworkSelectionMode(Message message)1145     public void getNetworkSelectionMode(Message message) {
1146         mCi.getNetworkSelectionMode(message);
1147     }
1148 
1149     /**
1150      * Manually selects a network. <code>response</code> is
1151      * dispatched when this is complete.  <code>response.obj</code> will be
1152      * an AsyncResult, and <code>response.obj.exception</code> will be non-null
1153      * on failure.
1154      *
1155      * @see #setNetworkSelectionModeAutomatic(Message)
1156      */
selectNetworkManually(OperatorInfo network, boolean persistSelection, Message response)1157     public void selectNetworkManually(OperatorInfo network, boolean persistSelection,
1158             Message response) {
1159         // wrap the response message in our own message along with
1160         // the operator's id.
1161         NetworkSelectMessage nsm = new NetworkSelectMessage();
1162         nsm.message = response;
1163         nsm.operatorNumeric = network.getOperatorNumeric();
1164         nsm.operatorAlphaLong = network.getOperatorAlphaLong();
1165         nsm.operatorAlphaShort = network.getOperatorAlphaShort();
1166 
1167         Message msg = obtainMessage(EVENT_SET_NETWORK_MANUAL_COMPLETE, nsm);
1168         mCi.setNetworkSelectionModeManual(network.getOperatorNumeric(), msg);
1169 
1170         if (persistSelection) {
1171             updateSavedNetworkOperator(nsm);
1172         } else {
1173             clearSavedNetworkSelection();
1174         }
1175     }
1176 
1177     /**
1178      * Registration point for emergency call/callback mode start. Message.obj is AsyncResult and
1179      * Message.obj.result will be Integer indicating start of call by value 1 or end of call by
1180      * value 0
1181      * @param h handler to notify
1182      * @param what what code of message when delivered
1183      * @param obj placed in Message.obj.userObj
1184      */
registerForEmergencyCallToggle(Handler h, int what, Object obj)1185     public void registerForEmergencyCallToggle(Handler h, int what, Object obj) {
1186         Registrant r = new Registrant(h, what, obj);
1187         mEmergencyCallToggledRegistrants.add(r);
1188     }
1189 
unregisterForEmergencyCallToggle(Handler h)1190     public void unregisterForEmergencyCallToggle(Handler h) {
1191         mEmergencyCallToggledRegistrants.remove(h);
1192     }
1193 
updateSavedNetworkOperator(NetworkSelectMessage nsm)1194     private void updateSavedNetworkOperator(NetworkSelectMessage nsm) {
1195         int subId = getSubId();
1196         if (SubscriptionManager.isValidSubscriptionId(subId)) {
1197             // open the shared preferences editor, and write the value.
1198             // nsm.operatorNumeric is "" if we're in automatic.selection.
1199             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
1200             SharedPreferences.Editor editor = sp.edit();
1201             editor.putString(NETWORK_SELECTION_KEY + subId, nsm.operatorNumeric);
1202             editor.putString(NETWORK_SELECTION_NAME_KEY + subId, nsm.operatorAlphaLong);
1203             editor.putString(NETWORK_SELECTION_SHORT_KEY + subId, nsm.operatorAlphaShort);
1204 
1205             // commit and log the result.
1206             if (!editor.commit()) {
1207                 Rlog.e(LOG_TAG, "failed to commit network selection preference");
1208             }
1209         } else {
1210             Rlog.e(LOG_TAG, "Cannot update network selection preference due to invalid subId " +
1211                     subId);
1212         }
1213     }
1214 
1215     /**
1216      * Used to track the settings upon completion of the network change.
1217      */
handleSetSelectNetwork(AsyncResult ar)1218     private void handleSetSelectNetwork(AsyncResult ar) {
1219         // look for our wrapper within the asyncresult, skip the rest if it
1220         // is null.
1221         if (!(ar.userObj instanceof NetworkSelectMessage)) {
1222             Rlog.e(LOG_TAG, "unexpected result from user object.");
1223             return;
1224         }
1225 
1226         NetworkSelectMessage nsm = (NetworkSelectMessage) ar.userObj;
1227 
1228         // found the object, now we send off the message we had originally
1229         // attached to the request.
1230         if (nsm.message != null) {
1231             AsyncResult.forMessage(nsm.message, ar.result, ar.exception);
1232             nsm.message.sendToTarget();
1233         }
1234     }
1235 
1236     /**
1237      * Method to retrieve the saved operator from the Shared Preferences
1238      */
getSavedNetworkSelection()1239     private OperatorInfo getSavedNetworkSelection() {
1240         // open the shared preferences and search with our key.
1241         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
1242         String numeric = sp.getString(NETWORK_SELECTION_KEY + getSubId(), "");
1243         String name = sp.getString(NETWORK_SELECTION_NAME_KEY + getSubId(), "");
1244         String shrt = sp.getString(NETWORK_SELECTION_SHORT_KEY + getSubId(), "");
1245         return new OperatorInfo(name, shrt, numeric);
1246     }
1247 
1248     /**
1249      * Clears the saved network selection.
1250      */
clearSavedNetworkSelection()1251     private void clearSavedNetworkSelection() {
1252         // open the shared preferences and search with our key.
1253         PreferenceManager.getDefaultSharedPreferences(getContext()).edit().
1254                 remove(NETWORK_SELECTION_KEY + getSubId()).
1255                 remove(NETWORK_SELECTION_NAME_KEY + getSubId()).
1256                 remove(NETWORK_SELECTION_SHORT_KEY + getSubId()).commit();
1257     }
1258 
1259     /**
1260      * Method to restore the previously saved operator id, or reset to
1261      * automatic selection, all depending upon the value in the shared
1262      * preferences.
1263      */
restoreSavedNetworkSelection(Message response)1264     private void restoreSavedNetworkSelection(Message response) {
1265         // retrieve the operator
1266         OperatorInfo networkSelection = getSavedNetworkSelection();
1267 
1268         // set to auto if the id is empty, otherwise select the network.
1269         if (networkSelection == null || TextUtils.isEmpty(networkSelection.getOperatorNumeric())) {
1270             setNetworkSelectionModeAutomatic(response);
1271         } else {
1272             selectNetworkManually(networkSelection, true, response);
1273         }
1274     }
1275 
1276     /**
1277      * Saves CLIR setting so that we can re-apply it as necessary
1278      * (in case the RIL resets it across reboots).
1279      */
saveClirSetting(int commandInterfaceCLIRMode)1280     public void saveClirSetting(int commandInterfaceCLIRMode) {
1281         // Open the shared preferences editor, and write the value.
1282         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
1283         SharedPreferences.Editor editor = sp.edit();
1284         editor.putInt(CLIR_KEY + getPhoneId(), commandInterfaceCLIRMode);
1285 
1286         // Commit and log the result.
1287         if (!editor.commit()) {
1288             Rlog.e(LOG_TAG, "Failed to commit CLIR preference");
1289         }
1290     }
1291 
1292     /**
1293      * For unit tests; don't send notifications to "Phone"
1294      * mailbox registrants if true.
1295      */
setUnitTestMode(boolean f)1296     private void setUnitTestMode(boolean f) {
1297         mUnitTestMode = f;
1298     }
1299 
1300     /**
1301      * @return true If unit test mode is enabled
1302      */
getUnitTestMode()1303     public boolean getUnitTestMode() {
1304         return mUnitTestMode;
1305     }
1306 
1307     /**
1308      * To be invoked when a voice call Connection disconnects.
1309      *
1310      * Subclasses of Phone probably want to replace this with a
1311      * version scoped to their packages
1312      */
notifyDisconnectP(Connection cn)1313     protected void notifyDisconnectP(Connection cn) {
1314         AsyncResult ar = new AsyncResult(null, cn, null);
1315         mDisconnectRegistrants.notifyRegistrants(ar);
1316     }
1317 
1318     /**
1319      * Register for ServiceState changed.
1320      * Message.obj will contain an AsyncResult.
1321      * AsyncResult.result will be a ServiceState instance
1322      */
registerForServiceStateChanged( Handler h, int what, Object obj)1323     public void registerForServiceStateChanged(
1324             Handler h, int what, Object obj) {
1325         checkCorrectThread(h);
1326 
1327         mServiceStateRegistrants.add(h, what, obj);
1328     }
1329 
1330     /**
1331      * Unregisters for ServiceStateChange notification.
1332      * Extraneous calls are tolerated silently
1333      */
unregisterForServiceStateChanged(Handler h)1334     public void unregisterForServiceStateChanged(Handler h) {
1335         mServiceStateRegistrants.remove(h);
1336     }
1337 
1338     /**
1339      * Notifies when out-band ringback tone is needed.<p>
1340      *
1341      *  Messages received from this:
1342      *  Message.obj will be an AsyncResult
1343      *  AsyncResult.userObj = obj
1344      *  AsyncResult.result = boolean, true to start play ringback tone
1345      *                       and false to stop. <p>
1346      */
registerForRingbackTone(Handler h, int what, Object obj)1347     public void registerForRingbackTone(Handler h, int what, Object obj) {
1348         mCi.registerForRingbackTone(h, what, obj);
1349     }
1350 
1351     /**
1352      * Unregisters for ringback tone notification.
1353      */
unregisterForRingbackTone(Handler h)1354     public void unregisterForRingbackTone(Handler h) {
1355         mCi.unregisterForRingbackTone(h);
1356     }
1357 
1358     /**
1359      * Notifies when out-band on-hold tone is needed.<p>
1360      *
1361      *  Messages received from this:
1362      *  Message.obj will be an AsyncResult
1363      *  AsyncResult.userObj = obj
1364      *  AsyncResult.result = boolean, true to start play on-hold tone
1365      *                       and false to stop. <p>
1366      */
registerForOnHoldTone(Handler h, int what, Object obj)1367     public void registerForOnHoldTone(Handler h, int what, Object obj) {
1368     }
1369 
1370     /**
1371      * Unregisters for on-hold tone notification.
1372      */
unregisterForOnHoldTone(Handler h)1373     public void unregisterForOnHoldTone(Handler h) {
1374     }
1375 
1376     /**
1377      * Registers the handler to reset the uplink mute state to get
1378      * uplink audio.
1379      */
registerForResendIncallMute(Handler h, int what, Object obj)1380     public void registerForResendIncallMute(Handler h, int what, Object obj) {
1381         mCi.registerForResendIncallMute(h, what, obj);
1382     }
1383 
1384     /**
1385      * Unregisters for resend incall mute notifications.
1386      */
unregisterForResendIncallMute(Handler h)1387     public void unregisterForResendIncallMute(Handler h) {
1388         mCi.unregisterForResendIncallMute(h);
1389     }
1390 
1391     /**
1392      * Enables or disables echo suppression.
1393      */
setEchoSuppressionEnabled()1394     public void setEchoSuppressionEnabled() {
1395         // no need for regular phone
1396     }
1397 
1398     /**
1399      * Subclasses of Phone probably want to replace this with a
1400      * version scoped to their packages
1401      */
notifyServiceStateChangedP(ServiceState ss)1402     protected void notifyServiceStateChangedP(ServiceState ss) {
1403         AsyncResult ar = new AsyncResult(null, ss, null);
1404         mServiceStateRegistrants.notifyRegistrants(ar);
1405 
1406         mNotifier.notifyServiceState(this);
1407     }
1408 
1409     /**
1410      * If this is a simulated phone interface, returns a SimulatedRadioControl.
1411      * @return SimulatedRadioControl if this is a simulated interface;
1412      * otherwise, null.
1413      */
getSimulatedRadioControl()1414     public SimulatedRadioControl getSimulatedRadioControl() {
1415         return mSimulatedRadioControl;
1416     }
1417 
1418     /**
1419      * Verifies the current thread is the same as the thread originally
1420      * used in the initialization of this instance. Throws RuntimeException
1421      * if not.
1422      *
1423      * @exception RuntimeException if the current thread is not
1424      * the thread that originally obtained this Phone instance.
1425      */
checkCorrectThread(Handler h)1426     private void checkCorrectThread(Handler h) {
1427         if (h.getLooper() != mLooper) {
1428             throw new RuntimeException(
1429                     "com.android.internal.telephony.Phone must be used from within one thread");
1430         }
1431     }
1432 
1433     /**
1434      * Set the properties by matching the carrier string in
1435      * a string-array resource
1436      */
getLocaleFromCarrierProperties(Context ctx)1437     private static Locale getLocaleFromCarrierProperties(Context ctx) {
1438         String carrier = SystemProperties.get("ro.carrier");
1439 
1440         if (null == carrier || 0 == carrier.length() || "unknown".equals(carrier)) {
1441             return null;
1442         }
1443 
1444         CharSequence[] carrierLocales = ctx.getResources().getTextArray(R.array.carrier_properties);
1445 
1446         for (int i = 0; i < carrierLocales.length; i+=3) {
1447             String c = carrierLocales[i].toString();
1448             if (carrier.equals(c)) {
1449                 return Locale.forLanguageTag(carrierLocales[i + 1].toString().replace('_', '-'));
1450             }
1451         }
1452 
1453         return null;
1454     }
1455 
1456     /**
1457      * Get current coarse-grained voice call state.
1458      * Use {@link #registerForPreciseCallStateChanged(Handler, int, Object)
1459      * registerForPreciseCallStateChanged()} for change notification. <p>
1460      * If the phone has an active call and call waiting occurs,
1461      * then the phone state is RINGING not OFFHOOK
1462      * <strong>Note:</strong>
1463      * This registration point provides notification of finer-grained
1464      * changes.<p>
1465      */
getState()1466     public abstract PhoneConstants.State getState();
1467 
1468     /**
1469      * Retrieves the IccFileHandler of the Phone instance
1470      */
getIccFileHandler()1471     public IccFileHandler getIccFileHandler(){
1472         UiccCardApplication uiccApplication = mUiccApplication.get();
1473         IccFileHandler fh;
1474 
1475         if (uiccApplication == null) {
1476             Rlog.d(LOG_TAG, "getIccFileHandler: uiccApplication == null, return null");
1477             fh = null;
1478         } else {
1479             fh = uiccApplication.getIccFileHandler();
1480         }
1481 
1482         Rlog.d(LOG_TAG, "getIccFileHandler: fh=" + fh);
1483         return fh;
1484     }
1485 
1486     /*
1487      * Retrieves the Handler of the Phone instance
1488      */
getHandler()1489     public Handler getHandler() {
1490         return this;
1491     }
1492 
1493     /**
1494      * Update the phone object if the voice radio technology has changed
1495      *
1496      * @param voiceRadioTech The new voice radio technology
1497      */
updatePhoneObject(int voiceRadioTech)1498     public void updatePhoneObject(int voiceRadioTech) {
1499     }
1500 
1501     /**
1502     * Retrieves the ServiceStateTracker of the phone instance.
1503     */
getServiceStateTracker()1504     public ServiceStateTracker getServiceStateTracker() {
1505         return null;
1506     }
1507 
1508     /**
1509     * Get call tracker
1510     */
getCallTracker()1511     public CallTracker getCallTracker() {
1512         return null;
1513     }
1514 
1515     /**
1516      * Update voice mail count related fields and notify listeners
1517      */
updateVoiceMail()1518     public void updateVoiceMail() {
1519         Rlog.e(LOG_TAG, "updateVoiceMail() should be overridden");
1520     }
1521 
getCurrentUiccAppType()1522     public AppType getCurrentUiccAppType() {
1523         UiccCardApplication currentApp = mUiccApplication.get();
1524         if (currentApp != null) {
1525             return currentApp.getType();
1526         }
1527         return AppType.APPTYPE_UNKNOWN;
1528     }
1529 
1530     /**
1531      * Returns the ICC card interface for this phone, or null
1532      * if not applicable to underlying technology.
1533      */
getIccCard()1534     public IccCard getIccCard() {
1535         return null;
1536         //throw new Exception("getIccCard Shouldn't be called from Phone");
1537     }
1538 
1539     /**
1540      * Retrieves the serial number of the ICC, if applicable. Returns only the decimal digits before
1541      * the first hex digit in the ICC ID.
1542      */
getIccSerialNumber()1543     public String getIccSerialNumber() {
1544         IccRecords r = mIccRecords.get();
1545         return (r != null) ? r.getIccId() : null;
1546     }
1547 
1548     /**
1549      * Retrieves the full serial number of the ICC (including hex digits), if applicable.
1550      */
getFullIccSerialNumber()1551     public String getFullIccSerialNumber() {
1552         IccRecords r = mIccRecords.get();
1553         return (r != null) ? r.getFullIccId() : null;
1554     }
1555 
1556     /**
1557      * Returns SIM record load state. Use
1558      * <code>getSimCard().registerForReady()</code> for change notification.
1559      *
1560      * @return true if records from the SIM have been loaded and are
1561      * available (if applicable). If not applicable to the underlying
1562      * technology, returns true as well.
1563      */
getIccRecordsLoaded()1564     public boolean getIccRecordsLoaded() {
1565         IccRecords r = mIccRecords.get();
1566         return (r != null) ? r.getRecordsLoaded() : false;
1567     }
1568 
1569     /**
1570      * @return all available cell information or null if none.
1571      */
getAllCellInfo()1572     public List<CellInfo> getAllCellInfo() {
1573         List<CellInfo> cellInfoList = getServiceStateTracker().getAllCellInfo();
1574         return privatizeCellInfoList(cellInfoList);
1575     }
1576 
1577     /**
1578      * Clear CDMA base station lat/long values if location setting is disabled.
1579      * @param cellInfoList the original cell info list from the RIL
1580      * @return the original list with CDMA lat/long cleared if necessary
1581      */
privatizeCellInfoList(List<CellInfo> cellInfoList)1582     private List<CellInfo> privatizeCellInfoList(List<CellInfo> cellInfoList) {
1583         if (cellInfoList == null) return null;
1584         int mode = Settings.Secure.getInt(getContext().getContentResolver(),
1585                 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
1586         if (mode == Settings.Secure.LOCATION_MODE_OFF) {
1587             ArrayList<CellInfo> privateCellInfoList = new ArrayList<CellInfo>(cellInfoList.size());
1588             // clear lat/lon values for location privacy
1589             for (CellInfo c : cellInfoList) {
1590                 if (c instanceof CellInfoCdma) {
1591                     CellInfoCdma cellInfoCdma = (CellInfoCdma) c;
1592                     CellIdentityCdma cellIdentity = cellInfoCdma.getCellIdentity();
1593                     CellIdentityCdma maskedCellIdentity = new CellIdentityCdma(
1594                             cellIdentity.getNetworkId(),
1595                             cellIdentity.getSystemId(),
1596                             cellIdentity.getBasestationId(),
1597                             Integer.MAX_VALUE, Integer.MAX_VALUE);
1598                     CellInfoCdma privateCellInfoCdma = new CellInfoCdma(cellInfoCdma);
1599                     privateCellInfoCdma.setCellIdentity(maskedCellIdentity);
1600                     privateCellInfoList.add(privateCellInfoCdma);
1601                 } else {
1602                     privateCellInfoList.add(c);
1603                 }
1604             }
1605             cellInfoList = privateCellInfoList;
1606         }
1607         return cellInfoList;
1608     }
1609 
1610     /**
1611      * Sets the minimum time in milli-seconds between {@link PhoneStateListener#onCellInfoChanged
1612      * PhoneStateListener.onCellInfoChanged} will be invoked.
1613      *
1614      * The default, 0, means invoke onCellInfoChanged when any of the reported
1615      * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue
1616      * A onCellInfoChanged.
1617      *
1618      * @param rateInMillis the rate
1619      */
setCellInfoListRate(int rateInMillis)1620     public void setCellInfoListRate(int rateInMillis) {
1621         mCi.setCellInfoListRate(rateInMillis, null);
1622     }
1623 
1624     /**
1625      * Get voice message waiting indicator status. No change notification
1626      * available on this interface. Use PhoneStateNotifier or similar instead.
1627      *
1628      * @return true if there is a voice message waiting
1629      */
getMessageWaitingIndicator()1630     public boolean getMessageWaitingIndicator() {
1631         return mVmCount != 0;
1632     }
1633 
getCallForwardingIndicatorFromSharedPref()1634     private int getCallForwardingIndicatorFromSharedPref() {
1635         int status = IccRecords.CALL_FORWARDING_STATUS_DISABLED;
1636         int subId = getSubId();
1637         if (SubscriptionManager.isValidSubscriptionId(subId)) {
1638             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
1639             status = sp.getInt(CF_STATUS + subId, IccRecords.CALL_FORWARDING_STATUS_UNKNOWN);
1640             Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: for subId " + subId + "= " +
1641                     status);
1642             // Check for old preference if status is UNKNOWN for current subId. This part of the
1643             // code is needed only when upgrading from M to N.
1644             if (status == IccRecords.CALL_FORWARDING_STATUS_UNKNOWN) {
1645                 String subscriberId = sp.getString(CF_ID, null);
1646                 if (subscriberId != null) {
1647                     String currentSubscriberId = getSubscriberId();
1648 
1649                     if (subscriberId.equals(currentSubscriberId)) {
1650                         // get call forwarding status from preferences
1651                         status = sp.getInt(CF_STATUS, IccRecords.CALL_FORWARDING_STATUS_DISABLED);
1652                         setCallForwardingIndicatorInSharedPref(
1653                                 status == IccRecords.CALL_FORWARDING_STATUS_ENABLED ? true : false);
1654                         Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: " + status);
1655                     } else {
1656                         Rlog.d(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: returning " +
1657                                 "DISABLED as status for matching subscriberId not found");
1658                     }
1659 
1660                     // get rid of old preferences.
1661                     SharedPreferences.Editor editor = sp.edit();
1662                     editor.remove(CF_ID);
1663                     editor.remove(CF_STATUS);
1664                     editor.apply();
1665                 }
1666             }
1667         } else {
1668             Rlog.e(LOG_TAG, "getCallForwardingIndicatorFromSharedPref: invalid subId " + subId);
1669         }
1670         return status;
1671     }
1672 
setCallForwardingIndicatorInSharedPref(boolean enable)1673     private void setCallForwardingIndicatorInSharedPref(boolean enable) {
1674         int status = enable ? IccRecords.CALL_FORWARDING_STATUS_ENABLED :
1675                 IccRecords.CALL_FORWARDING_STATUS_DISABLED;
1676         int subId = getSubId();
1677         Rlog.d(LOG_TAG, "setCallForwardingIndicatorInSharedPref: Storing status = " + status +
1678                 " in pref " + CF_STATUS + subId);
1679 
1680         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
1681         SharedPreferences.Editor editor = sp.edit();
1682         editor.putInt(CF_STATUS + subId, status);
1683         editor.apply();
1684     }
1685 
setVoiceCallForwardingFlag(int line, boolean enable, String number)1686     public void setVoiceCallForwardingFlag(int line, boolean enable, String number) {
1687         setCallForwardingIndicatorInSharedPref(enable);
1688         IccRecords r = mIccRecords.get();
1689         if (r != null) {
1690             r.setVoiceCallForwardingFlag(line, enable, number);
1691         }
1692     }
1693 
setVoiceCallForwardingFlag(IccRecords r, int line, boolean enable, String number)1694     protected void setVoiceCallForwardingFlag(IccRecords r, int line, boolean enable,
1695                                               String number) {
1696         setCallForwardingIndicatorInSharedPref(enable);
1697         r.setVoiceCallForwardingFlag(line, enable, number);
1698     }
1699 
1700     /**
1701      * Get voice call forwarding indicator status. No change notification
1702      * available on this interface. Use PhoneStateNotifier or similar instead.
1703      *
1704      * @return true if there is a voice call forwarding
1705      */
getCallForwardingIndicator()1706     public boolean getCallForwardingIndicator() {
1707         if (getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
1708             Rlog.e(LOG_TAG, "getCallForwardingIndicator: not possible in CDMA");
1709             return false;
1710         }
1711         IccRecords r = mIccRecords.get();
1712         int callForwardingIndicator = IccRecords.CALL_FORWARDING_STATUS_UNKNOWN;
1713         if (r != null) {
1714             callForwardingIndicator = r.getVoiceCallForwardingFlag();
1715         }
1716         if (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_UNKNOWN) {
1717             callForwardingIndicator = getCallForwardingIndicatorFromSharedPref();
1718         }
1719         return (callForwardingIndicator == IccRecords.CALL_FORWARDING_STATUS_ENABLED);
1720     }
1721 
1722     /**
1723      *  Query the CDMA roaming preference setting
1724      *
1725      * @param response is callback message to report one of  CDMA_RM_*
1726      */
queryCdmaRoamingPreference(Message response)1727     public void queryCdmaRoamingPreference(Message response) {
1728         mCi.queryCdmaRoamingPreference(response);
1729     }
1730 
1731     /**
1732      * Get current signal strength. No change notification available on this
1733      * interface. Use <code>PhoneStateNotifier</code> or an equivalent.
1734      * An ASU is 0-31 or -1 if unknown (for GSM, dBm = -113 - 2 * asu).
1735      * The following special values are defined:</p>
1736      * <ul><li>0 means "-113 dBm or less".</li>
1737      * <li>31 means "-51 dBm or greater".</li></ul>
1738      *
1739      * @return Current signal strength as SignalStrength
1740      */
getSignalStrength()1741     public SignalStrength getSignalStrength() {
1742         ServiceStateTracker sst = getServiceStateTracker();
1743         if (sst == null) {
1744             return new SignalStrength();
1745         } else {
1746             return sst.getSignalStrength();
1747         }
1748     }
1749 
1750     /**
1751      *  Requests to set the CDMA roaming preference
1752      * @param cdmaRoamingType one of  CDMA_RM_*
1753      * @param response is callback message
1754      */
setCdmaRoamingPreference(int cdmaRoamingType, Message response)1755     public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
1756         mCi.setCdmaRoamingPreference(cdmaRoamingType, response);
1757     }
1758 
1759     /**
1760      *  Requests to set the CDMA subscription mode
1761      * @param cdmaSubscriptionType one of  CDMA_SUBSCRIPTION_*
1762      * @param response is callback message
1763      */
setCdmaSubscription(int cdmaSubscriptionType, Message response)1764     public void setCdmaSubscription(int cdmaSubscriptionType, Message response) {
1765         mCi.setCdmaSubscriptionSource(cdmaSubscriptionType, response);
1766     }
1767 
1768     /**
1769      *  Requests to set the preferred network type for searching and registering
1770      * (CS/PS domain, RAT, and operation mode)
1771      * @param networkType one of  NT_*_TYPE
1772      * @param response is callback message
1773      */
setPreferredNetworkType(int networkType, Message response)1774     public void setPreferredNetworkType(int networkType, Message response) {
1775         // Only set preferred network types to that which the modem supports
1776         int modemRaf = getRadioAccessFamily();
1777         int rafFromType = RadioAccessFamily.getRafFromNetworkType(networkType);
1778 
1779         if (modemRaf == RadioAccessFamily.RAF_UNKNOWN
1780                 || rafFromType == RadioAccessFamily.RAF_UNKNOWN) {
1781             Rlog.d(LOG_TAG, "setPreferredNetworkType: Abort, unknown RAF: "
1782                     + modemRaf + " " + rafFromType);
1783             if (response != null) {
1784                 CommandException ex;
1785 
1786                 ex = new CommandException(CommandException.Error.GENERIC_FAILURE);
1787                 AsyncResult.forMessage(response, null, ex);
1788                 response.sendToTarget();
1789             }
1790             return;
1791         }
1792 
1793         int filteredRaf = (rafFromType & modemRaf);
1794         int filteredType = RadioAccessFamily.getNetworkTypeFromRaf(filteredRaf);
1795 
1796         Rlog.d(LOG_TAG, "setPreferredNetworkType: networkType = " + networkType
1797                 + " modemRaf = " + modemRaf
1798                 + " rafFromType = " + rafFromType
1799                 + " filteredType = " + filteredType);
1800 
1801         mCi.setPreferredNetworkType(filteredType, response);
1802     }
1803 
1804     /**
1805      *  Query the preferred network type setting
1806      *
1807      * @param response is callback message to report one of  NT_*_TYPE
1808      */
getPreferredNetworkType(Message response)1809     public void getPreferredNetworkType(Message response) {
1810         mCi.getPreferredNetworkType(response);
1811     }
1812 
1813     /**
1814      * Gets the default SMSC address.
1815      *
1816      * @param result Callback message contains the SMSC address.
1817      */
getSmscAddress(Message result)1818     public void getSmscAddress(Message result) {
1819         mCi.getSmscAddress(result);
1820     }
1821 
1822     /**
1823      * Sets the default SMSC address.
1824      *
1825      * @param address new SMSC address
1826      * @param result Callback message is empty on completion
1827      */
setSmscAddress(String address, Message result)1828     public void setSmscAddress(String address, Message result) {
1829         mCi.setSmscAddress(address, result);
1830     }
1831 
1832     /**
1833      * setTTYMode
1834      * sets a TTY mode option.
1835      * @param ttyMode is a one of the following:
1836      * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
1837      * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
1838      * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
1839      * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
1840      * @param onComplete a callback message when the action is completed
1841      */
setTTYMode(int ttyMode, Message onComplete)1842     public void setTTYMode(int ttyMode, Message onComplete) {
1843         mCi.setTTYMode(ttyMode, onComplete);
1844     }
1845 
1846     /**
1847      * setUiTTYMode
1848      * sets a TTY mode option.
1849      * @param ttyMode is a one of the following:
1850      * - {@link com.android.internal.telephony.Phone#TTY_MODE_OFF}
1851      * - {@link com.android.internal.telephony.Phone#TTY_MODE_FULL}
1852      * - {@link com.android.internal.telephony.Phone#TTY_MODE_HCO}
1853      * - {@link com.android.internal.telephony.Phone#TTY_MODE_VCO}
1854      * @param onComplete a callback message when the action is completed
1855      */
setUiTTYMode(int uiTtyMode, Message onComplete)1856     public void setUiTTYMode(int uiTtyMode, Message onComplete) {
1857         Rlog.d(LOG_TAG, "unexpected setUiTTYMode method call");
1858     }
1859 
1860     /**
1861      * queryTTYMode
1862      * query the status of the TTY mode
1863      *
1864      * @param onComplete a callback message when the action is completed.
1865      */
queryTTYMode(Message onComplete)1866     public void queryTTYMode(Message onComplete) {
1867         mCi.queryTTYMode(onComplete);
1868     }
1869 
1870     /**
1871      * Enable or disable enhanced Voice Privacy (VP). If enhanced VP is
1872      * disabled, normal VP is enabled.
1873      *
1874      * @param enable whether true or false to enable or disable.
1875      * @param onComplete a callback message when the action is completed.
1876      */
enableEnhancedVoicePrivacy(boolean enable, Message onComplete)1877     public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
1878     }
1879 
1880     /**
1881      * Get the currently set Voice Privacy (VP) mode.
1882      *
1883      * @param onComplete a callback message when the action is completed.
1884      */
getEnhancedVoicePrivacy(Message onComplete)1885     public void getEnhancedVoicePrivacy(Message onComplete) {
1886     }
1887 
1888     /**
1889      * Assign a specified band for RF configuration.
1890      *
1891      * @param bandMode one of BM_*_BAND
1892      * @param response is callback message
1893      */
setBandMode(int bandMode, Message response)1894     public void setBandMode(int bandMode, Message response) {
1895         mCi.setBandMode(bandMode, response);
1896     }
1897 
1898     /**
1899      * Query the list of band mode supported by RF.
1900      *
1901      * @param response is callback message
1902      *        ((AsyncResult)response.obj).result  is an int[] where int[0] is
1903      *        the size of the array and the rest of each element representing
1904      *        one available BM_*_BAND
1905      */
queryAvailableBandMode(Message response)1906     public void queryAvailableBandMode(Message response) {
1907         mCi.queryAvailableBandMode(response);
1908     }
1909 
1910     /**
1911      * Invokes RIL_REQUEST_OEM_HOOK_RAW on RIL implementation.
1912      *
1913      * @param data The data for the request.
1914      * @param response <strong>On success</strong>,
1915      * (byte[])(((AsyncResult)response.obj).result)
1916      * <strong>On failure</strong>,
1917      * (((AsyncResult)response.obj).result) == null and
1918      * (((AsyncResult)response.obj).exception) being an instance of
1919      * com.android.internal.telephony.gsm.CommandException
1920      *
1921      * @see #invokeOemRilRequestRaw(byte[], android.os.Message)
1922      */
invokeOemRilRequestRaw(byte[] data, Message response)1923     public void invokeOemRilRequestRaw(byte[] data, Message response) {
1924         mCi.invokeOemRilRequestRaw(data, response);
1925     }
1926 
1927     /**
1928      * Invokes RIL_REQUEST_OEM_HOOK_Strings on RIL implementation.
1929      *
1930      * @param strings The strings to make available as the request data.
1931      * @param response <strong>On success</strong>, "response" bytes is
1932      * made available as:
1933      * (String[])(((AsyncResult)response.obj).result).
1934      * <strong>On failure</strong>,
1935      * (((AsyncResult)response.obj).result) == null and
1936      * (((AsyncResult)response.obj).exception) being an instance of
1937      * com.android.internal.telephony.gsm.CommandException
1938      *
1939      * @see #invokeOemRilRequestStrings(java.lang.String[], android.os.Message)
1940      */
invokeOemRilRequestStrings(String[] strings, Message response)1941     public void invokeOemRilRequestStrings(String[] strings, Message response) {
1942         mCi.invokeOemRilRequestStrings(strings, response);
1943     }
1944 
1945     /**
1946      * Read one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}.
1947      * Used for device configuration by some CDMA operators.
1948      *
1949      * @param itemID the ID of the item to read
1950      * @param response callback message with the String response in the obj field
1951      */
nvReadItem(int itemID, Message response)1952     public void nvReadItem(int itemID, Message response) {
1953         mCi.nvReadItem(itemID, response);
1954     }
1955 
1956     /**
1957      * Write one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}.
1958      * Used for device configuration by some CDMA operators.
1959      *
1960      * @param itemID the ID of the item to read
1961      * @param itemValue the value to write, as a String
1962      * @param response Callback message.
1963      */
nvWriteItem(int itemID, String itemValue, Message response)1964     public void nvWriteItem(int itemID, String itemValue, Message response) {
1965         mCi.nvWriteItem(itemID, itemValue, response);
1966     }
1967 
1968     /**
1969      * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
1970      * Used for device configuration by some CDMA operators.
1971      *
1972      * @param preferredRoamingList byte array containing the new PRL
1973      * @param response Callback message.
1974      */
nvWriteCdmaPrl(byte[] preferredRoamingList, Message response)1975     public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message response) {
1976         mCi.nvWriteCdmaPrl(preferredRoamingList, response);
1977     }
1978 
1979     /**
1980      * Perform the specified type of NV config reset. The radio will be taken offline
1981      * and the device must be rebooted after erasing the NV. Used for device
1982      * configuration by some CDMA operators.
1983      *
1984      * @param resetType reset type: 1: reload NV reset, 2: erase NV reset, 3: factory NV reset
1985      * @param response Callback message.
1986      */
nvResetConfig(int resetType, Message response)1987     public void nvResetConfig(int resetType, Message response) {
1988         mCi.nvResetConfig(resetType, response);
1989     }
1990 
notifyDataActivity()1991     public void notifyDataActivity() {
1992         mNotifier.notifyDataActivity(this);
1993     }
1994 
notifyMessageWaitingIndicator()1995     private void notifyMessageWaitingIndicator() {
1996         // Do not notify voice mail waiting if device doesn't support voice
1997         if (!mIsVoiceCapable)
1998             return;
1999 
2000         // This function is added to send the notification to DefaultPhoneNotifier.
2001         mNotifier.notifyMessageWaitingChanged(this);
2002     }
2003 
notifyDataConnection(String reason, String apnType, PhoneConstants.DataState state)2004     public void notifyDataConnection(String reason, String apnType,
2005             PhoneConstants.DataState state) {
2006         mNotifier.notifyDataConnection(this, reason, apnType, state);
2007     }
2008 
notifyDataConnection(String reason, String apnType)2009     public void notifyDataConnection(String reason, String apnType) {
2010         mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
2011     }
2012 
notifyDataConnection(String reason)2013     public void notifyDataConnection(String reason) {
2014         String types[] = getActiveApnTypes();
2015         for (String apnType : types) {
2016             mNotifier.notifyDataConnection(this, reason, apnType, getDataConnectionState(apnType));
2017         }
2018     }
2019 
notifyOtaspChanged(int otaspMode)2020     public void notifyOtaspChanged(int otaspMode) {
2021         mNotifier.notifyOtaspChanged(this, otaspMode);
2022     }
2023 
notifySignalStrength()2024     public void notifySignalStrength() {
2025         mNotifier.notifySignalStrength(this);
2026     }
2027 
notifyCellInfo(List<CellInfo> cellInfo)2028     public void notifyCellInfo(List<CellInfo> cellInfo) {
2029         mNotifier.notifyCellInfo(this, privatizeCellInfoList(cellInfo));
2030     }
2031 
notifyVoLteServiceStateChanged(VoLteServiceState lteState)2032     public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) {
2033         mNotifier.notifyVoLteServiceStateChanged(this, lteState);
2034     }
2035 
2036     /**
2037      * @return true if a mobile originating emergency call is active
2038      */
isInEmergencyCall()2039     public boolean isInEmergencyCall() {
2040         return false;
2041     }
2042 
2043     /**
2044      * @return {@code true} if we are in emergency call back mode. This is a period where the phone
2045      * should be using as little power as possible and be ready to receive an incoming call from the
2046      * emergency operator.
2047      */
isInEcm()2048     public boolean isInEcm() {
2049         return false;
2050     }
2051 
getVideoState(Call call)2052     private static int getVideoState(Call call) {
2053         int videoState = VideoProfile.STATE_AUDIO_ONLY;
2054         Connection conn = call.getEarliestConnection();
2055         if (conn != null) {
2056             videoState = conn.getVideoState();
2057         }
2058         return videoState;
2059     }
2060 
isVideoCall(Call call)2061     private boolean isVideoCall(Call call) {
2062         int videoState = getVideoState(call);
2063         return (VideoProfile.isVideo(videoState));
2064     }
2065 
2066     /**
2067      * @return {@code true} if video call is present, false otherwise.
2068      */
isVideoCallPresent()2069     public boolean isVideoCallPresent() {
2070         boolean isVideoCallActive = false;
2071         if (mImsPhone != null) {
2072             isVideoCallActive = isVideoCall(mImsPhone.getForegroundCall()) ||
2073                     isVideoCall(mImsPhone.getBackgroundCall()) ||
2074                     isVideoCall(mImsPhone.getRingingCall());
2075         }
2076         Rlog.d(LOG_TAG, "isVideoCallActive: " + isVideoCallActive);
2077         return isVideoCallActive;
2078     }
2079 
2080     /**
2081      * Return a numerical identifier for the phone radio interface.
2082      * @return PHONE_TYPE_XXX as defined above.
2083      */
getPhoneType()2084     public abstract int getPhoneType();
2085 
2086     /**
2087      * Returns unread voicemail count. This count is shown when the  voicemail
2088      * notification is expanded.<p>
2089      */
getVoiceMessageCount()2090     public int getVoiceMessageCount(){
2091         return mVmCount;
2092     }
2093 
2094     /** sets the voice mail count of the phone and notifies listeners. */
setVoiceMessageCount(int countWaiting)2095     public void setVoiceMessageCount(int countWaiting) {
2096         mVmCount = countWaiting;
2097         int subId = getSubId();
2098         if (SubscriptionManager.isValidSubscriptionId(subId)) {
2099 
2100             Rlog.d(LOG_TAG, "setVoiceMessageCount: Storing Voice Mail Count = " + countWaiting +
2101                     " for mVmCountKey = " + VM_COUNT + subId + " in preferences.");
2102 
2103             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
2104             SharedPreferences.Editor editor = sp.edit();
2105             editor.putInt(VM_COUNT + subId, countWaiting);
2106             editor.apply();
2107         } else {
2108             Rlog.e(LOG_TAG, "setVoiceMessageCount in sharedPreference: invalid subId " + subId);
2109         }
2110         // notify listeners of voice mail
2111         notifyMessageWaitingIndicator();
2112     }
2113 
2114     /** gets the voice mail count from preferences */
getStoredVoiceMessageCount()2115     protected int getStoredVoiceMessageCount() {
2116         int countVoiceMessages = 0;
2117         int subId = getSubId();
2118         if (SubscriptionManager.isValidSubscriptionId(subId)) {
2119             int invalidCount = -2;  //-1 is not really invalid. It is used for unknown number of vm
2120             SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
2121             int countFromSP = sp.getInt(VM_COUNT + subId, invalidCount);
2122             if (countFromSP != invalidCount) {
2123                 countVoiceMessages = countFromSP;
2124                 Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: from preference for subId " + subId +
2125                         "= " + countVoiceMessages);
2126             } else {
2127                 // Check for old preference if count not found for current subId. This part of the
2128                 // code is needed only when upgrading from M to N.
2129                 String subscriberId = sp.getString(VM_ID, null);
2130                 if (subscriberId != null) {
2131                     String currentSubscriberId = getSubscriberId();
2132 
2133                     if (currentSubscriberId != null && currentSubscriberId.equals(subscriberId)) {
2134                         // get voice mail count from preferences
2135                         countVoiceMessages = sp.getInt(VM_COUNT, 0);
2136                         setVoiceMessageCount(countVoiceMessages);
2137                         Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: from preference = " +
2138                                 countVoiceMessages);
2139                     } else {
2140                         Rlog.d(LOG_TAG, "getStoredVoiceMessageCount: returning 0 as count for " +
2141                                 "matching subscriberId not found");
2142 
2143                     }
2144                     // get rid of old preferences.
2145                     SharedPreferences.Editor editor = sp.edit();
2146                     editor.remove(VM_ID);
2147                     editor.remove(VM_COUNT);
2148                     editor.apply();
2149                 }
2150             }
2151         } else {
2152             Rlog.e(LOG_TAG, "getStoredVoiceMessageCount: invalid subId " + subId);
2153         }
2154         return countVoiceMessages;
2155     }
2156 
2157     /**
2158      * Returns the CDMA ERI icon index to display
2159      */
getCdmaEriIconIndex()2160     public int getCdmaEriIconIndex() {
2161         return -1;
2162     }
2163 
2164     /**
2165      * Returns the CDMA ERI icon mode,
2166      * 0 - ON
2167      * 1 - FLASHING
2168      */
getCdmaEriIconMode()2169     public int getCdmaEriIconMode() {
2170         return -1;
2171     }
2172 
2173     /**
2174      * Returns the CDMA ERI text,
2175      */
getCdmaEriText()2176     public String getCdmaEriText() {
2177         return "GSM nw, no ERI";
2178     }
2179 
2180     /**
2181      * Retrieves the MIN for CDMA phones.
2182      */
getCdmaMin()2183     public String getCdmaMin() {
2184         return null;
2185     }
2186 
2187     /**
2188      * Check if subscription data has been assigned to mMin
2189      *
2190      * return true if MIN info is ready; false otherwise.
2191      */
isMinInfoReady()2192     public boolean isMinInfoReady() {
2193         return false;
2194     }
2195 
2196     /**
2197      *  Retrieves PRL Version for CDMA phones
2198      */
getCdmaPrlVersion()2199     public String getCdmaPrlVersion(){
2200         return null;
2201     }
2202 
2203     /**
2204      * send burst DTMF tone, it can send the string as single character or multiple character
2205      * ignore if there is no active call or not valid digits string.
2206      * Valid digit means only includes characters ISO-LATIN characters 0-9, *, #
2207      * The difference between sendDtmf and sendBurstDtmf is sendDtmf only sends one character,
2208      * this api can send single character and multiple character, also, this api has response
2209      * back to caller.
2210      *
2211      * @param dtmfString is string representing the dialing digit(s) in the active call
2212      * @param on the DTMF ON length in milliseconds, or 0 for default
2213      * @param off the DTMF OFF length in milliseconds, or 0 for default
2214      * @param onComplete is the callback message when the action is processed by BP
2215      *
2216      */
sendBurstDtmf(String dtmfString, int on, int off, Message onComplete)2217     public void sendBurstDtmf(String dtmfString, int on, int off, Message onComplete) {
2218     }
2219 
2220     /**
2221      * Sets an event to be fired when the telephony system processes
2222      * a post-dial character on an outgoing call.<p>
2223      *
2224      * Messages of type <code>what</code> will be sent to <code>h</code>.
2225      * The <code>obj</code> field of these Message's will be instances of
2226      * <code>AsyncResult</code>. <code>Message.obj.result</code> will be
2227      * a Connection object.<p>
2228      *
2229      * Message.arg1 will be the post dial character being processed,
2230      * or 0 ('\0') if end of string.<p>
2231      *
2232      * If Connection.getPostDialState() == WAIT,
2233      * the application must call
2234      * {@link com.android.internal.telephony.Connection#proceedAfterWaitChar()
2235      * Connection.proceedAfterWaitChar()} or
2236      * {@link com.android.internal.telephony.Connection#cancelPostDial()
2237      * Connection.cancelPostDial()}
2238      * for the telephony system to continue playing the post-dial
2239      * DTMF sequence.<p>
2240      *
2241      * If Connection.getPostDialState() == WILD,
2242      * the application must call
2243      * {@link com.android.internal.telephony.Connection#proceedAfterWildChar
2244      * Connection.proceedAfterWildChar()}
2245      * or
2246      * {@link com.android.internal.telephony.Connection#cancelPostDial()
2247      * Connection.cancelPostDial()}
2248      * for the telephony system to continue playing the
2249      * post-dial DTMF sequence.<p>
2250      *
2251      * Only one post dial character handler may be set. <p>
2252      * Calling this method with "h" equal to null unsets this handler.<p>
2253      */
setOnPostDialCharacter(Handler h, int what, Object obj)2254     public void setOnPostDialCharacter(Handler h, int what, Object obj) {
2255         mPostDialHandler = new Registrant(h, what, obj);
2256     }
2257 
getPostDialHandler()2258     public Registrant getPostDialHandler() {
2259         return mPostDialHandler;
2260     }
2261 
2262     /**
2263      * request to exit emergency call back mode
2264      * the caller should use setOnECMModeExitResponse
2265      * to receive the emergency callback mode exit response
2266      */
exitEmergencyCallbackMode()2267     public void exitEmergencyCallbackMode() {
2268     }
2269 
2270     /**
2271      * Register for notifications when CDMA OTA Provision status change
2272      *
2273      * @param h Handler that receives the notification message.
2274      * @param what User-defined message code.
2275      * @param obj User object.
2276      */
registerForCdmaOtaStatusChange(Handler h, int what, Object obj)2277     public void registerForCdmaOtaStatusChange(Handler h, int what, Object obj) {
2278     }
2279 
2280     /**
2281      * Unregister for notifications when CDMA OTA Provision status change
2282      * @param h Handler to be removed from the registrant list.
2283      */
unregisterForCdmaOtaStatusChange(Handler h)2284     public void unregisterForCdmaOtaStatusChange(Handler h) {
2285     }
2286 
2287     /**
2288      * Registration point for subscription info ready
2289      * @param h handler to notify
2290      * @param what what code of message when delivered
2291      * @param obj placed in Message.obj
2292      */
registerForSubscriptionInfoReady(Handler h, int what, Object obj)2293     public void registerForSubscriptionInfoReady(Handler h, int what, Object obj) {
2294     }
2295 
2296     /**
2297      * Unregister for notifications for subscription info
2298      * @param h Handler to be removed from the registrant list.
2299      */
unregisterForSubscriptionInfoReady(Handler h)2300     public void unregisterForSubscriptionInfoReady(Handler h) {
2301     }
2302 
2303     /**
2304      * Returns true if OTA Service Provisioning needs to be performed.
2305      */
needsOtaServiceProvisioning()2306     public boolean needsOtaServiceProvisioning() {
2307         return false;
2308     }
2309 
2310     /**
2311      * this decides if the dial number is OTA(Over the air provision) number or not
2312      * @param dialStr is string representing the dialing digit(s)
2313      * @return  true means the dialStr is OTA number, and false means the dialStr is not OTA number
2314      */
isOtaSpNumber(String dialStr)2315     public  boolean isOtaSpNumber(String dialStr) {
2316         return false;
2317     }
2318 
2319     /**
2320      * Register for notifications when CDMA call waiting comes
2321      *
2322      * @param h Handler that receives the notification message.
2323      * @param what User-defined message code.
2324      * @param obj User object.
2325      */
registerForCallWaiting(Handler h, int what, Object obj)2326     public void registerForCallWaiting(Handler h, int what, Object obj){
2327     }
2328 
2329     /**
2330      * Unegister for notifications when CDMA Call waiting comes
2331      * @param h Handler to be removed from the registrant list.
2332      */
unregisterForCallWaiting(Handler h)2333     public void unregisterForCallWaiting(Handler h){
2334     }
2335 
2336     /**
2337      * Registration point for Ecm timer reset
2338      * @param h handler to notify
2339      * @param what user-defined message code
2340      * @param obj placed in Message.obj
2341      */
registerForEcmTimerReset(Handler h, int what, Object obj)2342     public void registerForEcmTimerReset(Handler h, int what, Object obj) {
2343     }
2344 
2345     /**
2346      * Unregister for notification for Ecm timer reset
2347      * @param h Handler to be removed from the registrant list.
2348      */
unregisterForEcmTimerReset(Handler h)2349     public void unregisterForEcmTimerReset(Handler h) {
2350     }
2351 
2352     /**
2353      * Register for signal information notifications from the network.
2354      * Message.obj will contain an AsyncResult.
2355      * AsyncResult.result will be a SuppServiceNotification instance.
2356      *
2357      * @param h Handler that receives the notification message.
2358      * @param what User-defined message code.
2359      * @param obj User object.
2360      */
registerForSignalInfo(Handler h, int what, Object obj)2361     public void registerForSignalInfo(Handler h, int what, Object obj) {
2362         mCi.registerForSignalInfo(h, what, obj);
2363     }
2364 
2365     /**
2366      * Unregisters for signal information notifications.
2367      * Extraneous calls are tolerated silently
2368      *
2369      * @param h Handler to be removed from the registrant list.
2370      */
unregisterForSignalInfo(Handler h)2371     public void unregisterForSignalInfo(Handler h) {
2372         mCi.unregisterForSignalInfo(h);
2373     }
2374 
2375     /**
2376      * Register for display information notifications from the network.
2377      * Message.obj will contain an AsyncResult.
2378      * AsyncResult.result will be a SuppServiceNotification instance.
2379      *
2380      * @param h Handler that receives the notification message.
2381      * @param what User-defined message code.
2382      * @param obj User object.
2383      */
registerForDisplayInfo(Handler h, int what, Object obj)2384     public void registerForDisplayInfo(Handler h, int what, Object obj) {
2385         mCi.registerForDisplayInfo(h, what, obj);
2386     }
2387 
2388     /**
2389      * Unregisters for display information notifications.
2390      * Extraneous calls are tolerated silently
2391      *
2392      * @param h Handler to be removed from the registrant list.
2393      */
unregisterForDisplayInfo(Handler h)2394     public void unregisterForDisplayInfo(Handler h) {
2395          mCi.unregisterForDisplayInfo(h);
2396     }
2397 
2398     /**
2399      * Register for CDMA number information record notification from the network.
2400      * Message.obj will contain an AsyncResult.
2401      * AsyncResult.result will be a CdmaInformationRecords.CdmaNumberInfoRec
2402      * instance.
2403      *
2404      * @param h Handler that receives the notification message.
2405      * @param what User-defined message code.
2406      * @param obj User object.
2407      */
registerForNumberInfo(Handler h, int what, Object obj)2408     public void registerForNumberInfo(Handler h, int what, Object obj) {
2409         mCi.registerForNumberInfo(h, what, obj);
2410     }
2411 
2412     /**
2413      * Unregisters for number information record notifications.
2414      * Extraneous calls are tolerated silently
2415      *
2416      * @param h Handler to be removed from the registrant list.
2417      */
unregisterForNumberInfo(Handler h)2418     public void unregisterForNumberInfo(Handler h) {
2419         mCi.unregisterForNumberInfo(h);
2420     }
2421 
2422     /**
2423      * Register for CDMA redirected number information record notification
2424      * from the network.
2425      * Message.obj will contain an AsyncResult.
2426      * AsyncResult.result will be a CdmaInformationRecords.CdmaRedirectingNumberInfoRec
2427      * instance.
2428      *
2429      * @param h Handler that receives the notification message.
2430      * @param what User-defined message code.
2431      * @param obj User object.
2432      */
registerForRedirectedNumberInfo(Handler h, int what, Object obj)2433     public void registerForRedirectedNumberInfo(Handler h, int what, Object obj) {
2434         mCi.registerForRedirectedNumberInfo(h, what, obj);
2435     }
2436 
2437     /**
2438      * Unregisters for redirected number information record notification.
2439      * Extraneous calls are tolerated silently
2440      *
2441      * @param h Handler to be removed from the registrant list.
2442      */
unregisterForRedirectedNumberInfo(Handler h)2443     public void unregisterForRedirectedNumberInfo(Handler h) {
2444         mCi.unregisterForRedirectedNumberInfo(h);
2445     }
2446 
2447     /**
2448      * Register for CDMA line control information record notification
2449      * from the network.
2450      * Message.obj will contain an AsyncResult.
2451      * AsyncResult.result will be a CdmaInformationRecords.CdmaLineControlInfoRec
2452      * instance.
2453      *
2454      * @param h Handler that receives the notification message.
2455      * @param what User-defined message code.
2456      * @param obj User object.
2457      */
registerForLineControlInfo(Handler h, int what, Object obj)2458     public void registerForLineControlInfo(Handler h, int what, Object obj) {
2459         mCi.registerForLineControlInfo(h, what, obj);
2460     }
2461 
2462     /**
2463      * Unregisters for line control information notifications.
2464      * Extraneous calls are tolerated silently
2465      *
2466      * @param h Handler to be removed from the registrant list.
2467      */
unregisterForLineControlInfo(Handler h)2468     public void unregisterForLineControlInfo(Handler h) {
2469         mCi.unregisterForLineControlInfo(h);
2470     }
2471 
2472     /**
2473      * Register for CDMA T53 CLIR information record notifications
2474      * from the network.
2475      * Message.obj will contain an AsyncResult.
2476      * AsyncResult.result will be a CdmaInformationRecords.CdmaT53ClirInfoRec
2477      * instance.
2478      *
2479      * @param h Handler that receives the notification message.
2480      * @param what User-defined message code.
2481      * @param obj User object.
2482      */
registerFoT53ClirlInfo(Handler h, int what, Object obj)2483     public void registerFoT53ClirlInfo(Handler h, int what, Object obj) {
2484         mCi.registerFoT53ClirlInfo(h, what, obj);
2485     }
2486 
2487     /**
2488      * Unregisters for T53 CLIR information record notification
2489      * Extraneous calls are tolerated silently
2490      *
2491      * @param h Handler to be removed from the registrant list.
2492      */
unregisterForT53ClirInfo(Handler h)2493     public void unregisterForT53ClirInfo(Handler h) {
2494         mCi.unregisterForT53ClirInfo(h);
2495     }
2496 
2497     /**
2498      * Register for CDMA T53 audio control information record notifications
2499      * from the network.
2500      * Message.obj will contain an AsyncResult.
2501      * AsyncResult.result will be a CdmaInformationRecords.CdmaT53AudioControlInfoRec
2502      * instance.
2503      *
2504      * @param h Handler that receives the notification message.
2505      * @param what User-defined message code.
2506      * @param obj User object.
2507      */
registerForT53AudioControlInfo(Handler h, int what, Object obj)2508     public void registerForT53AudioControlInfo(Handler h, int what, Object obj) {
2509         mCi.registerForT53AudioControlInfo(h, what, obj);
2510     }
2511 
2512     /**
2513      * Unregisters for T53 audio control information record notifications.
2514      * Extraneous calls are tolerated silently
2515      *
2516      * @param h Handler to be removed from the registrant list.
2517      */
unregisterForT53AudioControlInfo(Handler h)2518     public void unregisterForT53AudioControlInfo(Handler h) {
2519         mCi.unregisterForT53AudioControlInfo(h);
2520     }
2521 
2522     /**
2523      * registers for exit emergency call back mode request response
2524      *
2525      * @param h Handler that receives the notification message.
2526      * @param what User-defined message code.
2527      * @param obj User object.
2528      */
setOnEcbModeExitResponse(Handler h, int what, Object obj)2529     public void setOnEcbModeExitResponse(Handler h, int what, Object obj){
2530     }
2531 
2532     /**
2533      * Unregisters for exit emergency call back mode request response
2534      *
2535      * @param h Handler to be removed from the registrant list.
2536      */
unsetOnEcbModeExitResponse(Handler h)2537     public void unsetOnEcbModeExitResponse(Handler h){
2538     }
2539 
2540     /**
2541      * Register for radio off or not available
2542      *
2543      * @param h Handler that receives the notification message.
2544      * @param what User-defined message code.
2545      * @param obj User object.
2546      */
registerForRadioOffOrNotAvailable(Handler h, int what, Object obj)2547     public void registerForRadioOffOrNotAvailable(Handler h, int what, Object obj) {
2548         mRadioOffOrNotAvailableRegistrants.addUnique(h, what, obj);
2549     }
2550 
2551     /**
2552      * Unregisters for radio off or not available
2553      *
2554      * @param h Handler to be removed from the registrant list.
2555      */
unregisterForRadioOffOrNotAvailable(Handler h)2556     public void unregisterForRadioOffOrNotAvailable(Handler h) {
2557         mRadioOffOrNotAvailableRegistrants.remove(h);
2558     }
2559 
2560     /**
2561      * Returns an array of string identifiers for the APN types serviced by the
2562      * currently active.
2563      *  @return The string array will always return at least one entry, Phone.APN_TYPE_DEFAULT.
2564      * TODO: Revisit if we always should return at least one entry.
2565      */
getActiveApnTypes()2566     public String[] getActiveApnTypes() {
2567         if (mDcTracker == null) {
2568             return null;
2569         }
2570 
2571         return mDcTracker.getActiveApnTypes();
2572     }
2573 
2574     /**
2575      * Check if TETHER_DUN_APN setting or config_tether_apndata includes APN that matches
2576      * current operator.
2577      * @return true if there is a matching DUN APN.
2578      */
hasMatchedTetherApnSetting()2579     public boolean hasMatchedTetherApnSetting() {
2580         return mDcTracker.hasMatchedTetherApnSetting();
2581     }
2582 
2583     /**
2584      * Returns string for the active APN host.
2585      *  @return type as a string or null if none.
2586      */
getActiveApnHost(String apnType)2587     public String getActiveApnHost(String apnType) {
2588         return mDcTracker.getActiveApnString(apnType);
2589     }
2590 
2591     /**
2592      * Return the LinkProperties for the named apn or null if not available
2593      */
getLinkProperties(String apnType)2594     public LinkProperties getLinkProperties(String apnType) {
2595         return mDcTracker.getLinkProperties(apnType);
2596     }
2597 
2598     /**
2599      * Return the NetworkCapabilities
2600      */
getNetworkCapabilities(String apnType)2601     public NetworkCapabilities getNetworkCapabilities(String apnType) {
2602         return mDcTracker.getNetworkCapabilities(apnType);
2603     }
2604 
2605     /**
2606      * Report on whether data connectivity is allowed.
2607      */
isDataConnectivityPossible()2608     public boolean isDataConnectivityPossible() {
2609         return isDataConnectivityPossible(PhoneConstants.APN_TYPE_DEFAULT);
2610     }
2611 
2612     /**
2613      * Report on whether data connectivity is allowed for an APN.
2614      */
isDataConnectivityPossible(String apnType)2615     public boolean isDataConnectivityPossible(String apnType) {
2616         return ((mDcTracker != null) &&
2617                 (mDcTracker.isDataPossible(apnType)));
2618     }
2619 
2620     /**
2621      * Notify registrants of a new ringing Connection.
2622      * Subclasses of Phone probably want to replace this with a
2623      * version scoped to their packages
2624      */
notifyNewRingingConnectionP(Connection cn)2625     public void notifyNewRingingConnectionP(Connection cn) {
2626         if (!mIsVoiceCapable)
2627             return;
2628         AsyncResult ar = new AsyncResult(null, cn, null);
2629         mNewRingingConnectionRegistrants.notifyRegistrants(ar);
2630     }
2631 
2632     /**
2633      * Notify registrants of a new unknown connection.
2634      */
notifyUnknownConnectionP(Connection cn)2635     public void notifyUnknownConnectionP(Connection cn) {
2636         mUnknownConnectionRegistrants.notifyResult(cn);
2637     }
2638 
2639     /**
2640      * Notify registrants if phone is video capable.
2641      */
notifyForVideoCapabilityChanged(boolean isVideoCallCapable)2642     public void notifyForVideoCapabilityChanged(boolean isVideoCallCapable) {
2643         // Cache the current video capability so that we don't lose the information.
2644         mIsVideoCapable = isVideoCallCapable;
2645 
2646         AsyncResult ar = new AsyncResult(null, isVideoCallCapable, null);
2647         mVideoCapabilityChangedRegistrants.notifyRegistrants(ar);
2648     }
2649 
2650     /**
2651      * Notify registrants of a RING event.
2652      */
notifyIncomingRing()2653     private void notifyIncomingRing() {
2654         if (!mIsVoiceCapable)
2655             return;
2656         AsyncResult ar = new AsyncResult(null, this, null);
2657         mIncomingRingRegistrants.notifyRegistrants(ar);
2658     }
2659 
2660     /**
2661      * Send the incoming call Ring notification if conditions are right.
2662      */
sendIncomingCallRingNotification(int token)2663     private void sendIncomingCallRingNotification(int token) {
2664         if (mIsVoiceCapable && !mDoesRilSendMultipleCallRing &&
2665                 (token == mCallRingContinueToken)) {
2666             Rlog.d(LOG_TAG, "Sending notifyIncomingRing");
2667             notifyIncomingRing();
2668             sendMessageDelayed(
2669                     obtainMessage(EVENT_CALL_RING_CONTINUE, token, 0), mCallRingDelay);
2670         } else {
2671             Rlog.d(LOG_TAG, "Ignoring ring notification request,"
2672                     + " mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing
2673                     + " token=" + token
2674                     + " mCallRingContinueToken=" + mCallRingContinueToken
2675                     + " mIsVoiceCapable=" + mIsVoiceCapable);
2676         }
2677     }
2678 
2679     /**
2680      * TODO: Adding a function for each property is not good.
2681      * A fucntion of type getPhoneProp(propType) where propType is an
2682      * enum of GSM+CDMA+LTE props would be a better approach.
2683      *
2684      * Get "Restriction of menu options for manual PLMN selection" bit
2685      * status from EF_CSP data, this belongs to "Value Added Services Group".
2686      * @return true if this bit is set or EF_CSP data is unavailable,
2687      * false otherwise
2688      */
isCspPlmnEnabled()2689     public boolean isCspPlmnEnabled() {
2690         return false;
2691     }
2692 
2693     /**
2694      * Return an interface to retrieve the ISIM records for IMS, if available.
2695      * @return the interface to retrieve the ISIM records, or null if not supported
2696      */
getIsimRecords()2697     public IsimRecords getIsimRecords() {
2698         Rlog.e(LOG_TAG, "getIsimRecords() is only supported on LTE devices");
2699         return null;
2700     }
2701 
2702     /**
2703      * Retrieves the MSISDN from the UICC. For GSM/UMTS phones, this is equivalent to
2704      * {@link #getLine1Number()}. For CDMA phones, {@link #getLine1Number()} returns
2705      * the MDN, so this method is provided to return the MSISDN on CDMA/LTE phones.
2706      */
getMsisdn()2707     public String getMsisdn() {
2708         return null;
2709     }
2710 
2711     /**
2712      * Get the current for the default apn DataState. No change notification
2713      * exists at this interface -- use
2714      * {@link android.telephony.PhoneStateListener} instead.
2715      */
getDataConnectionState()2716     public PhoneConstants.DataState getDataConnectionState() {
2717         return getDataConnectionState(PhoneConstants.APN_TYPE_DEFAULT);
2718     }
2719 
notifyCallForwardingIndicator()2720     public void notifyCallForwardingIndicator() {
2721     }
2722 
notifyDataConnectionFailed(String reason, String apnType)2723     public void notifyDataConnectionFailed(String reason, String apnType) {
2724         mNotifier.notifyDataConnectionFailed(this, reason, apnType);
2725     }
2726 
notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, String failCause)2727     public void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn,
2728             String failCause) {
2729         mNotifier.notifyPreciseDataConnectionFailed(this, reason, apnType, apn, failCause);
2730     }
2731 
2732     /**
2733      * Return if the current radio is LTE on CDMA. This
2734      * is a tri-state return value as for a period of time
2735      * the mode may be unknown.
2736      *
2737      * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
2738      * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
2739      */
getLteOnCdmaMode()2740     public int getLteOnCdmaMode() {
2741         return mCi.getLteOnCdmaMode();
2742     }
2743 
2744     /**
2745      * Sets the SIM voice message waiting indicator records.
2746      * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported
2747      * @param countWaiting The number of messages waiting, if known. Use
2748      *                     -1 to indicate that an unknown number of
2749      *                      messages are waiting
2750      */
setVoiceMessageWaiting(int line, int countWaiting)2751     public void setVoiceMessageWaiting(int line, int countWaiting) {
2752         // This function should be overridden by class GsmCdmaPhone.
2753         Rlog.e(LOG_TAG, "Error! This function should never be executed, inactive Phone.");
2754     }
2755 
2756     /**
2757      * Gets the USIM service table from the UICC, if present and available.
2758      * @return an interface to the UsimServiceTable record, or null if not available
2759      */
getUsimServiceTable()2760     public UsimServiceTable getUsimServiceTable() {
2761         IccRecords r = mIccRecords.get();
2762         return (r != null) ? r.getUsimServiceTable() : null;
2763     }
2764 
2765     /**
2766      * Gets the Uicc card corresponding to this phone.
2767      * @return the UiccCard object corresponding to the phone ID.
2768      */
getUiccCard()2769     public UiccCard getUiccCard() {
2770         return mUiccController.getUiccCard(mPhoneId);
2771     }
2772 
2773     /**
2774      * Get P-CSCF address from PCO after data connection is established or modified.
2775      * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
2776      */
getPcscfAddress(String apnType)2777     public String[] getPcscfAddress(String apnType) {
2778         return mDcTracker.getPcscfAddress(apnType);
2779     }
2780 
2781     /**
2782      * Set IMS registration state
2783      */
setImsRegistrationState(boolean registered)2784     public void setImsRegistrationState(boolean registered) {
2785     }
2786 
2787     /**
2788      * Return an instance of a IMS phone
2789      */
getImsPhone()2790     public Phone getImsPhone() {
2791         return mImsPhone;
2792     }
2793 
2794     /**
2795      * Return if UT capability of ImsPhone is enabled or not
2796      */
isUtEnabled()2797     public boolean isUtEnabled() {
2798         return false;
2799     }
2800 
dispose()2801     public void dispose() {
2802     }
2803 
updateImsPhone()2804     private void updateImsPhone() {
2805         Rlog.d(LOG_TAG, "updateImsPhone"
2806                 + " mImsServiceReady=" + mImsServiceReady);
2807 
2808         if (mImsServiceReady && (mImsPhone == null)) {
2809             mImsPhone = PhoneFactory.makeImsPhone(mNotifier, this);
2810             CallManager.getInstance().registerPhone(mImsPhone);
2811             mImsPhone.registerForSilentRedial(
2812                     this, EVENT_INITIATE_SILENT_REDIAL, null);
2813         } else if (!mImsServiceReady && (mImsPhone != null)) {
2814             CallManager.getInstance().unregisterPhone(mImsPhone);
2815             mImsPhone.unregisterForSilentRedial(this);
2816 
2817             mImsPhone.dispose();
2818             // Potential GC issue if someone keeps a reference to ImsPhone.
2819             // However: this change will make sure that such a reference does
2820             // not access functions through NULL pointer.
2821             //mImsPhone.removeReferences();
2822             mImsPhone = null;
2823         }
2824     }
2825 
2826     /**
2827      * Dials a number.
2828      *
2829      * @param dialString The number to dial.
2830      * @param uusInfo The UUSInfo.
2831      * @param videoState The video state for the call.
2832      * @param intentExtras Extras from the original CALL intent.
2833      * @return The Connection.
2834      * @throws CallStateException
2835      */
dialInternal( String dialString, UUSInfo uusInfo, int videoState, Bundle intentExtras)2836     protected Connection dialInternal(
2837             String dialString, UUSInfo uusInfo, int videoState, Bundle intentExtras)
2838             throws CallStateException {
2839         // dialInternal shall be overriden by GsmCdmaPhone
2840         return null;
2841     }
2842 
2843     /*
2844      * Returns the subscription id.
2845      */
getSubId()2846     public int getSubId() {
2847         return SubscriptionController.getInstance().getSubIdUsingPhoneId(mPhoneId);
2848     }
2849 
2850     /**
2851      * Returns the phone id.
2852      */
getPhoneId()2853     public int getPhoneId() {
2854         return mPhoneId;
2855     }
2856 
2857     /**
2858      * Return the service state of mImsPhone if it is STATE_IN_SERVICE
2859      * otherwise return the current voice service state
2860      */
getVoicePhoneServiceState()2861     public int getVoicePhoneServiceState() {
2862         Phone imsPhone = mImsPhone;
2863         if (imsPhone != null
2864                 && imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) {
2865             return ServiceState.STATE_IN_SERVICE;
2866         }
2867         return getServiceState().getState();
2868     }
2869 
2870     /**
2871      * Override the service provider name and the operator name for the current ICCID.
2872      */
setOperatorBrandOverride(String brand)2873     public boolean setOperatorBrandOverride(String brand) {
2874         return false;
2875     }
2876 
2877     /**
2878      * Override the roaming indicator for the current ICCID.
2879      */
setRoamingOverride(List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList)2880     public boolean setRoamingOverride(List<String> gsmRoamingList,
2881             List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
2882             List<String> cdmaNonRoamingList) {
2883         String iccId = getIccSerialNumber();
2884         if (TextUtils.isEmpty(iccId)) {
2885             return false;
2886         }
2887 
2888         setRoamingOverrideHelper(gsmRoamingList, GSM_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
2889         setRoamingOverrideHelper(gsmNonRoamingList, GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
2890         setRoamingOverrideHelper(cdmaRoamingList, CDMA_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
2891         setRoamingOverrideHelper(cdmaNonRoamingList, CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX, iccId);
2892 
2893         // Refresh.
2894         ServiceStateTracker tracker = getServiceStateTracker();
2895         if (tracker != null) {
2896             tracker.pollState();
2897         }
2898         return true;
2899     }
2900 
setRoamingOverrideHelper(List<String> list, String prefix, String iccId)2901     private void setRoamingOverrideHelper(List<String> list, String prefix, String iccId) {
2902         SharedPreferences.Editor spEditor =
2903                 PreferenceManager.getDefaultSharedPreferences(mContext).edit();
2904         String key = prefix + iccId;
2905         if (list == null || list.isEmpty()) {
2906             spEditor.remove(key).commit();
2907         } else {
2908             spEditor.putStringSet(key, new HashSet<String>(list)).commit();
2909         }
2910     }
2911 
isMccMncMarkedAsRoaming(String mccMnc)2912     public boolean isMccMncMarkedAsRoaming(String mccMnc) {
2913         return getRoamingOverrideHelper(GSM_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc);
2914     }
2915 
isMccMncMarkedAsNonRoaming(String mccMnc)2916     public boolean isMccMncMarkedAsNonRoaming(String mccMnc) {
2917         return getRoamingOverrideHelper(GSM_NON_ROAMING_LIST_OVERRIDE_PREFIX, mccMnc);
2918     }
2919 
isSidMarkedAsRoaming(int SID)2920     public boolean isSidMarkedAsRoaming(int SID) {
2921         return getRoamingOverrideHelper(CDMA_ROAMING_LIST_OVERRIDE_PREFIX,
2922                 Integer.toString(SID));
2923     }
2924 
isSidMarkedAsNonRoaming(int SID)2925     public boolean isSidMarkedAsNonRoaming(int SID) {
2926         return getRoamingOverrideHelper(CDMA_NON_ROAMING_LIST_OVERRIDE_PREFIX,
2927                 Integer.toString(SID));
2928     }
2929 
2930     /**
2931      * Query the IMS Registration Status.
2932      *
2933      * @return true if IMS is Registered
2934      */
isImsRegistered()2935     public boolean isImsRegistered() {
2936         Phone imsPhone = mImsPhone;
2937         boolean isImsRegistered = false;
2938         if (imsPhone != null) {
2939             isImsRegistered = imsPhone.isImsRegistered();
2940         } else {
2941             ServiceStateTracker sst = getServiceStateTracker();
2942             if (sst != null) {
2943                 isImsRegistered = sst.isImsRegistered();
2944             }
2945         }
2946         Rlog.d(LOG_TAG, "isImsRegistered =" + isImsRegistered);
2947         return isImsRegistered;
2948     }
2949 
2950     /**
2951      * Get Wifi Calling Feature Availability
2952      */
isWifiCallingEnabled()2953     public boolean isWifiCallingEnabled() {
2954         Phone imsPhone = mImsPhone;
2955         boolean isWifiCallingEnabled = false;
2956         if (imsPhone != null) {
2957             isWifiCallingEnabled = imsPhone.isWifiCallingEnabled();
2958         }
2959         Rlog.d(LOG_TAG, "isWifiCallingEnabled =" + isWifiCallingEnabled);
2960         return isWifiCallingEnabled;
2961     }
2962 
2963     /**
2964      * Get Volte Feature Availability
2965      */
isVolteEnabled()2966     public boolean isVolteEnabled() {
2967         Phone imsPhone = mImsPhone;
2968         boolean isVolteEnabled = false;
2969         if (imsPhone != null) {
2970             isVolteEnabled = imsPhone.isVolteEnabled();
2971         }
2972         Rlog.d(LOG_TAG, "isImsRegistered =" + isVolteEnabled);
2973         return isVolteEnabled;
2974     }
2975 
getRoamingOverrideHelper(String prefix, String key)2976     private boolean getRoamingOverrideHelper(String prefix, String key) {
2977         String iccId = getIccSerialNumber();
2978         if (TextUtils.isEmpty(iccId) || TextUtils.isEmpty(key)) {
2979             return false;
2980         }
2981 
2982         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
2983         Set<String> value = sp.getStringSet(prefix + iccId, null);
2984         if (value == null) {
2985             return false;
2986         }
2987         return value.contains(key);
2988     }
2989 
2990     /**
2991      * Is Radio Present on the device and is it accessible
2992      */
isRadioAvailable()2993     public boolean isRadioAvailable() {
2994         return mCi.getRadioState().isAvailable();
2995     }
2996 
2997     /**
2998      * Is Radio turned on
2999      */
isRadioOn()3000     public boolean isRadioOn() {
3001         return mCi.getRadioState().isOn();
3002     }
3003 
3004     /**
3005      * shutdown Radio gracefully
3006      */
shutdownRadio()3007     public void shutdownRadio() {
3008         getServiceStateTracker().requestShutdown();
3009     }
3010 
3011     /**
3012      * Return true if the device is shutting down.
3013      */
isShuttingDown()3014     public boolean isShuttingDown() {
3015         return getServiceStateTracker().isDeviceShuttingDown();
3016     }
3017 
3018     /**
3019      *  Set phone radio capability
3020      *
3021      *  @param rc the phone radio capability defined in
3022      *         RadioCapability. It's a input object used to transfer parameter to logic modem
3023      *  @param response Callback message.
3024      */
setRadioCapability(RadioCapability rc, Message response)3025     public void setRadioCapability(RadioCapability rc, Message response) {
3026         mCi.setRadioCapability(rc, response);
3027     }
3028 
3029     /**
3030      *  Get phone radio access family
3031      *
3032      *  @return a bit mask to identify the radio access family.
3033      */
getRadioAccessFamily()3034     public int getRadioAccessFamily() {
3035         final RadioCapability rc = getRadioCapability();
3036         return (rc == null ? RadioAccessFamily.RAF_UNKNOWN : rc.getRadioAccessFamily());
3037     }
3038 
3039     /**
3040      *  Get the associated data modems Id.
3041      *
3042      *  @return a String containing the id of the data modem
3043      */
getModemUuId()3044     public String getModemUuId() {
3045         final RadioCapability rc = getRadioCapability();
3046         return (rc == null ? "" : rc.getLogicalModemUuid());
3047     }
3048 
3049     /**
3050      *  Get phone radio capability
3051      *
3052      *  @return the capability of the radio defined in RadioCapability
3053      */
getRadioCapability()3054     public RadioCapability getRadioCapability() {
3055         return mRadioCapability.get();
3056     }
3057 
3058     /**
3059      *  The RadioCapability has changed. This comes up from the RIL and is called when radios first
3060      *  become available or after a capability switch.  The flow is we use setRadioCapability to
3061      *  request a change with the RIL and get an UNSOL response with the new data which gets set
3062      *  here.
3063      *
3064      *  @param rc the phone radio capability currently in effect for this phone.
3065      */
radioCapabilityUpdated(RadioCapability rc)3066     public void radioCapabilityUpdated(RadioCapability rc) {
3067         // Called when radios first become available or after a capability switch
3068         // Update the cached value
3069         mRadioCapability.set(rc);
3070 
3071         if (SubscriptionManager.isValidSubscriptionId(getSubId())) {
3072             sendSubscriptionSettings(true);
3073         }
3074     }
3075 
sendSubscriptionSettings(boolean restoreNetworkSelection)3076     public void sendSubscriptionSettings(boolean restoreNetworkSelection) {
3077         // Send settings down
3078         int type = PhoneFactory.calculatePreferredNetworkType(mContext, getSubId());
3079         setPreferredNetworkType(type, null);
3080 
3081         if (restoreNetworkSelection) {
3082             restoreSavedNetworkSelection(null);
3083         }
3084     }
3085 
setPreferredNetworkTypeIfSimLoaded()3086     protected void setPreferredNetworkTypeIfSimLoaded() {
3087         int subId = getSubId();
3088         if (SubscriptionManager.isValidSubscriptionId(subId)) {
3089             int type = PhoneFactory.calculatePreferredNetworkType(mContext, getSubId());
3090             setPreferredNetworkType(type, null);
3091         }
3092     }
3093 
3094     /**
3095      * Registers the handler when phone radio  capability is changed.
3096      *
3097      * @param h Handler for notification message.
3098      * @param what User-defined message code.
3099      * @param obj User object.
3100      */
registerForRadioCapabilityChanged(Handler h, int what, Object obj)3101     public void registerForRadioCapabilityChanged(Handler h, int what, Object obj) {
3102         mCi.registerForRadioCapabilityChanged(h, what, obj);
3103     }
3104 
3105     /**
3106      * Unregister for notifications when phone radio type and access technology is changed.
3107      *
3108      * @param h Handler to be removed from the registrant list.
3109      */
unregisterForRadioCapabilityChanged(Handler h)3110     public void unregisterForRadioCapabilityChanged(Handler h) {
3111         mCi.unregisterForRadioCapabilityChanged(this);
3112     }
3113 
3114     /**
3115      * Determines if  IMS is enabled for call.
3116      *
3117      * @return {@code true} if IMS calling is enabled.
3118      */
isImsUseEnabled()3119     public boolean isImsUseEnabled() {
3120         boolean imsUseEnabled =
3121                 ((ImsManager.isVolteEnabledByPlatform(mContext) &&
3122                 ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mContext)) ||
3123                 (ImsManager.isWfcEnabledByPlatform(mContext) &&
3124                 ImsManager.isWfcEnabledByUser(mContext)) &&
3125                 ImsManager.isNonTtyOrTtyOnVolteEnabled(mContext));
3126         return imsUseEnabled;
3127     }
3128 
3129     /**
3130      * Determines if video calling is enabled for the phone.
3131      *
3132      * @return {@code true} if video calling is enabled, {@code false} otherwise.
3133      */
isVideoEnabled()3134     public boolean isVideoEnabled() {
3135         Phone imsPhone = mImsPhone;
3136         if ((imsPhone != null)
3137                 && (imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)) {
3138             return imsPhone.isVideoEnabled();
3139         }
3140         return false;
3141     }
3142 
3143     /**
3144      * Returns the status of Link Capacity Estimation (LCE) service.
3145      */
getLceStatus()3146     public int getLceStatus() {
3147         return mLceStatus;
3148     }
3149 
3150     /**
3151      * Returns the modem activity information
3152      */
getModemActivityInfo(Message response)3153     public void getModemActivityInfo(Message response)  {
3154         mCi.getModemActivityInfo(response);
3155     }
3156 
3157     /**
3158      * Starts LCE service after radio becomes available.
3159      * LCE service state may get destroyed on the modem when radio becomes unavailable.
3160      */
startLceAfterRadioIsAvailable()3161     public void startLceAfterRadioIsAvailable() {
3162         mCi.startLceService(DEFAULT_REPORT_INTERVAL_MS, LCE_PULL_MODE,
3163                 obtainMessage(EVENT_CONFIG_LCE));
3164     }
3165 
3166     /**
3167      * Returns the locale based on the carrier properties (such as {@code ro.carrier}) and
3168      * SIM preferences.
3169      */
getLocaleFromSimAndCarrierPrefs()3170     public Locale getLocaleFromSimAndCarrierPrefs() {
3171         final IccRecords records = mIccRecords.get();
3172         if (records != null && records.getSimLanguage() != null) {
3173             return new Locale(records.getSimLanguage());
3174         }
3175 
3176         return getLocaleFromCarrierProperties(mContext);
3177     }
3178 
updateDataConnectionTracker()3179     public void updateDataConnectionTracker() {
3180         mDcTracker.update();
3181     }
3182 
setInternalDataEnabled(boolean enable, Message onCompleteMsg)3183     public void setInternalDataEnabled(boolean enable, Message onCompleteMsg) {
3184         mDcTracker.setInternalDataEnabled(enable, onCompleteMsg);
3185     }
3186 
updateCurrentCarrierInProvider()3187     public boolean updateCurrentCarrierInProvider() {
3188         return false;
3189     }
3190 
registerForAllDataDisconnected(Handler h, int what, Object obj)3191     public void registerForAllDataDisconnected(Handler h, int what, Object obj) {
3192         mDcTracker.registerForAllDataDisconnected(h, what, obj);
3193     }
3194 
unregisterForAllDataDisconnected(Handler h)3195     public void unregisterForAllDataDisconnected(Handler h) {
3196         mDcTracker.unregisterForAllDataDisconnected(h);
3197     }
3198 
getIccSmsInterfaceManager()3199     public IccSmsInterfaceManager getIccSmsInterfaceManager(){
3200         return null;
3201     }
3202 
isMatchGid(String gid)3203     protected boolean isMatchGid(String gid) {
3204         String gid1 = getGroupIdLevel1();
3205         int gidLength = gid.length();
3206         if (!TextUtils.isEmpty(gid1) && (gid1.length() >= gidLength)
3207                 && gid1.substring(0, gidLength).equalsIgnoreCase(gid)) {
3208             return true;
3209         }
3210         return false;
3211     }
3212 
checkWfcWifiOnlyModeBeforeDial(Phone imsPhone, Context context)3213     public static void checkWfcWifiOnlyModeBeforeDial(Phone imsPhone, Context context)
3214             throws CallStateException {
3215         if (imsPhone == null || !imsPhone.isWifiCallingEnabled()) {
3216             boolean wfcWiFiOnly = (ImsManager.isWfcEnabledByPlatform(context) &&
3217                     ImsManager.isWfcEnabledByUser(context) &&
3218                     (ImsManager.getWfcMode(context) ==
3219                             ImsConfig.WfcModeFeatureValueConstants.WIFI_ONLY));
3220             if (wfcWiFiOnly) {
3221                 throw new CallStateException(
3222                         CallStateException.ERROR_DISCONNECTED,
3223                         "WFC Wi-Fi Only Mode: IMS not registered");
3224             }
3225         }
3226     }
3227 
startRingbackTone()3228     public void startRingbackTone() {
3229     }
3230 
stopRingbackTone()3231     public void stopRingbackTone() {
3232     }
3233 
callEndCleanupHandOverCallIfAny()3234     public void callEndCleanupHandOverCallIfAny() {
3235     }
3236 
cancelUSSD()3237     public void cancelUSSD() {
3238     }
3239 
3240     /**
3241      * Set boolean broadcastEmergencyCallStateChanges
3242      */
setBroadcastEmergencyCallStateChanges(boolean broadcast)3243     public abstract void setBroadcastEmergencyCallStateChanges(boolean broadcast);
3244 
sendEmergencyCallStateChange(boolean callActive)3245     public abstract void sendEmergencyCallStateChange(boolean callActive);
3246 
3247     /**
3248      * This function returns the parent phone of the current phone. It is applicable
3249      * only for IMS phone (function is overridden by ImsPhone). For others the phone
3250      * object itself is returned.
3251      * @return
3252      */
getDefaultPhone()3253     public Phone getDefaultPhone() {
3254         return this;
3255     }
3256 
dump(FileDescriptor fd, PrintWriter pw, String[] args)3257     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
3258         pw.println("Phone: subId=" + getSubId());
3259         pw.println(" mPhoneId=" + mPhoneId);
3260         pw.println(" mCi=" + mCi);
3261         pw.println(" mDnsCheckDisabled=" + mDnsCheckDisabled);
3262         pw.println(" mDcTracker=" + mDcTracker);
3263         pw.println(" mDoesRilSendMultipleCallRing=" + mDoesRilSendMultipleCallRing);
3264         pw.println(" mCallRingContinueToken=" + mCallRingContinueToken);
3265         pw.println(" mCallRingDelay=" + mCallRingDelay);
3266         pw.println(" mIsVoiceCapable=" + mIsVoiceCapable);
3267         pw.println(" mIccRecords=" + mIccRecords.get());
3268         pw.println(" mUiccApplication=" + mUiccApplication.get());
3269         pw.println(" mSmsStorageMonitor=" + mSmsStorageMonitor);
3270         pw.println(" mSmsUsageMonitor=" + mSmsUsageMonitor);
3271         pw.flush();
3272         pw.println(" mLooper=" + mLooper);
3273         pw.println(" mContext=" + mContext);
3274         pw.println(" mNotifier=" + mNotifier);
3275         pw.println(" mSimulatedRadioControl=" + mSimulatedRadioControl);
3276         pw.println(" mUnitTestMode=" + mUnitTestMode);
3277         pw.println(" isDnsCheckDisabled()=" + isDnsCheckDisabled());
3278         pw.println(" getUnitTestMode()=" + getUnitTestMode());
3279         pw.println(" getState()=" + getState());
3280         pw.println(" getIccSerialNumber()=" + getIccSerialNumber());
3281         pw.println(" getIccRecordsLoaded()=" + getIccRecordsLoaded());
3282         pw.println(" getMessageWaitingIndicator()=" + getMessageWaitingIndicator());
3283         pw.println(" getCallForwardingIndicator()=" + getCallForwardingIndicator());
3284         pw.println(" isInEmergencyCall()=" + isInEmergencyCall());
3285         pw.flush();
3286         pw.println(" isInEcm()=" + isInEcm());
3287         pw.println(" getPhoneName()=" + getPhoneName());
3288         pw.println(" getPhoneType()=" + getPhoneType());
3289         pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount());
3290         pw.println(" getActiveApnTypes()=" + getActiveApnTypes());
3291         pw.println(" isDataConnectivityPossible()=" + isDataConnectivityPossible());
3292         pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning());
3293         pw.flush();
3294         pw.println("++++++++++++++++++++++++++++++++");
3295 
3296         if (mImsPhone != null) {
3297             try {
3298                 mImsPhone.dump(fd, pw, args);
3299             } catch (Exception e) {
3300                 e.printStackTrace();
3301             }
3302 
3303             pw.flush();
3304             pw.println("++++++++++++++++++++++++++++++++");
3305         }
3306 
3307         if (mDcTracker != null) {
3308             try {
3309                 mDcTracker.dump(fd, pw, args);
3310             } catch (Exception e) {
3311                 e.printStackTrace();
3312             }
3313 
3314             pw.flush();
3315             pw.println("++++++++++++++++++++++++++++++++");
3316         }
3317 
3318         if (getServiceStateTracker() != null) {
3319             try {
3320                 getServiceStateTracker().dump(fd, pw, args);
3321             } catch (Exception e) {
3322                 e.printStackTrace();
3323             }
3324 
3325             pw.flush();
3326             pw.println("++++++++++++++++++++++++++++++++");
3327         }
3328 
3329         if (getCallTracker() != null) {
3330             try {
3331                 getCallTracker().dump(fd, pw, args);
3332             } catch (Exception e) {
3333                 e.printStackTrace();
3334             }
3335 
3336             pw.flush();
3337             pw.println("++++++++++++++++++++++++++++++++");
3338         }
3339 
3340         if (mCi != null && mCi instanceof RIL) {
3341             try {
3342                 ((RIL)mCi).dump(fd, pw, args);
3343             } catch (Exception e) {
3344                 e.printStackTrace();
3345             }
3346 
3347             pw.flush();
3348             pw.println("++++++++++++++++++++++++++++++++");
3349         }
3350     }
3351 }
3352