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