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