1 /*
2  * Copyright (C) 2006 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.phone;
18 
19 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20 
21 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_IMS;
22 import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
23 
24 import android.Manifest.permission;
25 import android.annotation.NonNull;
26 import android.annotation.Nullable;
27 import android.app.AppOpsManager;
28 import android.app.PendingIntent;
29 import android.content.ComponentName;
30 import android.content.ContentResolver;
31 import android.content.Context;
32 import android.content.Intent;
33 import android.content.SharedPreferences;
34 import android.content.pm.ApplicationInfo;
35 import android.content.pm.ComponentInfo;
36 import android.content.pm.PackageInfo;
37 import android.content.pm.PackageManager;
38 import android.net.Uri;
39 import android.os.AsyncResult;
40 import android.os.Binder;
41 import android.os.Build;
42 import android.os.Bundle;
43 import android.os.Handler;
44 import android.os.IBinder;
45 import android.os.Looper;
46 import android.os.Message;
47 import android.os.Messenger;
48 import android.os.ParcelFileDescriptor;
49 import android.os.ParcelUuid;
50 import android.os.PersistableBundle;
51 import android.os.Process;
52 import android.os.RemoteException;
53 import android.os.ResultReceiver;
54 import android.os.ServiceSpecificException;
55 import android.os.UserHandle;
56 import android.os.UserManager;
57 import android.os.WorkSource;
58 import android.preference.PreferenceManager;
59 import android.provider.DeviceConfig;
60 import android.provider.Settings;
61 import android.provider.Telephony;
62 import android.sysprop.TelephonyProperties;
63 import android.telecom.PhoneAccount;
64 import android.telecom.PhoneAccountHandle;
65 import android.telecom.TelecomManager;
66 import android.telephony.Annotation.ApnType;
67 import android.telephony.CallForwardingInfo;
68 import android.telephony.CarrierConfigManager;
69 import android.telephony.CarrierRestrictionRules;
70 import android.telephony.CellIdentity;
71 import android.telephony.CellIdentityCdma;
72 import android.telephony.CellIdentityGsm;
73 import android.telephony.CellInfo;
74 import android.telephony.CellInfoGsm;
75 import android.telephony.CellInfoWcdma;
76 import android.telephony.ClientRequestStats;
77 import android.telephony.ICellInfoCallback;
78 import android.telephony.IccOpenLogicalChannelResponse;
79 import android.telephony.LocationAccessPolicy;
80 import android.telephony.ModemActivityInfo;
81 import android.telephony.NeighboringCellInfo;
82 import android.telephony.NetworkScanRequest;
83 import android.telephony.PhoneCapability;
84 import android.telephony.PhoneNumberRange;
85 import android.telephony.RadioAccessFamily;
86 import android.telephony.RadioAccessSpecifier;
87 import android.telephony.ServiceState;
88 import android.telephony.SignalStrength;
89 import android.telephony.SubscriptionInfo;
90 import android.telephony.SubscriptionManager;
91 import android.telephony.TelephonyFrameworkInitializer;
92 import android.telephony.TelephonyHistogram;
93 import android.telephony.TelephonyManager;
94 import android.telephony.TelephonyScanManager;
95 import android.telephony.UiccCardInfo;
96 import android.telephony.UiccSlotInfo;
97 import android.telephony.UssdResponse;
98 import android.telephony.VisualVoicemailSmsFilterSettings;
99 import android.telephony.data.ApnSetting;
100 import android.telephony.emergency.EmergencyNumber;
101 import android.telephony.ims.ImsException;
102 import android.telephony.ims.ProvisioningManager;
103 import android.telephony.ims.RegistrationManager;
104 import android.telephony.ims.aidl.IImsCapabilityCallback;
105 import android.telephony.ims.aidl.IImsConfig;
106 import android.telephony.ims.aidl.IImsConfigCallback;
107 import android.telephony.ims.aidl.IImsMmTelFeature;
108 import android.telephony.ims.aidl.IImsRcsFeature;
109 import android.telephony.ims.aidl.IImsRegistration;
110 import android.telephony.ims.aidl.IImsRegistrationCallback;
111 import android.telephony.ims.feature.ImsFeature;
112 import android.telephony.ims.feature.MmTelFeature;
113 import android.telephony.ims.feature.RcsFeature;
114 import android.telephony.ims.stub.ImsConfigImplBase;
115 import android.telephony.ims.stub.ImsRegistrationImplBase;
116 import android.text.TextUtils;
117 import android.util.ArraySet;
118 import android.util.EventLog;
119 import android.util.Log;
120 import android.util.Pair;
121 
122 import com.android.ims.ImsManager;
123 import com.android.ims.internal.IImsServiceFeatureCallback;
124 import com.android.internal.telephony.CallForwardInfo;
125 import com.android.internal.telephony.CallManager;
126 import com.android.internal.telephony.CallStateException;
127 import com.android.internal.telephony.CarrierInfoManager;
128 import com.android.internal.telephony.CarrierResolver;
129 import com.android.internal.telephony.CellNetworkScanResult;
130 import com.android.internal.telephony.CommandException;
131 import com.android.internal.telephony.CommandsInterface;
132 import com.android.internal.telephony.DefaultPhoneNotifier;
133 import com.android.internal.telephony.HalVersion;
134 import com.android.internal.telephony.IBooleanConsumer;
135 import com.android.internal.telephony.IIntegerConsumer;
136 import com.android.internal.telephony.INumberVerificationCallback;
137 import com.android.internal.telephony.ITelephony;
138 import com.android.internal.telephony.IccCard;
139 import com.android.internal.telephony.LocaleTracker;
140 import com.android.internal.telephony.NetworkScanRequestTracker;
141 import com.android.internal.telephony.OperatorInfo;
142 import com.android.internal.telephony.Phone;
143 import com.android.internal.telephony.PhoneConfigurationManager;
144 import com.android.internal.telephony.PhoneConstantConversions;
145 import com.android.internal.telephony.PhoneConstants;
146 import com.android.internal.telephony.PhoneFactory;
147 import com.android.internal.telephony.ProxyController;
148 import com.android.internal.telephony.RIL;
149 import com.android.internal.telephony.RILConstants;
150 import com.android.internal.telephony.ServiceStateTracker;
151 import com.android.internal.telephony.SmsController;
152 import com.android.internal.telephony.SmsPermissions;
153 import com.android.internal.telephony.SubscriptionController;
154 import com.android.internal.telephony.TelephonyIntents;
155 import com.android.internal.telephony.TelephonyPermissions;
156 import com.android.internal.telephony.dataconnection.ApnSettingUtils;
157 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
158 import com.android.internal.telephony.euicc.EuiccConnector;
159 import com.android.internal.telephony.ims.ImsResolver;
160 import com.android.internal.telephony.imsphone.ImsPhone;
161 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
162 import com.android.internal.telephony.metrics.TelephonyMetrics;
163 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
164 import com.android.internal.telephony.uicc.IccIoResult;
165 import com.android.internal.telephony.uicc.IccRecords;
166 import com.android.internal.telephony.uicc.IccUtils;
167 import com.android.internal.telephony.uicc.SIMRecords;
168 import com.android.internal.telephony.uicc.UiccCard;
169 import com.android.internal.telephony.uicc.UiccCardApplication;
170 import com.android.internal.telephony.uicc.UiccController;
171 import com.android.internal.telephony.uicc.UiccProfile;
172 import com.android.internal.telephony.uicc.UiccSlot;
173 import com.android.internal.telephony.util.LocaleUtils;
174 import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
175 import com.android.internal.util.HexDump;
176 import com.android.phone.settings.PickSmsSubscriptionActivity;
177 import com.android.phone.vvm.PhoneAccountHandleConverter;
178 import com.android.phone.vvm.RemoteVvmTaskManager;
179 import com.android.phone.vvm.VisualVoicemailSettingsUtil;
180 import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
181 import com.android.telephony.Rlog;
182 
183 import java.io.FileDescriptor;
184 import java.io.PrintWriter;
185 import java.util.ArrayList;
186 import java.util.Arrays;
187 import java.util.HashMap;
188 import java.util.HashSet;
189 import java.util.List;
190 import java.util.Locale;
191 import java.util.Map;
192 import java.util.NoSuchElementException;
193 import java.util.Set;
194 import java.util.concurrent.atomic.AtomicBoolean;
195 import java.util.function.Consumer;
196 
197 /**
198  * Implementation of the ITelephony interface.
199  */
200 public class PhoneInterfaceManager extends ITelephony.Stub {
201     private static final String LOG_TAG = "PhoneInterfaceManager";
202     private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
203     private static final boolean DBG_LOC = false;
204     private static final boolean DBG_MERGE = false;
205 
206     // Message codes used with mMainThreadHandler
207     private static final int CMD_HANDLE_PIN_MMI = 1;
208     private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
209     private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
210     private static final int CMD_OPEN_CHANNEL = 9;
211     private static final int EVENT_OPEN_CHANNEL_DONE = 10;
212     private static final int CMD_CLOSE_CHANNEL = 11;
213     private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
214     private static final int CMD_NV_READ_ITEM = 13;
215     private static final int EVENT_NV_READ_ITEM_DONE = 14;
216     private static final int CMD_NV_WRITE_ITEM = 15;
217     private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
218     private static final int CMD_NV_WRITE_CDMA_PRL = 17;
219     private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
220     private static final int CMD_RESET_MODEM_CONFIG = 19;
221     private static final int EVENT_RESET_MODEM_CONFIG_DONE = 20;
222     private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21;
223     private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22;
224     private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23;
225     private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24;
226     private static final int CMD_SEND_ENVELOPE = 25;
227     private static final int EVENT_SEND_ENVELOPE_DONE = 26;
228     private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
229     private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
230     private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
231     private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
232     private static final int CMD_EXCHANGE_SIM_IO = 31;
233     private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
234     private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
235     private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
236     private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
237     private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
238     private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
239     private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
240     private static final int CMD_PERFORM_NETWORK_SCAN = 39;
241     private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
242     private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
243     private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
244     private static final int CMD_SET_ALLOWED_CARRIERS = 43;
245     private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
246     private static final int CMD_GET_ALLOWED_CARRIERS = 45;
247     private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
248     private static final int CMD_HANDLE_USSD_REQUEST = 47;
249     private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
250     private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
251     private static final int CMD_SWITCH_SLOTS = 50;
252     private static final int EVENT_SWITCH_SLOTS_DONE = 51;
253     private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
254     private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
255     private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
256     private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
257     private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
258     private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
259     private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
260     private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
261     private static final int CMD_GET_ALL_CELL_INFO = 60;
262     private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
263     private static final int CMD_GET_CELL_LOCATION = 62;
264     private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
265     private static final int CMD_MODEM_REBOOT = 64;
266     private static final int EVENT_CMD_MODEM_REBOOT_DONE = 65;
267     private static final int CMD_REQUEST_CELL_INFO_UPDATE = 66;
268     private static final int EVENT_REQUEST_CELL_INFO_UPDATE_DONE = 67;
269     private static final int CMD_REQUEST_ENABLE_MODEM = 68;
270     private static final int EVENT_ENABLE_MODEM_DONE = 69;
271     private static final int CMD_GET_MODEM_STATUS = 70;
272     private static final int EVENT_GET_MODEM_STATUS_DONE = 71;
273     private static final int CMD_SET_FORBIDDEN_PLMNS = 72;
274     private static final int EVENT_SET_FORBIDDEN_PLMNS_DONE = 73;
275     private static final int CMD_ERASE_MODEM_CONFIG = 74;
276     private static final int EVENT_ERASE_MODEM_CONFIG_DONE = 75;
277     private static final int CMD_CHANGE_ICC_LOCK_PASSWORD = 76;
278     private static final int EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE = 77;
279     private static final int CMD_SET_ICC_LOCK_ENABLED = 78;
280     private static final int EVENT_SET_ICC_LOCK_ENABLED_DONE = 79;
281     private static final int CMD_SET_SYSTEM_SELECTION_CHANNELS = 80;
282     private static final int EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE = 81;
283     private static final int MSG_NOTIFY_USER_ACTIVITY = 82;
284     private static final int CMD_GET_CALL_FORWARDING = 83;
285     private static final int EVENT_GET_CALL_FORWARDING_DONE = 84;
286     private static final int CMD_SET_CALL_FORWARDING = 85;
287     private static final int EVENT_SET_CALL_FORWARDING_DONE = 86;
288     private static final int CMD_GET_CALL_WAITING = 87;
289     private static final int EVENT_GET_CALL_WAITING_DONE = 88;
290     private static final int CMD_SET_CALL_WAITING = 89;
291     private static final int EVENT_SET_CALL_WAITING_DONE = 90;
292 
293     // Parameters of select command.
294     private static final int SELECT_COMMAND = 0xA4;
295     private static final int SELECT_P1 = 0x04;
296     private static final int SELECT_P2 = 0;
297     private static final int SELECT_P3 = 0x10;
298 
299     /** The singleton instance. */
300     private static PhoneInterfaceManager sInstance;
301 
302     private PhoneGlobals mApp;
303     private CallManager mCM;
304     private ImsResolver mImsResolver;
305     private UserManager mUserManager;
306     private AppOpsManager mAppOps;
307     private MainThreadHandler mMainThreadHandler;
308     private SubscriptionController mSubscriptionController;
309     private SharedPreferences mTelephonySharedPreferences;
310     private PhoneConfigurationManager mPhoneConfigurationManager;
311 
312     /** User Activity */
313     private AtomicBoolean mNotifyUserActivity;
314     private static final int USER_ACTIVITY_NOTIFICATION_DELAY = 200;
315 
316     private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
317     private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
318     private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
319     private static final String PREF_PROVISION_IMS_MMTEL_PREFIX = "provision_ims_mmtel_";
320 
321     // String to store multi SIM allowed
322     private static final String PREF_MULTI_SIM_RESTRICTED = "multisim_restricted";
323 
324     // The AID of ISD-R.
325     private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
326 
327     private NetworkScanRequestTracker mNetworkScanRequestTracker;
328 
329     private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
330     private static final int MANUFACTURER_CODE_LENGTH = 8;
331 
332     /**
333      * Experiment flag to enable erase modem config on reset network, default value is false
334      */
335     public static final String RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED =
336             "reset_network_erase_modem_config_enabled";
337 
338     /**
339      * A request object to use for transmitting data to an ICC.
340      */
341     private static final class IccAPDUArgument {
342         public int channel, cla, command, p1, p2, p3;
343         public String data;
344 
IccAPDUArgument(int channel, int cla, int command, int p1, int p2, int p3, String data)345         public IccAPDUArgument(int channel, int cla, int command,
346                 int p1, int p2, int p3, String data) {
347             this.channel = channel;
348             this.cla = cla;
349             this.command = command;
350             this.p1 = p1;
351             this.p2 = p2;
352             this.p3 = p3;
353             this.data = data;
354         }
355     }
356 
357     /**
358      * A request object to use for transmitting data to an ICC.
359      */
360     private static final class ManualNetworkSelectionArgument {
361         public OperatorInfo operatorInfo;
362         public boolean persistSelection;
363 
ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection)364         public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
365             this.operatorInfo = operatorInfo;
366             this.persistSelection = persistSelection;
367         }
368     }
369 
370     /**
371      * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
372      * request after sending. The main thread will notify the request when it is complete.
373      */
374     private static final class MainThreadRequest {
375         /** The argument to use for the request */
376         public Object argument;
377         /** The result of the request that is run on the main thread */
378         public Object result;
379         // The subscriber id that this request applies to. Defaults to
380         // SubscriptionManager.INVALID_SUBSCRIPTION_ID
381         public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
382 
383         // In cases where subId is unavailable, the caller needs to specify the phone.
384         public Phone phone;
385 
386         public WorkSource workSource;
387 
MainThreadRequest(Object argument)388         public MainThreadRequest(Object argument) {
389             this.argument = argument;
390         }
391 
MainThreadRequest(Object argument, Phone phone, WorkSource workSource)392         MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
393             this.argument = argument;
394             if (phone != null) {
395                 this.phone = phone;
396             }
397             this.workSource = workSource;
398         }
399 
MainThreadRequest(Object argument, Integer subId, WorkSource workSource)400         MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
401             this.argument = argument;
402             if (subId != null) {
403                 this.subId = subId;
404             }
405             this.workSource = workSource;
406         }
407     }
408 
409     private static final class IncomingThirdPartyCallArgs {
410         public final ComponentName component;
411         public final String callId;
412         public final String callerDisplayName;
413 
IncomingThirdPartyCallArgs(ComponentName component, String callId, String callerDisplayName)414         public IncomingThirdPartyCallArgs(ComponentName component, String callId,
415                 String callerDisplayName) {
416             this.component = component;
417             this.callId = callId;
418             this.callerDisplayName = callerDisplayName;
419         }
420     }
421 
422     /**
423      * A handler that processes messages on the main thread in the phone process. Since many
424      * of the Phone calls are not thread safe this is needed to shuttle the requests from the
425      * inbound binder threads to the main thread in the phone process.  The Binder thread
426      * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
427      * on, which will be notified when the operation completes and will contain the result of the
428      * request.
429      *
430      * <p>If a MainThreadRequest object is provided in the msg.obj field,
431      * note that request.result must be set to something non-null for the calling thread to
432      * unblock.
433      */
434     private final class MainThreadHandler extends Handler {
435         @Override
handleMessage(Message msg)436         public void handleMessage(Message msg) {
437             MainThreadRequest request;
438             Message onCompleted;
439             AsyncResult ar;
440             UiccCard uiccCard;
441             IccAPDUArgument iccArgument;
442             final Phone defaultPhone = getDefaultPhone();
443 
444             switch (msg.what) {
445                 case CMD_HANDLE_USSD_REQUEST: {
446                     request = (MainThreadRequest) msg.obj;
447                     final Phone phone = getPhoneFromRequest(request);
448                     Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
449                     String ussdRequest =  ussdObject.first;
450                     ResultReceiver wrappedCallback = ussdObject.second;
451 
452                     if (!isUssdApiAllowed(request.subId)) {
453                         // Carrier does not support use of this API, return failure.
454                         Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
455                         UssdResponse response = new UssdResponse(ussdRequest, null);
456                         Bundle returnData = new Bundle();
457                         returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
458                         wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
459 
460                         request.result = true;
461                         notifyRequester(request);
462                         return;
463                     }
464 
465                     try {
466                         request.result = phone != null
467                                 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
468                     } catch (CallStateException cse) {
469                         request.result = false;
470                     }
471                     // Wake up the requesting thread
472                     notifyRequester(request);
473                     break;
474                 }
475 
476                 case CMD_HANDLE_PIN_MMI: {
477                     request = (MainThreadRequest) msg.obj;
478                     final Phone phone = getPhoneFromRequest(request);
479                     request.result = phone != null ?
480                             getPhoneFromRequest(request).handlePinMmi((String) request.argument)
481                             : false;
482                     // Wake up the requesting thread
483                     notifyRequester(request);
484                     break;
485                 }
486 
487                 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
488                     request = (MainThreadRequest) msg.obj;
489                     iccArgument = (IccAPDUArgument) request.argument;
490                     uiccCard = getUiccCardFromRequest(request);
491                     if (uiccCard == null) {
492                         loge("iccTransmitApduLogicalChannel: No UICC");
493                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
494                         notifyRequester(request);
495                     } else {
496                         onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
497                             request);
498                         uiccCard.iccTransmitApduLogicalChannel(
499                             iccArgument.channel, iccArgument.cla, iccArgument.command,
500                             iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
501                             onCompleted);
502                     }
503                     break;
504 
505                 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
506                     ar = (AsyncResult) msg.obj;
507                     request = (MainThreadRequest) ar.userObj;
508                     if (ar.exception == null && ar.result != null) {
509                         request.result = ar.result;
510                     } else {
511                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
512                         if (ar.result == null) {
513                             loge("iccTransmitApduLogicalChannel: Empty response");
514                         } else if (ar.exception instanceof CommandException) {
515                             loge("iccTransmitApduLogicalChannel: CommandException: " +
516                                     ar.exception);
517                         } else {
518                             loge("iccTransmitApduLogicalChannel: Unknown exception");
519                         }
520                     }
521                     notifyRequester(request);
522                     break;
523 
524                 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
525                     request = (MainThreadRequest) msg.obj;
526                     iccArgument = (IccAPDUArgument) request.argument;
527                     uiccCard = getUiccCardFromRequest(request);
528                     if (uiccCard == null) {
529                         loge("iccTransmitApduBasicChannel: No UICC");
530                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
531                         notifyRequester(request);
532                     } else {
533                         onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
534                             request);
535                         uiccCard.iccTransmitApduBasicChannel(
536                             iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
537                             iccArgument.p3, iccArgument.data, onCompleted);
538                     }
539                     break;
540 
541                 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
542                     ar = (AsyncResult) msg.obj;
543                     request = (MainThreadRequest) ar.userObj;
544                     if (ar.exception == null && ar.result != null) {
545                         request.result = ar.result;
546                     } else {
547                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
548                         if (ar.result == null) {
549                             loge("iccTransmitApduBasicChannel: Empty response");
550                         } else if (ar.exception instanceof CommandException) {
551                             loge("iccTransmitApduBasicChannel: CommandException: " +
552                                     ar.exception);
553                         } else {
554                             loge("iccTransmitApduBasicChannel: Unknown exception");
555                         }
556                     }
557                     notifyRequester(request);
558                     break;
559 
560                 case CMD_EXCHANGE_SIM_IO:
561                     request = (MainThreadRequest) msg.obj;
562                     iccArgument = (IccAPDUArgument) request.argument;
563                     uiccCard = getUiccCardFromRequest(request);
564                     if (uiccCard == null) {
565                         loge("iccExchangeSimIO: No UICC");
566                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
567                         notifyRequester(request);
568                     } else {
569                         onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
570                                 request);
571                         uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
572                                 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
573                                 iccArgument.data, onCompleted);
574                     }
575                     break;
576 
577                 case EVENT_EXCHANGE_SIM_IO_DONE:
578                     ar = (AsyncResult) msg.obj;
579                     request = (MainThreadRequest) ar.userObj;
580                     if (ar.exception == null && ar.result != null) {
581                         request.result = ar.result;
582                     } else {
583                         request.result = new IccIoResult(0x6f, 0, (byte[])null);
584                     }
585                     notifyRequester(request);
586                     break;
587 
588                 case CMD_SEND_ENVELOPE:
589                     request = (MainThreadRequest) msg.obj;
590                     uiccCard = getUiccCardFromRequest(request);
591                     if (uiccCard == null) {
592                         loge("sendEnvelopeWithStatus: No UICC");
593                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
594                         notifyRequester(request);
595                     } else {
596                         onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
597                         uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
598                     }
599                     break;
600 
601                 case EVENT_SEND_ENVELOPE_DONE:
602                     ar = (AsyncResult) msg.obj;
603                     request = (MainThreadRequest) ar.userObj;
604                     if (ar.exception == null && ar.result != null) {
605                         request.result = ar.result;
606                     } else {
607                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
608                         if (ar.result == null) {
609                             loge("sendEnvelopeWithStatus: Empty response");
610                         } else if (ar.exception instanceof CommandException) {
611                             loge("sendEnvelopeWithStatus: CommandException: " +
612                                     ar.exception);
613                         } else {
614                             loge("sendEnvelopeWithStatus: exception:" + ar.exception);
615                         }
616                     }
617                     notifyRequester(request);
618                     break;
619 
620                 case CMD_OPEN_CHANNEL:
621                     request = (MainThreadRequest) msg.obj;
622                     uiccCard = getUiccCardFromRequest(request);
623                     Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
624                     if (uiccCard == null) {
625                         loge("iccOpenLogicalChannel: No UICC");
626                         request.result = new IccOpenLogicalChannelResponse(-1,
627                             IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
628                         notifyRequester(request);
629                     } else {
630                         onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
631                         uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
632                                 openChannelArgs.second, onCompleted);
633                     }
634                     break;
635 
636                 case EVENT_OPEN_CHANNEL_DONE:
637                     ar = (AsyncResult) msg.obj;
638                     request = (MainThreadRequest) ar.userObj;
639                     IccOpenLogicalChannelResponse openChannelResp;
640                     if (ar.exception == null && ar.result != null) {
641                         int[] result = (int[]) ar.result;
642                         int channelId = result[0];
643                         byte[] selectResponse = null;
644                         if (result.length > 1) {
645                             selectResponse = new byte[result.length - 1];
646                             for (int i = 1; i < result.length; ++i) {
647                                 selectResponse[i - 1] = (byte) result[i];
648                             }
649                         }
650                         openChannelResp = new IccOpenLogicalChannelResponse(channelId,
651                             IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
652                     } else {
653                         if (ar.result == null) {
654                             loge("iccOpenLogicalChannel: Empty response");
655                         }
656                         if (ar.exception != null) {
657                             loge("iccOpenLogicalChannel: Exception: " + ar.exception);
658                         }
659 
660                         int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
661                         if (ar.exception instanceof CommandException) {
662                             CommandException.Error error =
663                                 ((CommandException) (ar.exception)).getCommandError();
664                             if (error == CommandException.Error.MISSING_RESOURCE) {
665                                 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
666                             } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
667                                 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
668                             }
669                         }
670                         openChannelResp = new IccOpenLogicalChannelResponse(
671                             IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
672                     }
673                     request.result = openChannelResp;
674                     notifyRequester(request);
675                     break;
676 
677                 case CMD_CLOSE_CHANNEL:
678                     request = (MainThreadRequest) msg.obj;
679                     uiccCard = getUiccCardFromRequest(request);
680                     if (uiccCard == null) {
681                         loge("iccCloseLogicalChannel: No UICC");
682                         request.result = false;
683                         notifyRequester(request);
684                     } else {
685                         onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
686                         uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
687                     }
688                     break;
689 
690                 case EVENT_CLOSE_CHANNEL_DONE:
691                     handleNullReturnEvent(msg, "iccCloseLogicalChannel");
692                     break;
693 
694                 case CMD_NV_READ_ITEM:
695                     request = (MainThreadRequest) msg.obj;
696                     onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
697                     defaultPhone.nvReadItem((Integer) request.argument, onCompleted,
698                             request.workSource);
699                     break;
700 
701                 case EVENT_NV_READ_ITEM_DONE:
702                     ar = (AsyncResult) msg.obj;
703                     request = (MainThreadRequest) ar.userObj;
704                     if (ar.exception == null && ar.result != null) {
705                         request.result = ar.result;     // String
706                     } else {
707                         request.result = "";
708                         if (ar.result == null) {
709                             loge("nvReadItem: Empty response");
710                         } else if (ar.exception instanceof CommandException) {
711                             loge("nvReadItem: CommandException: " +
712                                     ar.exception);
713                         } else {
714                             loge("nvReadItem: Unknown exception");
715                         }
716                     }
717                     notifyRequester(request);
718                     break;
719 
720                 case CMD_NV_WRITE_ITEM:
721                     request = (MainThreadRequest) msg.obj;
722                     onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
723                     Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
724                     defaultPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
725                             request.workSource);
726                     break;
727 
728                 case EVENT_NV_WRITE_ITEM_DONE:
729                     handleNullReturnEvent(msg, "nvWriteItem");
730                     break;
731 
732                 case CMD_NV_WRITE_CDMA_PRL:
733                     request = (MainThreadRequest) msg.obj;
734                     onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
735                     defaultPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
736                     break;
737 
738                 case EVENT_NV_WRITE_CDMA_PRL_DONE:
739                     handleNullReturnEvent(msg, "nvWriteCdmaPrl");
740                     break;
741 
742                 case CMD_RESET_MODEM_CONFIG:
743                     request = (MainThreadRequest) msg.obj;
744                     onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
745                     defaultPhone.resetModemConfig(onCompleted);
746                     break;
747 
748                 case EVENT_RESET_MODEM_CONFIG_DONE:
749                     handleNullReturnEvent(msg, "resetModemConfig");
750                     break;
751 
752                 case CMD_GET_PREFERRED_NETWORK_TYPE:
753                     request = (MainThreadRequest) msg.obj;
754                     onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
755                     getPhoneFromRequest(request).getPreferredNetworkType(onCompleted);
756                     break;
757 
758                 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
759                     ar = (AsyncResult) msg.obj;
760                     request = (MainThreadRequest) ar.userObj;
761                     if (ar.exception == null && ar.result != null) {
762                         request.result = ar.result;     // Integer
763                     } else {
764                         request.result = null;
765                         if (ar.result == null) {
766                             loge("getPreferredNetworkType: Empty response");
767                         } else if (ar.exception instanceof CommandException) {
768                             loge("getPreferredNetworkType: CommandException: " +
769                                     ar.exception);
770                         } else {
771                             loge("getPreferredNetworkType: Unknown exception");
772                         }
773                     }
774                     notifyRequester(request);
775                     break;
776 
777                 case CMD_SET_PREFERRED_NETWORK_TYPE:
778                     request = (MainThreadRequest) msg.obj;
779                     onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
780                     int networkType = (Integer) request.argument;
781                     getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted);
782                     break;
783 
784                 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
785                     handleNullReturnEvent(msg, "setPreferredNetworkType");
786                     break;
787 
788                 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
789                     request = (MainThreadRequest)msg.obj;
790                     onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
791                     defaultPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
792                     break;
793 
794                 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
795                     ar = (AsyncResult)msg.obj;
796                     request = (MainThreadRequest)ar.userObj;
797                     request.result = ar;
798                     notifyRequester(request);
799                     break;
800 
801                 case CMD_SET_VOICEMAIL_NUMBER:
802                     request = (MainThreadRequest) msg.obj;
803                     onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
804                     Pair<String, String> tagNum = (Pair<String, String>) request.argument;
805                     getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
806                             onCompleted);
807                     break;
808 
809                 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
810                     handleNullReturnEvent(msg, "setVoicemailNumber");
811                     break;
812 
813                 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
814                     request = (MainThreadRequest) msg.obj;
815                     onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
816                             request);
817                     getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
818                     break;
819 
820                 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
821                     handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
822                     break;
823 
824                 case CMD_PERFORM_NETWORK_SCAN:
825                     request = (MainThreadRequest) msg.obj;
826                     onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
827                     getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
828                     break;
829 
830                 case CMD_GET_CALL_FORWARDING:
831                     request = (MainThreadRequest) msg.obj;
832                     onCompleted = obtainMessage(EVENT_GET_CALL_FORWARDING_DONE, request);
833                     int callForwardingReason = (Integer) request.argument;
834                     getPhoneFromRequest(request).getCallForwardingOption(
835                             callForwardingReason, onCompleted);
836                     break;
837 
838                 case EVENT_GET_CALL_FORWARDING_DONE:
839                     ar = (AsyncResult) msg.obj;
840                     request = (MainThreadRequest) ar.userObj;
841                     CallForwardingInfo callForwardingInfo = null;
842                     if (ar.exception == null && ar.result != null) {
843                         CallForwardInfo[] callForwardInfos = (CallForwardInfo[]) ar.result;
844                         for (CallForwardInfo callForwardInfo : callForwardInfos) {
845                             // Service Class is a bit mask per 3gpp 27.007. Search for
846                             // any service for voice call.
847                             if ((callForwardInfo.serviceClass
848                                     & CommandsInterface.SERVICE_CLASS_VOICE) > 0) {
849                                 callForwardingInfo = new CallForwardingInfo(
850                                         callForwardInfo.serviceClass, callForwardInfo.reason,
851                                                 callForwardInfo.number,
852                                                         callForwardInfo.timeSeconds);
853                                 break;
854                             }
855                         }
856                         // Didn't find a call forward info for voice call.
857                         if (callForwardingInfo == null) {
858                             callForwardingInfo = new CallForwardingInfo(
859                                     CallForwardingInfo.STATUS_UNKNOWN_ERROR,
860                                             0 /* reason */, null /* number */, 0 /* timeout */);
861                         }
862                     } else {
863                         if (ar.result == null) {
864                             loge("EVENT_GET_CALL_FORWARDING_DONE: Empty response");
865                         }
866                         if (ar.exception != null) {
867                             loge("EVENT_GET_CALL_FORWARDING_DONE: Exception: " + ar.exception);
868                         }
869                         int errorCode = CallForwardingInfo.STATUS_UNKNOWN_ERROR;
870                         if (ar.exception instanceof CommandException) {
871                             CommandException.Error error =
872                                     ((CommandException) (ar.exception)).getCommandError();
873                             if (error == CommandException.Error.FDN_CHECK_FAILURE) {
874                                 errorCode = CallForwardingInfo.STATUS_FDN_CHECK_FAILURE;
875                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
876                                 errorCode = CallForwardingInfo.STATUS_NOT_SUPPORTED;
877                             }
878                         }
879                         callForwardingInfo = new CallForwardingInfo(
880                                 errorCode, 0 /* reason */, null /* number */, 0 /* timeout */);
881                     }
882                     request.result = callForwardingInfo;
883                     notifyRequester(request);
884                     break;
885 
886                 case CMD_SET_CALL_FORWARDING:
887                     request = (MainThreadRequest) msg.obj;
888                     onCompleted = obtainMessage(EVENT_SET_CALL_FORWARDING_DONE, request);
889                     CallForwardingInfo callForwardingInfoToSet =
890                             (CallForwardingInfo) request.argument;
891                     getPhoneFromRequest(request).setCallForwardingOption(
892                             callForwardingInfoToSet.getStatus(),
893                             callForwardingInfoToSet.getReason(),
894                             callForwardingInfoToSet.getNumber(),
895                             callForwardingInfoToSet.getTimeoutSeconds(), onCompleted);
896                     break;
897 
898                 case EVENT_SET_CALL_FORWARDING_DONE:
899                     ar = (AsyncResult) msg.obj;
900                     request = (MainThreadRequest) ar.userObj;
901                     if (ar.exception == null) {
902                         request.result = true;
903                     } else {
904                         request.result = false;
905                         loge("setCallForwarding exception: " + ar.exception);
906                     }
907                     notifyRequester(request);
908                     break;
909 
910                 case CMD_GET_CALL_WAITING:
911                     request = (MainThreadRequest) msg.obj;
912                     onCompleted = obtainMessage(EVENT_GET_CALL_WAITING_DONE, request);
913                     getPhoneFromRequest(request).getCallWaiting(onCompleted);
914                     break;
915 
916                 case EVENT_GET_CALL_WAITING_DONE:
917                     ar = (AsyncResult) msg.obj;
918                     request = (MainThreadRequest) ar.userObj;
919                     int callForwardingStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
920                     if (ar.exception == null && ar.result != null) {
921                         int[] callForwardResults = (int[]) ar.result;
922                         // Service Class is a bit mask per 3gpp 27.007.
923                         // Search for any service for voice call.
924                         if (callForwardResults.length > 1
925                                 && ((callForwardResults[1]
926                                         & CommandsInterface.SERVICE_CLASS_VOICE) > 0)) {
927                             callForwardingStatus = callForwardResults[0] == 0
928                                     ? TelephonyManager.CALL_WAITING_STATUS_INACTIVE
929                                             : TelephonyManager.CALL_WAITING_STATUS_ACTIVE;
930                         } else {
931                             callForwardingStatus = TelephonyManager.CALL_WAITING_STATUS_INACTIVE;
932                         }
933                     } else {
934                         if (ar.result == null) {
935                             loge("EVENT_GET_CALL_WAITING_DONE: Empty response");
936                         }
937                         if (ar.exception != null) {
938                             loge("EVENT_GET_CALL_WAITING_DONE: Exception: " + ar.exception);
939                         }
940                         if (ar.exception instanceof CommandException) {
941                             CommandException.Error error =
942                                     ((CommandException) (ar.exception)).getCommandError();
943                             if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
944                                 callForwardingStatus =
945                                         TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED;
946                             }
947                         }
948                     }
949                     request.result = callForwardingStatus;
950                     notifyRequester(request);
951                     break;
952 
953                 case CMD_SET_CALL_WAITING:
954                     request = (MainThreadRequest) msg.obj;
955                     onCompleted = obtainMessage(EVENT_SET_CALL_WAITING_DONE, request);
956                     boolean isEnable = (Boolean) request.argument;
957                     getPhoneFromRequest(request).setCallWaiting(isEnable, onCompleted);
958                     break;
959 
960                 case EVENT_SET_CALL_WAITING_DONE:
961                     ar = (AsyncResult) msg.obj;
962                     request = (MainThreadRequest) ar.userObj;
963                     if (ar.exception == null) {
964                         request.result = true;
965                     } else {
966                         request.result = false;
967                         loge("setCallWaiting exception: " + ar.exception);
968                     }
969                     notifyRequester(request);
970                     break;
971 
972                 case EVENT_PERFORM_NETWORK_SCAN_DONE:
973                     ar = (AsyncResult) msg.obj;
974                     request = (MainThreadRequest) ar.userObj;
975                     CellNetworkScanResult cellScanResult;
976                     if (ar.exception == null && ar.result != null) {
977                         cellScanResult = new CellNetworkScanResult(
978                                 CellNetworkScanResult.STATUS_SUCCESS,
979                                 (List<OperatorInfo>) ar.result);
980                     } else {
981                         if (ar.result == null) {
982                             loge("getCellNetworkScanResults: Empty response");
983                         }
984                         if (ar.exception != null) {
985                             loge("getCellNetworkScanResults: Exception: " + ar.exception);
986                         }
987                         int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
988                         if (ar.exception instanceof CommandException) {
989                             CommandException.Error error =
990                                 ((CommandException) (ar.exception)).getCommandError();
991                             if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
992                                 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
993                             } else if (error == CommandException.Error.GENERIC_FAILURE) {
994                                 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
995                             }
996                         }
997                         cellScanResult = new CellNetworkScanResult(errorCode, null);
998                     }
999                     request.result = cellScanResult;
1000                     notifyRequester(request);
1001                     break;
1002 
1003                 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
1004                     request = (MainThreadRequest) msg.obj;
1005                     ManualNetworkSelectionArgument selArg =
1006                             (ManualNetworkSelectionArgument) request.argument;
1007                     onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
1008                             request);
1009                     getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
1010                             selArg.persistSelection, onCompleted);
1011                     break;
1012 
1013                 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
1014                     ar = (AsyncResult) msg.obj;
1015                     request = (MainThreadRequest) ar.userObj;
1016                     if (ar.exception == null) {
1017                         request.result = true;
1018                     } else {
1019                         request.result = false;
1020                         loge("setNetworkSelectionModeManual " + ar.exception);
1021                     }
1022                     notifyRequester(request);
1023                     mApp.onNetworkSelectionChanged(request.subId);
1024                     break;
1025 
1026                 case CMD_GET_MODEM_ACTIVITY_INFO:
1027                     request = (MainThreadRequest) msg.obj;
1028                     onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
1029                     if (defaultPhone != null) {
1030                         defaultPhone.getModemActivityInfo(onCompleted, request.workSource);
1031                     } else {
1032                         ResultReceiver result = (ResultReceiver) request.argument;
1033                         Bundle bundle = new Bundle();
1034                         bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY,
1035                                 new ModemActivityInfo(0, 0, 0, new int[0], 0));
1036                         result.send(0, bundle);
1037                     }
1038                     break;
1039 
1040                 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE:
1041                     ar = (AsyncResult) msg.obj;
1042                     request = (MainThreadRequest) ar.userObj;
1043                     ResultReceiver result = (ResultReceiver) request.argument;
1044 
1045                     ModemActivityInfo ret = new ModemActivityInfo(0, 0, 0, new int[0], 0);
1046                     if (ar.exception == null && ar.result != null) {
1047                         // Update the last modem activity info and the result of the request.
1048                         ModemActivityInfo info = (ModemActivityInfo) ar.result;
1049                         if (isModemActivityInfoValid(info)) {
1050                             int[] mergedTxTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
1051                             int[] txTimeMs = info.getTransmitTimeMillis();
1052                             int[] lastModemTxTimeMs = mLastModemActivityInfo
1053                                     .getTransmitTimeMillis();
1054                             for (int i = 0; i < mergedTxTimeMs.length; i++) {
1055                                 mergedTxTimeMs[i] = txTimeMs[i] + lastModemTxTimeMs[i];
1056                             }
1057                             mLastModemActivityInfo.setTimestamp(info.getTimestamp());
1058                             mLastModemActivityInfo.setSleepTimeMillis(info.getSleepTimeMillis()
1059                                     + mLastModemActivityInfo.getSleepTimeMillis());
1060                             mLastModemActivityInfo.setIdleTimeMillis(info.getIdleTimeMillis()
1061                                     + mLastModemActivityInfo.getIdleTimeMillis());
1062                             mLastModemActivityInfo.setTransmitTimeMillis(mergedTxTimeMs);
1063                             mLastModemActivityInfo.setReceiveTimeMillis(
1064                                     info.getReceiveTimeMillis()
1065                                             + mLastModemActivityInfo.getReceiveTimeMillis());
1066                         }
1067                         ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestamp(),
1068                                 mLastModemActivityInfo.getSleepTimeMillis(),
1069                                 mLastModemActivityInfo.getIdleTimeMillis(),
1070                                 mLastModemActivityInfo.getTransmitTimeMillis(),
1071                                 mLastModemActivityInfo.getReceiveTimeMillis());
1072                     } else {
1073                         if (ar.result == null) {
1074                             loge("queryModemActivityInfo: Empty response");
1075                         } else if (ar.exception instanceof CommandException) {
1076                             loge("queryModemActivityInfo: CommandException: " +
1077                                     ar.exception);
1078                         } else {
1079                             loge("queryModemActivityInfo: Unknown exception");
1080                         }
1081                     }
1082                     Bundle bundle = new Bundle();
1083                     bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
1084                     result.send(0, bundle);
1085                     notifyRequester(request);
1086                     break;
1087 
1088                 case CMD_SET_ALLOWED_CARRIERS:
1089                     request = (MainThreadRequest) msg.obj;
1090                     CarrierRestrictionRules argument =
1091                             (CarrierRestrictionRules) request.argument;
1092                     onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
1093                     defaultPhone.setAllowedCarriers(argument, onCompleted, request.workSource);
1094                     break;
1095 
1096                 case EVENT_SET_ALLOWED_CARRIERS_DONE:
1097                     ar = (AsyncResult) msg.obj;
1098                     request = (MainThreadRequest) ar.userObj;
1099                     if (ar.exception == null && ar.result != null) {
1100                         request.result = ar.result;
1101                     } else {
1102                         request.result = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
1103                         if (ar.exception instanceof CommandException) {
1104                             loge("setAllowedCarriers: CommandException: " + ar.exception);
1105                             CommandException.Error error =
1106                                     ((CommandException) (ar.exception)).getCommandError();
1107                             if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1108                                 request.result =
1109                                         TelephonyManager.SET_CARRIER_RESTRICTION_NOT_SUPPORTED;
1110                             }
1111                         } else {
1112                             loge("setAllowedCarriers: Unknown exception");
1113                         }
1114                     }
1115                     notifyRequester(request);
1116                     break;
1117 
1118                 case CMD_GET_ALLOWED_CARRIERS:
1119                     request = (MainThreadRequest) msg.obj;
1120                     onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
1121                     defaultPhone.getAllowedCarriers(onCompleted, request.workSource);
1122                     break;
1123 
1124                 case EVENT_GET_ALLOWED_CARRIERS_DONE:
1125                     ar = (AsyncResult) msg.obj;
1126                     request = (MainThreadRequest) ar.userObj;
1127                     if (ar.exception == null && ar.result != null) {
1128                         request.result = ar.result;
1129                     } else {
1130                         request.result = new IllegalStateException(
1131                             "Failed to get carrier restrictions");
1132                         if (ar.result == null) {
1133                             loge("getAllowedCarriers: Empty response");
1134                         } else if (ar.exception instanceof CommandException) {
1135                             loge("getAllowedCarriers: CommandException: " +
1136                                     ar.exception);
1137                         } else {
1138                             loge("getAllowedCarriers: Unknown exception");
1139                         }
1140                     }
1141                     notifyRequester(request);
1142                     break;
1143 
1144                 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
1145                     ar = (AsyncResult) msg.obj;
1146                     request = (MainThreadRequest) ar.userObj;
1147                     if (ar.exception == null && ar.result != null) {
1148                         request.result = ar.result;
1149                     } else {
1150                         request.result = new IllegalArgumentException(
1151                                 "Failed to retrieve Forbidden Plmns");
1152                         if (ar.result == null) {
1153                             loge("getForbiddenPlmns: Empty response");
1154                         } else {
1155                             loge("getForbiddenPlmns: Unknown exception");
1156                         }
1157                     }
1158                     notifyRequester(request);
1159                     break;
1160 
1161                 case CMD_GET_FORBIDDEN_PLMNS:
1162                     request = (MainThreadRequest) msg.obj;
1163                     uiccCard = getUiccCardFromRequest(request);
1164                     if (uiccCard == null) {
1165                         loge("getForbiddenPlmns() UiccCard is null");
1166                         request.result = new IllegalArgumentException(
1167                                 "getForbiddenPlmns() UiccCard is null");
1168                         notifyRequester(request);
1169                         break;
1170                     }
1171                     Integer appType = (Integer) request.argument;
1172                     UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
1173                     if (uiccApp == null) {
1174                         loge("getForbiddenPlmns() no app with specified type -- "
1175                                 + appType);
1176                         request.result = new IllegalArgumentException("Failed to get UICC App");
1177                         notifyRequester(request);
1178                         break;
1179                     } else {
1180                         if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
1181                                 + " specified type -- " + appType);
1182                     }
1183                     onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
1184                     ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
1185                               onCompleted);
1186                     break;
1187 
1188                 case CMD_SWITCH_SLOTS:
1189                     request = (MainThreadRequest) msg.obj;
1190                     int[] physicalSlots = (int[]) request.argument;
1191                     onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
1192                     UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
1193                     break;
1194 
1195                 case EVENT_SWITCH_SLOTS_DONE:
1196                     ar = (AsyncResult) msg.obj;
1197                     request = (MainThreadRequest) ar.userObj;
1198                     request.result = (ar.exception == null);
1199                     notifyRequester(request);
1200                     break;
1201                 case CMD_GET_NETWORK_SELECTION_MODE:
1202                     request = (MainThreadRequest) msg.obj;
1203                     onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
1204                     getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
1205                     break;
1206 
1207                 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
1208                     ar = (AsyncResult) msg.obj;
1209                     request = (MainThreadRequest) ar.userObj;
1210                     if (ar.exception != null) {
1211                         request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
1212                     } else {
1213                         int mode = ((int[]) ar.result)[0];
1214                         if (mode == 0) {
1215                             request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
1216                         } else {
1217                             request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
1218                         }
1219                     }
1220                     notifyRequester(request);
1221                     break;
1222                 case CMD_GET_CDMA_ROAMING_MODE:
1223                     request = (MainThreadRequest) msg.obj;
1224                     onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
1225                     getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
1226                     break;
1227                 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
1228                     ar = (AsyncResult) msg.obj;
1229                     request = (MainThreadRequest) ar.userObj;
1230                     if (ar.exception != null) {
1231                         request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
1232                     } else {
1233                         request.result = ((int[]) ar.result)[0];
1234                     }
1235                     notifyRequester(request);
1236                     break;
1237                 case CMD_SET_CDMA_ROAMING_MODE:
1238                     request = (MainThreadRequest) msg.obj;
1239                     onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
1240                     int mode = (int) request.argument;
1241                     getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
1242                     break;
1243                 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
1244                     ar = (AsyncResult) msg.obj;
1245                     request = (MainThreadRequest) ar.userObj;
1246                     request.result = ar.exception == null;
1247                     notifyRequester(request);
1248                     break;
1249                 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
1250                     request = (MainThreadRequest) msg.obj;
1251                     onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1252                     int subscriptionMode = (int) request.argument;
1253                     getPhoneFromRequest(request).setCdmaSubscription(subscriptionMode, onCompleted);
1254                     break;
1255                 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
1256                     ar = (AsyncResult) msg.obj;
1257                     request = (MainThreadRequest) ar.userObj;
1258                     request.result = ar.exception == null;
1259                     notifyRequester(request);
1260                     break;
1261                 case CMD_GET_ALL_CELL_INFO:
1262                     request = (MainThreadRequest) msg.obj;
1263                     onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
1264                     request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
1265                     break;
1266                 case EVENT_GET_ALL_CELL_INFO_DONE:
1267                     ar = (AsyncResult) msg.obj;
1268                     request = (MainThreadRequest) ar.userObj;
1269                     // If a timeout occurs, the response will be null
1270                     request.result = (ar.exception == null && ar.result != null)
1271                             ? ar.result : new ArrayList<CellInfo>();
1272                     synchronized (request) {
1273                         request.notifyAll();
1274                     }
1275                     break;
1276                 case CMD_REQUEST_CELL_INFO_UPDATE:
1277                     request = (MainThreadRequest) msg.obj;
1278                     request.phone.requestCellInfoUpdate(request.workSource,
1279                             obtainMessage(EVENT_REQUEST_CELL_INFO_UPDATE_DONE, request));
1280                     break;
1281                 case EVENT_REQUEST_CELL_INFO_UPDATE_DONE:
1282                     ar = (AsyncResult) msg.obj;
1283                     request = (MainThreadRequest) ar.userObj;
1284                     ICellInfoCallback cb = (ICellInfoCallback) request.argument;
1285                     try {
1286                         if (ar.exception != null) {
1287                             Log.e(LOG_TAG, "Exception retrieving CellInfo=" + ar.exception);
1288                             cb.onError(
1289                                     TelephonyManager.CellInfoCallback.ERROR_MODEM_ERROR,
1290                                     ar.exception.getClass().getName(),
1291                                     ar.exception.toString());
1292                         } else if (ar.result == null) {
1293                             Log.w(LOG_TAG, "Timeout Waiting for CellInfo!");
1294                             cb.onError(TelephonyManager.CellInfoCallback.ERROR_TIMEOUT, null, null);
1295                         } else {
1296                             // use the result as returned
1297                             cb.onCellInfo((List<CellInfo>) ar.result);
1298                         }
1299                     } catch (RemoteException re) {
1300                         Log.w(LOG_TAG, "Discarded CellInfo due to Callback RemoteException");
1301                     }
1302                     break;
1303                 case CMD_GET_CELL_LOCATION:
1304                     request = (MainThreadRequest) msg.obj;
1305                     WorkSource ws = (WorkSource) request.argument;
1306                     Phone phone = getPhoneFromRequest(request);
1307                     phone.getCellIdentity(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
1308                     break;
1309                 case EVENT_GET_CELL_LOCATION_DONE:
1310                     ar = (AsyncResult) msg.obj;
1311                     request = (MainThreadRequest) ar.userObj;
1312                     if (ar.exception == null) {
1313                         request.result = ar.result;
1314                     } else {
1315                         phone = getPhoneFromRequest(request);
1316                         request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
1317                                 ? new CellIdentityCdma() : new CellIdentityGsm();
1318                     }
1319 
1320                     synchronized (request) {
1321                         request.notifyAll();
1322                     }
1323                     break;
1324                 case CMD_MODEM_REBOOT:
1325                     request = (MainThreadRequest) msg.obj;
1326                     onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
1327                     defaultPhone.rebootModem(onCompleted);
1328                     break;
1329                 case EVENT_CMD_MODEM_REBOOT_DONE:
1330                     handleNullReturnEvent(msg, "rebootModem");
1331                     break;
1332                 case CMD_REQUEST_ENABLE_MODEM:
1333                     request = (MainThreadRequest) msg.obj;
1334                     boolean enable = (boolean) request.argument;
1335                     onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
1336                     onCompleted.arg1 = enable ? 1 : 0;
1337                     PhoneConfigurationManager.getInstance()
1338                             .enablePhone(request.phone, enable, onCompleted);
1339                     break;
1340                 case EVENT_ENABLE_MODEM_DONE:
1341                     ar = (AsyncResult) msg.obj;
1342                     request = (MainThreadRequest) ar.userObj;
1343                     request.result = (ar.exception == null);
1344                     int phoneId = request.phone.getPhoneId();
1345                     //update the cache as modem status has changed
1346                     if ((boolean) request.result) {
1347                         mPhoneConfigurationManager.addToPhoneStatusCache(phoneId, msg.arg1 == 1);
1348                         updateModemStateMetrics();
1349                     } else {
1350                         Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1351                                 + ar.exception);
1352                     }
1353                     notifyRequester(request);
1354                     break;
1355                 case CMD_GET_MODEM_STATUS:
1356                     request = (MainThreadRequest) msg.obj;
1357                     onCompleted = obtainMessage(EVENT_GET_MODEM_STATUS_DONE, request);
1358                     PhoneConfigurationManager.getInstance()
1359                             .getPhoneStatusFromModem(request.phone, onCompleted);
1360                     break;
1361                 case EVENT_GET_MODEM_STATUS_DONE:
1362                     ar = (AsyncResult) msg.obj;
1363                     request = (MainThreadRequest) ar.userObj;
1364                     int id = request.phone.getPhoneId();
1365                     if (ar.exception == null && ar.result != null) {
1366                         request.result = ar.result;
1367                         //update the cache as modem status has changed
1368                         mPhoneConfigurationManager.addToPhoneStatusCache(id,
1369                                 (boolean) request.result);
1370                     } else {
1371                         // Return true if modem status cannot be retrieved. For most cases,
1372                         // modem status is on. And for older version modems, GET_MODEM_STATUS
1373                         // and disable modem are not supported. Modem is always on.
1374                         // TODO: this should be fixed in R to support a third
1375                         // status UNKNOWN b/131631629
1376                         request.result = true;
1377                         Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1378                                 + ar.exception);
1379                     }
1380                     notifyRequester(request);
1381                     break;
1382                 case CMD_SET_SYSTEM_SELECTION_CHANNELS: {
1383                     request = (MainThreadRequest) msg.obj;
1384                     onCompleted = obtainMessage(EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1385                     Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1386                             (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1387                     request.phone.setSystemSelectionChannels(args.first, onCompleted);
1388                     break;
1389                 }
1390                 case EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE: {
1391                     ar = (AsyncResult) msg.obj;
1392                     request = (MainThreadRequest) ar.userObj;
1393                     Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1394                             (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1395                     args.second.accept(ar.exception == null);
1396                     notifyRequester(request);
1397                     break;
1398                 }
1399                 case EVENT_SET_FORBIDDEN_PLMNS_DONE:
1400                     ar = (AsyncResult) msg.obj;
1401                     request = (MainThreadRequest) ar.userObj;
1402                     if (ar.exception == null && ar.result != null) {
1403                         request.result = ar.result;
1404                     } else {
1405                         request.result = -1;
1406                         loge("Failed to set Forbidden Plmns");
1407                         if (ar.result == null) {
1408                             loge("setForbidenPlmns: Empty response");
1409                         } else if (ar.exception != null) {
1410                             loge("setForbiddenPlmns: Exception: " + ar.exception);
1411                             request.result = -1;
1412                         } else {
1413                             loge("setForbiddenPlmns: Unknown exception");
1414                         }
1415                     }
1416                     notifyRequester(request);
1417                     break;
1418                 case CMD_SET_FORBIDDEN_PLMNS:
1419                     request = (MainThreadRequest) msg.obj;
1420                     uiccCard = getUiccCardFromRequest(request);
1421                     if (uiccCard == null) {
1422                         loge("setForbiddenPlmns: UiccCard is null");
1423                         request.result = -1;
1424                         notifyRequester(request);
1425                         break;
1426                     }
1427                     Pair<Integer, List<String>> setFplmnsArgs =
1428                             (Pair<Integer, List<String>>) request.argument;
1429                     appType = setFplmnsArgs.first;
1430                     List<String> fplmns = setFplmnsArgs.second;
1431                     uiccApp = uiccCard.getApplicationByType(appType);
1432                     if (uiccApp == null) {
1433                         loge("setForbiddenPlmns: no app with specified type -- " + appType);
1434                         request.result = -1;
1435                         loge("Failed to get UICC App");
1436                         notifyRequester(request);
1437                     } else {
1438                         onCompleted = obtainMessage(EVENT_SET_FORBIDDEN_PLMNS_DONE, request);
1439                         ((SIMRecords) uiccApp.getIccRecords())
1440                                 .setForbiddenPlmns(onCompleted, fplmns);
1441                     }
1442                     break;
1443                 case CMD_ERASE_MODEM_CONFIG:
1444                     request = (MainThreadRequest) msg.obj;
1445                     onCompleted = obtainMessage(EVENT_ERASE_MODEM_CONFIG_DONE, request);
1446                     defaultPhone.eraseModemConfig(onCompleted);
1447                     break;
1448                 case EVENT_ERASE_MODEM_CONFIG_DONE:
1449                     handleNullReturnEvent(msg, "eraseModemConfig");
1450                     break;
1451 
1452                 case CMD_CHANGE_ICC_LOCK_PASSWORD:
1453                     request = (MainThreadRequest) msg.obj;
1454                     onCompleted = obtainMessage(EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE, request);
1455                     Pair<String, String> changed = (Pair<String, String>) request.argument;
1456                     getPhoneFromRequest(request).getIccCard().changeIccLockPassword(
1457                             changed.first, changed.second, onCompleted);
1458                     break;
1459                 case EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE:
1460                     ar = (AsyncResult) msg.obj;
1461                     request = (MainThreadRequest) ar.userObj;
1462                     if (ar.exception == null) {
1463                         request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
1464                     } else {
1465                         request.result = msg.arg1;
1466                     }
1467                     notifyRequester(request);
1468                     break;
1469 
1470                 case CMD_SET_ICC_LOCK_ENABLED:
1471                     request = (MainThreadRequest) msg.obj;
1472                     onCompleted = obtainMessage(EVENT_SET_ICC_LOCK_ENABLED_DONE, request);
1473                     Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
1474                     getPhoneFromRequest(request).getIccCard().setIccLockEnabled(
1475                             enabled.first, enabled.second, onCompleted);
1476                     break;
1477                 case EVENT_SET_ICC_LOCK_ENABLED_DONE:
1478                     ar = (AsyncResult) msg.obj;
1479                     request = (MainThreadRequest) ar.userObj;
1480                     if (ar.exception == null) {
1481                         request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
1482                     } else {
1483                         request.result = msg.arg1;
1484                     }
1485                     notifyRequester(request);
1486                     break;
1487 
1488                 case MSG_NOTIFY_USER_ACTIVITY:
1489                     removeMessages(MSG_NOTIFY_USER_ACTIVITY);
1490                     Intent intent = new Intent(TelephonyIntents.ACTION_USER_ACTIVITY_NOTIFICATION);
1491                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1492                     getDefaultPhone().getContext().sendBroadcastAsUser(
1493                             intent, UserHandle.ALL, permission.USER_ACTIVITY);
1494                     break;
1495                 default:
1496                     Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
1497                     break;
1498             }
1499         }
1500 
notifyRequester(MainThreadRequest request)1501         private void notifyRequester(MainThreadRequest request) {
1502             synchronized (request) {
1503                 request.notifyAll();
1504             }
1505         }
1506 
handleNullReturnEvent(Message msg, String command)1507         private void handleNullReturnEvent(Message msg, String command) {
1508             AsyncResult ar = (AsyncResult) msg.obj;
1509             MainThreadRequest request = (MainThreadRequest) ar.userObj;
1510             if (ar.exception == null) {
1511                 request.result = true;
1512             } else {
1513                 request.result = false;
1514                 if (ar.exception instanceof CommandException) {
1515                     loge(command + ": CommandException: " + ar.exception);
1516                 } else {
1517                     loge(command + ": Unknown exception");
1518                 }
1519             }
1520             notifyRequester(request);
1521         }
1522     }
1523 
1524     /**
1525      * Posts the specified command to be executed on the main thread,
1526      * waits for the request to complete, and returns the result.
1527      * @see #sendRequestAsync
1528      */
sendRequest(int command, Object argument)1529     private Object sendRequest(int command, Object argument) {
1530         return sendRequest(
1531                 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null, null);
1532     }
1533 
1534     /**
1535      * Posts the specified command to be executed on the main thread,
1536      * waits for the request to complete, and returns the result.
1537      * @see #sendRequestAsync
1538      */
sendRequest(int command, Object argument, WorkSource workSource)1539     private Object sendRequest(int command, Object argument, WorkSource workSource) {
1540         return sendRequest(command, argument,  SubscriptionManager.INVALID_SUBSCRIPTION_ID,
1541                 null, workSource);
1542     }
1543 
1544     /**
1545      * Posts the specified command to be executed on the main thread,
1546      * waits for the request to complete, and returns the result.
1547      * @see #sendRequestAsync
1548      */
sendRequest(int command, Object argument, Integer subId)1549     private Object sendRequest(int command, Object argument, Integer subId) {
1550         return sendRequest(command, argument, subId, null, null);
1551     }
1552 
1553     /**
1554      * Posts the specified command to be executed on the main thread,
1555      * waits for the request to complete, and returns the result.
1556      * @see #sendRequestAsync
1557      */
sendRequest(int command, Object argument, int subId, WorkSource workSource)1558     private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
1559         return sendRequest(command, argument, subId, null, workSource);
1560     }
1561 
1562     /**
1563      * Posts the specified command to be executed on the main thread,
1564      * waits for the request to complete, and returns the result.
1565      * @see #sendRequestAsync
1566      */
sendRequest(int command, Object argument, Phone phone, WorkSource workSource)1567     private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
1568         return sendRequest(
1569                 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone, workSource);
1570     }
1571 
1572     /**
1573      * Posts the specified command to be executed on the main thread,
1574      * waits for the request to complete, and returns the result.
1575      * @see #sendRequestAsync
1576      */
sendRequest( int command, Object argument, Integer subId, Phone phone, WorkSource workSource)1577     private Object sendRequest(
1578             int command, Object argument, Integer subId, Phone phone, WorkSource workSource) {
1579         if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
1580             throw new RuntimeException("This method will deadlock if called from the main thread.");
1581         }
1582 
1583         MainThreadRequest request = null;
1584         if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
1585             throw new IllegalArgumentException("subId and phone cannot both be specified!");
1586         } else if (phone != null) {
1587             request = new MainThreadRequest(argument, phone, workSource);
1588         } else {
1589             request = new MainThreadRequest(argument, subId, workSource);
1590         }
1591 
1592         Message msg = mMainThreadHandler.obtainMessage(command, request);
1593         msg.sendToTarget();
1594 
1595         // Wait for the request to complete
1596         synchronized (request) {
1597             while (request.result == null) {
1598                 try {
1599                     request.wait();
1600                 } catch (InterruptedException e) {
1601                     // Do nothing, go back and wait until the request is complete
1602                 }
1603             }
1604         }
1605         return request.result;
1606     }
1607 
1608     /**
1609      * Asynchronous ("fire and forget") version of sendRequest():
1610      * Posts the specified command to be executed on the main thread, and
1611      * returns immediately.
1612      * @see #sendRequest
1613      */
sendRequestAsync(int command)1614     private void sendRequestAsync(int command) {
1615         mMainThreadHandler.sendEmptyMessage(command);
1616     }
1617 
1618     /**
1619      * Same as {@link #sendRequestAsync(int)} except it takes an argument.
1620      * @see {@link #sendRequest(int)}
1621      */
sendRequestAsync(int command, Object argument)1622     private void sendRequestAsync(int command, Object argument) {
1623         sendRequestAsync(command, argument, null, null);
1624     }
1625 
1626     /**
1627      * Same as {@link #sendRequestAsync(int,Object)} except it takes a Phone and WorkSource.
1628      * @see {@link #sendRequest(int,Object)}
1629      */
sendRequestAsync( int command, Object argument, Phone phone, WorkSource workSource)1630     private void sendRequestAsync(
1631             int command, Object argument, Phone phone, WorkSource workSource) {
1632         MainThreadRequest request = new MainThreadRequest(argument, phone, workSource);
1633         Message msg = mMainThreadHandler.obtainMessage(command, request);
1634         msg.sendToTarget();
1635     }
1636 
1637     /**
1638      * Initialize the singleton PhoneInterfaceManager instance.
1639      * This is only done once, at startup, from PhoneApp.onCreate().
1640      */
init(PhoneGlobals app)1641     /* package */ static PhoneInterfaceManager init(PhoneGlobals app) {
1642         synchronized (PhoneInterfaceManager.class) {
1643             if (sInstance == null) {
1644                 sInstance = new PhoneInterfaceManager(app);
1645             } else {
1646                 Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
1647             }
1648             return sInstance;
1649         }
1650     }
1651 
1652     /** Private constructor; @see init() */
PhoneInterfaceManager(PhoneGlobals app)1653     private PhoneInterfaceManager(PhoneGlobals app) {
1654         mApp = app;
1655         mCM = PhoneGlobals.getInstance().mCM;
1656         mImsResolver = PhoneGlobals.getInstance().getImsResolver();
1657         mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
1658         mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
1659         mMainThreadHandler = new MainThreadHandler();
1660         mSubscriptionController = SubscriptionController.getInstance();
1661         mTelephonySharedPreferences =
1662                 PreferenceManager.getDefaultSharedPreferences(mApp);
1663         mNetworkScanRequestTracker = new NetworkScanRequestTracker();
1664         mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
1665         mNotifyUserActivity = new AtomicBoolean(false);
1666 
1667         publish();
1668     }
1669 
getDefaultPhone()1670     private Phone getDefaultPhone() {
1671         Phone thePhone = getPhone(getDefaultSubscription());
1672         return (thePhone != null) ? thePhone : PhoneFactory.getDefaultPhone();
1673     }
1674 
publish()1675     private void publish() {
1676         if (DBG) log("publish: " + this);
1677 
1678         TelephonyFrameworkInitializer
1679                 .getTelephonyServiceManager()
1680                 .getTelephonyServiceRegisterer()
1681                 .register(this);
1682     }
1683 
getPhoneFromRequest(MainThreadRequest request)1684     private Phone getPhoneFromRequest(MainThreadRequest request) {
1685         if (request.phone != null) {
1686             return request.phone;
1687         } else {
1688             return getPhoneFromSubId(request.subId);
1689         }
1690     }
1691 
getPhoneFromSubId(int subId)1692     private Phone getPhoneFromSubId(int subId) {
1693         return (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
1694                 ? getDefaultPhone() : getPhone(subId);
1695     }
1696 
getUiccCardFromRequest(MainThreadRequest request)1697     private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
1698         Phone phone = getPhoneFromRequest(request);
1699         return phone == null ? null :
1700                 UiccController.getInstance().getUiccCard(phone.getPhoneId());
1701     }
1702 
1703     // returns phone associated with the subId.
getPhone(int subId)1704     private Phone getPhone(int subId) {
1705         return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
1706     }
1707 
sendEraseModemConfig(Phone phone)1708     private void sendEraseModemConfig(Phone phone) {
1709         if (phone != null) {
1710             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
1711                   mApp, phone.getSubId(), "eraseModemConfig");
1712             final long identity = Binder.clearCallingIdentity();
1713             try {
1714                 Boolean success = (Boolean) sendRequest(CMD_ERASE_MODEM_CONFIG, null);
1715                 if (DBG) log("eraseModemConfig:" + ' ' + (success ? "ok" : "fail"));
1716             } finally {
1717                 Binder.restoreCallingIdentity(identity);
1718             }
1719         }
1720     }
1721 
isImsAvailableOnDevice()1722     private boolean isImsAvailableOnDevice() {
1723         PackageManager pm = getDefaultPhone().getContext().getPackageManager();
1724         if (pm == null) {
1725             // For some reason package manger is not available.. This will fail internally anyway,
1726             // so do not throw error and allow.
1727             return true;
1728         }
1729         return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS, 0);
1730     }
1731 
dial(String number)1732     public void dial(String number) {
1733         dialForSubscriber(getPreferredVoiceSubscription(), number);
1734     }
1735 
dialForSubscriber(int subId, String number)1736     public void dialForSubscriber(int subId, String number) {
1737         if (DBG) log("dial: " + number);
1738         // No permission check needed here: This is just a wrapper around the
1739         // ACTION_DIAL intent, which is available to any app since it puts up
1740         // the UI before it does anything.
1741 
1742         final long identity = Binder.clearCallingIdentity();
1743         try {
1744             String url = createTelUrl(number);
1745             if (url == null) {
1746                 return;
1747             }
1748 
1749             // PENDING: should we just silently fail if phone is offhook or ringing?
1750             PhoneConstants.State state = mCM.getState(subId);
1751             if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
1752                 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
1753                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1754                 mApp.startActivity(intent);
1755             }
1756         } finally {
1757             Binder.restoreCallingIdentity(identity);
1758         }
1759     }
1760 
call(String callingPackage, String number)1761     public void call(String callingPackage, String number) {
1762         callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
1763     }
1764 
callForSubscriber(int subId, String callingPackage, String number)1765     public void callForSubscriber(int subId, String callingPackage, String number) {
1766         if (DBG) log("call: " + number);
1767 
1768         // This is just a wrapper around the ACTION_CALL intent, but we still
1769         // need to do a permission check since we're calling startActivity()
1770         // from the context of the phone app.
1771         enforceCallPermission();
1772 
1773         if (mAppOps.noteOp(AppOpsManager.OPSTR_CALL_PHONE, Binder.getCallingUid(), callingPackage)
1774                 != AppOpsManager.MODE_ALLOWED) {
1775             return;
1776         }
1777 
1778         final long identity = Binder.clearCallingIdentity();
1779         try {
1780             String url = createTelUrl(number);
1781             if (url == null) {
1782                 return;
1783             }
1784 
1785             boolean isValid = false;
1786             final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
1787             if (slist != null) {
1788                 for (SubscriptionInfo subInfoRecord : slist) {
1789                     if (subInfoRecord.getSubscriptionId() == subId) {
1790                         isValid = true;
1791                         break;
1792                     }
1793                 }
1794             }
1795             if (!isValid) {
1796                 return;
1797             }
1798 
1799             Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
1800             intent.putExtra(SUBSCRIPTION_KEY, subId);
1801             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1802             mApp.startActivity(intent);
1803         } finally {
1804             Binder.restoreCallingIdentity(identity);
1805         }
1806     }
1807 
supplyPinForSubscriber(int subId, String pin)1808     public boolean supplyPinForSubscriber(int subId, String pin) {
1809         int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
1810         return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1811     }
1812 
supplyPukForSubscriber(int subId, String puk, String pin)1813     public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
1814         int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
1815         return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1816     }
1817 
supplyPinReportResultForSubscriber(int subId, String pin)1818     public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
1819         enforceModifyPermission();
1820 
1821         final long identity = Binder.clearCallingIdentity();
1822         try {
1823             final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
1824             checkSimPin.start();
1825             return checkSimPin.unlockSim(null, pin);
1826         } finally {
1827             Binder.restoreCallingIdentity(identity);
1828         }
1829     }
1830 
supplyPukReportResultForSubscriber(int subId, String puk, String pin)1831     public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
1832         enforceModifyPermission();
1833 
1834         final long identity = Binder.clearCallingIdentity();
1835         try {
1836             final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
1837             checkSimPuk.start();
1838             return checkSimPuk.unlockSim(puk, pin);
1839         } finally {
1840             Binder.restoreCallingIdentity(identity);
1841         }
1842     }
1843 
1844     /**
1845      * Helper thread to turn async call to SimCard#supplyPin into
1846      * a synchronous one.
1847      */
1848     private static class UnlockSim extends Thread {
1849 
1850         private final IccCard mSimCard;
1851 
1852         private boolean mDone = false;
1853         private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1854         private int mRetryCount = -1;
1855 
1856         // For replies from SimCard interface
1857         private Handler mHandler;
1858 
1859         // For async handler to identify request type
1860         private static final int SUPPLY_PIN_COMPLETE = 100;
1861 
UnlockSim(IccCard simCard)1862         public UnlockSim(IccCard simCard) {
1863             mSimCard = simCard;
1864         }
1865 
1866         @Override
run()1867         public void run() {
1868             Looper.prepare();
1869             synchronized (UnlockSim.this) {
1870                 mHandler = new Handler() {
1871                     @Override
1872                     public void handleMessage(Message msg) {
1873                         AsyncResult ar = (AsyncResult) msg.obj;
1874                         switch (msg.what) {
1875                             case SUPPLY_PIN_COMPLETE:
1876                                 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
1877                                 synchronized (UnlockSim.this) {
1878                                     mRetryCount = msg.arg1;
1879                                     if (ar.exception != null) {
1880                                         if (ar.exception instanceof CommandException &&
1881                                                 ((CommandException)(ar.exception)).getCommandError()
1882                                                 == CommandException.Error.PASSWORD_INCORRECT) {
1883                                             mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
1884                                         } else {
1885                                             mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1886                                         }
1887                                     } else {
1888                                         mResult = PhoneConstants.PIN_RESULT_SUCCESS;
1889                                     }
1890                                     mDone = true;
1891                                     UnlockSim.this.notifyAll();
1892                                 }
1893                                 break;
1894                         }
1895                     }
1896                 };
1897                 UnlockSim.this.notifyAll();
1898             }
1899             Looper.loop();
1900         }
1901 
1902         /*
1903          * Use PIN or PUK to unlock SIM card
1904          *
1905          * If PUK is null, unlock SIM card with PIN
1906          *
1907          * If PUK is not null, unlock SIM card with PUK and set PIN code
1908          */
unlockSim(String puk, String pin)1909         synchronized int[] unlockSim(String puk, String pin) {
1910 
1911             while (mHandler == null) {
1912                 try {
1913                     wait();
1914                 } catch (InterruptedException e) {
1915                     Thread.currentThread().interrupt();
1916                 }
1917             }
1918             Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
1919 
1920             if (puk == null) {
1921                 mSimCard.supplyPin(pin, callback);
1922             } else {
1923                 mSimCard.supplyPuk(puk, pin, callback);
1924             }
1925 
1926             while (!mDone) {
1927                 try {
1928                     Log.d(LOG_TAG, "wait for done");
1929                     wait();
1930                 } catch (InterruptedException e) {
1931                     // Restore the interrupted status
1932                     Thread.currentThread().interrupt();
1933                 }
1934             }
1935             Log.d(LOG_TAG, "done");
1936             int[] resultArray = new int[2];
1937             resultArray[0] = mResult;
1938             resultArray[1] = mRetryCount;
1939             return resultArray;
1940         }
1941     }
1942 
updateServiceLocation()1943     public void updateServiceLocation() {
1944         updateServiceLocationForSubscriber(getDefaultSubscription());
1945 
1946     }
1947 
updateServiceLocationForSubscriber(int subId)1948     public void updateServiceLocationForSubscriber(int subId) {
1949         // No permission check needed here: this call is harmless, and it's
1950         // needed for the ServiceState.requestStateUpdate() call (which is
1951         // already intentionally exposed to 3rd parties.)
1952         final long identity = Binder.clearCallingIdentity();
1953         try {
1954             final Phone phone = getPhone(subId);
1955             if (phone != null) {
1956                 phone.updateServiceLocation();
1957             }
1958         } finally {
1959             Binder.restoreCallingIdentity(identity);
1960         }
1961     }
1962 
1963     @Deprecated
1964     @Override
isRadioOn(String callingPackage)1965     public boolean isRadioOn(String callingPackage) {
1966         return isRadioOnWithFeature(callingPackage, null);
1967     }
1968 
1969 
1970     @Override
isRadioOnWithFeature(String callingPackage, String callingFeatureId)1971     public boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId) {
1972         return isRadioOnForSubscriberWithFeature(getDefaultSubscription(), callingPackage,
1973                 callingFeatureId);
1974     }
1975 
1976     @Deprecated
1977     @Override
isRadioOnForSubscriber(int subId, String callingPackage)1978     public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
1979         return isRadioOnForSubscriberWithFeature(subId, callingPackage, null);
1980     }
1981 
1982     @Override
isRadioOnForSubscriberWithFeature(int subId, String callingPackage, String callingFeatureId)1983     public boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage,
1984             String callingFeatureId) {
1985         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1986                 mApp, subId, callingPackage, callingFeatureId, "isRadioOnForSubscriber")) {
1987             return false;
1988         }
1989 
1990         final long identity = Binder.clearCallingIdentity();
1991         try {
1992             return isRadioOnForSubscriber(subId);
1993         } finally {
1994             Binder.restoreCallingIdentity(identity);
1995         }
1996     }
1997 
isRadioOnForSubscriber(int subId)1998     private boolean isRadioOnForSubscriber(int subId) {
1999         final long identity = Binder.clearCallingIdentity();
2000         try {
2001             final Phone phone = getPhone(subId);
2002             if (phone != null) {
2003                 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
2004             } else {
2005                 return false;
2006             }
2007         } finally {
2008             Binder.restoreCallingIdentity(identity);
2009         }
2010     }
2011 
toggleRadioOnOff()2012     public void toggleRadioOnOff() {
2013         toggleRadioOnOffForSubscriber(getDefaultSubscription());
2014     }
2015 
toggleRadioOnOffForSubscriber(int subId)2016     public void toggleRadioOnOffForSubscriber(int subId) {
2017         enforceModifyPermission();
2018 
2019         final long identity = Binder.clearCallingIdentity();
2020         try {
2021             final Phone phone = getPhone(subId);
2022             if (phone != null) {
2023                 phone.setRadioPower(!isRadioOnForSubscriber(subId));
2024             }
2025         } finally {
2026             Binder.restoreCallingIdentity(identity);
2027         }
2028     }
2029 
setRadio(boolean turnOn)2030     public boolean setRadio(boolean turnOn) {
2031         return setRadioForSubscriber(getDefaultSubscription(), turnOn);
2032     }
2033 
setRadioForSubscriber(int subId, boolean turnOn)2034     public boolean setRadioForSubscriber(int subId, boolean turnOn) {
2035         enforceModifyPermission();
2036 
2037         final long identity = Binder.clearCallingIdentity();
2038         try {
2039             final Phone phone = getPhone(subId);
2040             if (phone == null) {
2041                 return false;
2042             }
2043             if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
2044                 toggleRadioOnOffForSubscriber(subId);
2045             }
2046             return true;
2047         } finally {
2048             Binder.restoreCallingIdentity(identity);
2049         }
2050     }
2051 
needMobileRadioShutdown()2052     public boolean needMobileRadioShutdown() {
2053         enforceReadPrivilegedPermission("needMobileRadioShutdown");
2054         /*
2055          * If any of the Radios are available, it will need to be
2056          * shutdown. So return true if any Radio is available.
2057          */
2058         final long identity = Binder.clearCallingIdentity();
2059         try {
2060             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
2061                 Phone phone = PhoneFactory.getPhone(i);
2062                 if (phone != null && phone.isRadioAvailable()) return true;
2063             }
2064             logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
2065             return false;
2066         } finally {
2067             Binder.restoreCallingIdentity(identity);
2068         }
2069     }
2070 
2071     @Override
shutdownMobileRadios()2072     public void shutdownMobileRadios() {
2073         enforceModifyPermission();
2074 
2075         final long identity = Binder.clearCallingIdentity();
2076         try {
2077             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
2078                 logv("Shutting down Phone " + i);
2079                 shutdownRadioUsingPhoneId(i);
2080             }
2081         } finally {
2082             Binder.restoreCallingIdentity(identity);
2083         }
2084     }
2085 
shutdownRadioUsingPhoneId(int phoneId)2086     private void shutdownRadioUsingPhoneId(int phoneId) {
2087         Phone phone = PhoneFactory.getPhone(phoneId);
2088         if (phone != null && phone.isRadioAvailable()) {
2089             phone.shutdownRadio();
2090         }
2091     }
2092 
setRadioPower(boolean turnOn)2093     public boolean setRadioPower(boolean turnOn) {
2094         enforceModifyPermission();
2095 
2096         final long identity = Binder.clearCallingIdentity();
2097         try {
2098             final Phone defaultPhone = PhoneFactory.getDefaultPhone();
2099             if (defaultPhone != null) {
2100                 defaultPhone.setRadioPower(turnOn);
2101                 return true;
2102             } else {
2103                 loge("There's no default phone.");
2104                 return false;
2105             }
2106         } finally {
2107             Binder.restoreCallingIdentity(identity);
2108         }
2109     }
2110 
setRadioPowerForSubscriber(int subId, boolean turnOn)2111     public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
2112         enforceModifyPermission();
2113 
2114         final long identity = Binder.clearCallingIdentity();
2115         try {
2116             final Phone phone = getPhone(subId);
2117             if (phone != null) {
2118                 phone.setRadioPower(turnOn);
2119                 return true;
2120             } else {
2121                 return false;
2122             }
2123         } finally {
2124             Binder.restoreCallingIdentity(identity);
2125         }
2126     }
2127 
2128     // FIXME: subId version needed
2129     @Override
enableDataConnectivity()2130     public boolean enableDataConnectivity() {
2131         enforceModifyPermission();
2132 
2133         final long identity = Binder.clearCallingIdentity();
2134         try {
2135             int subId = mSubscriptionController.getDefaultDataSubId();
2136             final Phone phone = getPhone(subId);
2137             if (phone != null) {
2138                 phone.getDataEnabledSettings().setUserDataEnabled(true);
2139                 return true;
2140             } else {
2141                 return false;
2142             }
2143         } finally {
2144             Binder.restoreCallingIdentity(identity);
2145         }
2146     }
2147 
2148     // FIXME: subId version needed
2149     @Override
disableDataConnectivity()2150     public boolean disableDataConnectivity() {
2151         enforceModifyPermission();
2152 
2153         final long identity = Binder.clearCallingIdentity();
2154         try {
2155             int subId = mSubscriptionController.getDefaultDataSubId();
2156             final Phone phone = getPhone(subId);
2157             if (phone != null) {
2158                 phone.getDataEnabledSettings().setUserDataEnabled(false);
2159                 return true;
2160             } else {
2161                 return false;
2162             }
2163         } finally {
2164             Binder.restoreCallingIdentity(identity);
2165         }
2166     }
2167 
2168     @Override
isDataConnectivityPossible(int subId)2169     public boolean isDataConnectivityPossible(int subId) {
2170         final long identity = Binder.clearCallingIdentity();
2171         try {
2172             final Phone phone = getPhone(subId);
2173             if (phone != null) {
2174                 return phone.isDataAllowed(ApnSetting.TYPE_DEFAULT);
2175             } else {
2176                 return false;
2177             }
2178         } finally {
2179             Binder.restoreCallingIdentity(identity);
2180         }
2181     }
2182 
handlePinMmi(String dialString)2183     public boolean handlePinMmi(String dialString) {
2184         return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
2185     }
2186 
handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback)2187     public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
2188         enforceCallPermission();
2189 
2190         final long identity = Binder.clearCallingIdentity();
2191         try {
2192             if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2193                 return;
2194             }
2195             Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
2196             sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
2197         } finally {
2198             Binder.restoreCallingIdentity(identity);
2199         }
2200     };
2201 
handlePinMmiForSubscriber(int subId, String dialString)2202     public boolean handlePinMmiForSubscriber(int subId, String dialString) {
2203         enforceModifyPermission();
2204 
2205         final long identity = Binder.clearCallingIdentity();
2206         try {
2207             if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2208                 return false;
2209             }
2210             return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
2211         } finally {
2212             Binder.restoreCallingIdentity(identity);
2213         }
2214     }
2215 
getCallState()2216     public int getCallState() {
2217         return getCallStateForSlot(getSlotForDefaultSubscription());
2218     }
2219 
getCallStateForSlot(int slotIndex)2220     public int getCallStateForSlot(int slotIndex) {
2221         final long identity = Binder.clearCallingIdentity();
2222         try {
2223             Phone phone = PhoneFactory.getPhone(slotIndex);
2224             return phone == null ? TelephonyManager.CALL_STATE_IDLE :
2225                     PhoneConstantConversions.convertCallState(phone.getState());
2226         } finally {
2227             Binder.restoreCallingIdentity(identity);
2228         }
2229     }
2230 
2231     @Override
getDataState()2232     public int getDataState() {
2233         return getDataStateForSubId(mSubscriptionController.getDefaultDataSubId());
2234     }
2235 
2236     @Override
getDataStateForSubId(int subId)2237     public int getDataStateForSubId(int subId) {
2238         final long identity = Binder.clearCallingIdentity();
2239         try {
2240             final Phone phone = getPhone(subId);
2241             if (phone != null) {
2242                 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
2243             } else {
2244                 return PhoneConstantConversions.convertDataState(
2245                         PhoneConstants.DataState.DISCONNECTED);
2246             }
2247         } finally {
2248             Binder.restoreCallingIdentity(identity);
2249         }
2250     }
2251 
2252     @Override
getDataActivity()2253     public int getDataActivity() {
2254         return getDataActivityForSubId(mSubscriptionController.getDefaultDataSubId());
2255     }
2256 
2257     @Override
getDataActivityForSubId(int subId)2258     public int getDataActivityForSubId(int subId) {
2259         final long identity = Binder.clearCallingIdentity();
2260         try {
2261             final Phone phone = getPhone(subId);
2262             if (phone != null) {
2263                 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
2264             } else {
2265                 return TelephonyManager.DATA_ACTIVITY_NONE;
2266             }
2267         } finally {
2268             Binder.restoreCallingIdentity(identity);
2269         }
2270     }
2271 
2272     @Override
getCellLocation(String callingPackage, String callingFeatureId)2273     public CellIdentity getCellLocation(String callingPackage, String callingFeatureId) {
2274         mApp.getSystemService(AppOpsManager.class)
2275                 .checkPackage(Binder.getCallingUid(), callingPackage);
2276 
2277         LocationAccessPolicy.LocationPermissionResult locationResult =
2278                 LocationAccessPolicy.checkLocationPermission(mApp,
2279                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
2280                                 .setCallingPackage(callingPackage)
2281                                 .setCallingFeatureId(callingFeatureId)
2282                                 .setCallingPid(Binder.getCallingPid())
2283                                 .setCallingUid(Binder.getCallingUid())
2284                                 .setMethod("getCellLocation")
2285                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2286                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2287                                 .build());
2288         switch (locationResult) {
2289             case DENIED_HARD:
2290                 throw new SecurityException("Not allowed to access cell location");
2291             case DENIED_SOFT:
2292                 return (getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
2293                         ? new CellIdentityCdma() : new CellIdentityGsm();
2294         }
2295 
2296         WorkSource workSource = getWorkSource(Binder.getCallingUid());
2297         final long identity = Binder.clearCallingIdentity();
2298         try {
2299             if (DBG_LOC) log("getCellLocation: is active user");
2300             int subId = mSubscriptionController.getDefaultDataSubId();
2301             return (CellIdentity) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
2302         } finally {
2303             Binder.restoreCallingIdentity(identity);
2304         }
2305     }
2306 
2307     @Override
getNetworkCountryIsoForPhone(int phoneId)2308     public String getNetworkCountryIsoForPhone(int phoneId) {
2309         // Reporting the correct network country is ambiguous when IWLAN could conflict with
2310         // registered cell info, so return a NULL country instead.
2311         final long identity = Binder.clearCallingIdentity();
2312         try {
2313             if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
2314                 // Get default phone in this case.
2315                 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
2316             }
2317             final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
2318             Phone phone = PhoneFactory.getPhone(phoneId);
2319             if (phone == null) return "";
2320             ServiceStateTracker sst = phone.getServiceStateTracker();
2321             if (sst == null) return "";
2322             LocaleTracker lt = sst.getLocaleTracker();
2323             if (lt == null) return "";
2324             if (!TextUtils.isEmpty(lt.getCurrentCountry())) return lt.getCurrentCountry();
2325             EmergencyNumberTracker ent = phone.getEmergencyNumberTracker();
2326             return (ent == null) ? "" : ent.getEmergencyCountryIso();
2327         } finally {
2328             Binder.restoreCallingIdentity(identity);
2329         }
2330     }
2331 
2332     @Override
enableLocationUpdates()2333     public void enableLocationUpdates() {
2334         enableLocationUpdatesForSubscriber(getDefaultSubscription());
2335     }
2336 
2337     @Override
enableLocationUpdatesForSubscriber(int subId)2338     public void enableLocationUpdatesForSubscriber(int subId) {
2339         mApp.enforceCallingOrSelfPermission(
2340                 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
2341 
2342         final long identity = Binder.clearCallingIdentity();
2343         try {
2344             final Phone phone = getPhone(subId);
2345             if (phone != null) {
2346                 phone.enableLocationUpdates();
2347             }
2348         } finally {
2349             Binder.restoreCallingIdentity(identity);
2350         }
2351     }
2352 
2353     @Override
disableLocationUpdates()2354     public void disableLocationUpdates() {
2355         disableLocationUpdatesForSubscriber(getDefaultSubscription());
2356     }
2357 
2358     @Override
disableLocationUpdatesForSubscriber(int subId)2359     public void disableLocationUpdatesForSubscriber(int subId) {
2360         mApp.enforceCallingOrSelfPermission(
2361                 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
2362 
2363         final long identity = Binder.clearCallingIdentity();
2364         try {
2365             final Phone phone = getPhone(subId);
2366             if (phone != null) {
2367                 phone.disableLocationUpdates();
2368             }
2369         } finally {
2370             Binder.restoreCallingIdentity(identity);
2371         }
2372     }
2373 
2374     /**
2375      * Returns the target SDK version number for a given package name.
2376      *
2377      * This call MUST be invoked before clearing the calling UID.
2378      *
2379      * @return target SDK if the package is found or INT_MAX.
2380      */
getTargetSdk(String packageName)2381     private int getTargetSdk(String packageName) {
2382         try {
2383             final ApplicationInfo ai = mApp.getPackageManager().getApplicationInfoAsUser(
2384                     packageName, 0, UserHandle.getUserHandleForUid(Binder.getCallingUid()));
2385             if (ai != null) return ai.targetSdkVersion;
2386         } catch (PackageManager.NameNotFoundException unexpected) {
2387             loge("Failed to get package info for pkg="
2388                     + packageName + ", uid=" + Binder.getCallingUid());
2389         }
2390         return Integer.MAX_VALUE;
2391     }
2392 
2393     @Override
2394     @SuppressWarnings("unchecked")
getNeighboringCellInfo(String callingPackage, String callingFeatureId)2395     public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage,
2396             String callingFeatureId) {
2397         final int targetSdk = getTargetSdk(callingPackage);
2398         if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
2399             throw new SecurityException(
2400                     "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
2401         }
2402 
2403         if (mAppOps.noteOp(AppOpsManager.OPSTR_NEIGHBORING_CELLS, Binder.getCallingUid(),
2404                 callingPackage) != AppOpsManager.MODE_ALLOWED) {
2405             return null;
2406         }
2407 
2408         if (DBG_LOC) log("getNeighboringCellInfo: is active user");
2409 
2410         List<CellInfo> info = getAllCellInfo(callingPackage, callingFeatureId);
2411         if (info == null) return null;
2412 
2413         List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
2414         for (CellInfo ci : info) {
2415             if (ci instanceof CellInfoGsm) {
2416                 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
2417             } else if (ci instanceof CellInfoWcdma) {
2418                 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
2419             }
2420         }
2421         return (neighbors.size()) > 0 ? neighbors : null;
2422     }
2423 
getCachedCellInfo()2424     private List<CellInfo> getCachedCellInfo() {
2425         List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2426         for (Phone phone : PhoneFactory.getPhones()) {
2427             List<CellInfo> info = phone.getAllCellInfo();
2428             if (info != null) cellInfos.addAll(info);
2429         }
2430         return cellInfos;
2431     }
2432 
2433     @Override
getAllCellInfo(String callingPackage, String callingFeatureId)2434     public List<CellInfo> getAllCellInfo(String callingPackage, String callingFeatureId) {
2435         mApp.getSystemService(AppOpsManager.class)
2436                 .checkPackage(Binder.getCallingUid(), callingPackage);
2437 
2438         LocationAccessPolicy.LocationPermissionResult locationResult =
2439                 LocationAccessPolicy.checkLocationPermission(mApp,
2440                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
2441                                 .setCallingPackage(callingPackage)
2442                                 .setCallingFeatureId(callingFeatureId)
2443                                 .setCallingPid(Binder.getCallingPid())
2444                                 .setCallingUid(Binder.getCallingUid())
2445                                 .setMethod("getAllCellInfo")
2446                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2447                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2448                                 .build());
2449         switch (locationResult) {
2450             case DENIED_HARD:
2451                 throw new SecurityException("Not allowed to access cell info");
2452             case DENIED_SOFT:
2453                 return new ArrayList<>();
2454         }
2455 
2456         final int targetSdk = getTargetSdk(callingPackage);
2457         if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
2458             return getCachedCellInfo();
2459         }
2460 
2461         if (DBG_LOC) log("getAllCellInfo: is active user");
2462         WorkSource workSource = getWorkSource(Binder.getCallingUid());
2463         final long identity = Binder.clearCallingIdentity();
2464         try {
2465             List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2466             for (Phone phone : PhoneFactory.getPhones()) {
2467                 final List<CellInfo> info = (List<CellInfo>) sendRequest(
2468                         CMD_GET_ALL_CELL_INFO, null, phone, workSource);
2469                 if (info != null) cellInfos.addAll(info);
2470             }
2471             return cellInfos;
2472         } finally {
2473             Binder.restoreCallingIdentity(identity);
2474         }
2475     }
2476 
2477     @Override
requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage, String callingFeatureId)2478     public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage,
2479             String callingFeatureId) {
2480         requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId,
2481                 getWorkSource(Binder.getCallingUid()));
2482     }
2483 
2484     @Override
requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb, String callingPackage, String callingFeatureId, WorkSource workSource)2485     public void requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb,
2486             String callingPackage, String callingFeatureId, WorkSource workSource) {
2487         enforceModifyPermission();
2488         requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId, workSource);
2489     }
2490 
requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb, String callingPackage, String callingFeatureId, WorkSource workSource)2491     private void requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb,
2492             String callingPackage, String callingFeatureId, WorkSource workSource) {
2493         mApp.getSystemService(AppOpsManager.class)
2494                 .checkPackage(Binder.getCallingUid(), callingPackage);
2495 
2496         LocationAccessPolicy.LocationPermissionResult locationResult =
2497                 LocationAccessPolicy.checkLocationPermission(mApp,
2498                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
2499                                 .setCallingPackage(callingPackage)
2500                                 .setCallingFeatureId(callingFeatureId)
2501                                 .setCallingPid(Binder.getCallingPid())
2502                                 .setCallingUid(Binder.getCallingUid())
2503                                 .setMethod("requestCellInfoUpdate")
2504                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2505                                 .setMinSdkVersionForFine(Build.VERSION_CODES.BASE)
2506                                 .build());
2507         switch (locationResult) {
2508             case DENIED_HARD:
2509                 if (getTargetSdk(callingPackage) < Build.VERSION_CODES.Q) {
2510                     // Safetynet logging for b/154934934
2511                     EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
2512                 }
2513                 throw new SecurityException("Not allowed to access cell info");
2514             case DENIED_SOFT:
2515                 if (getTargetSdk(callingPackage) < Build.VERSION_CODES.Q) {
2516                     // Safetynet logging for b/154934934
2517                     EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
2518                 }
2519                 try {
2520                     cb.onCellInfo(new ArrayList<CellInfo>());
2521                 } catch (RemoteException re) {
2522                     // Drop without consequences
2523                 }
2524                 return;
2525         }
2526 
2527 
2528         final Phone phone = getPhoneFromSubId(subId);
2529         if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
2530 
2531         sendRequestAsync(CMD_REQUEST_CELL_INFO_UPDATE, cb, phone, workSource);
2532     }
2533 
2534     @Override
setCellInfoListRate(int rateInMillis)2535     public void setCellInfoListRate(int rateInMillis) {
2536         enforceModifyPermission();
2537         WorkSource workSource = getWorkSource(Binder.getCallingUid());
2538 
2539         final long identity = Binder.clearCallingIdentity();
2540         try {
2541             getDefaultPhone().setCellInfoListRate(rateInMillis, workSource);
2542         } finally {
2543             Binder.restoreCallingIdentity(identity);
2544         }
2545     }
2546 
2547     @Override
getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId)2548     public String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
2549         Phone phone = PhoneFactory.getPhone(slotIndex);
2550         if (phone == null) {
2551             return null;
2552         }
2553         int subId = phone.getSubId();
2554         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
2555                 callingPackage, callingFeatureId, "getImeiForSlot")) {
2556             return null;
2557         }
2558 
2559         final long identity = Binder.clearCallingIdentity();
2560         try {
2561             return phone.getImei();
2562         } finally {
2563             Binder.restoreCallingIdentity(identity);
2564         }
2565     }
2566 
2567     @Override
getTypeAllocationCodeForSlot(int slotIndex)2568     public String getTypeAllocationCodeForSlot(int slotIndex) {
2569         Phone phone = PhoneFactory.getPhone(slotIndex);
2570         String tac = null;
2571         if (phone != null) {
2572             String imei = phone.getImei();
2573             tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
2574         }
2575         return tac;
2576     }
2577 
2578     @Override
getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId)2579     public String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
2580         Phone phone = PhoneFactory.getPhone(slotIndex);
2581         if (phone == null) {
2582             return null;
2583         }
2584 
2585         int subId = phone.getSubId();
2586         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
2587                 callingPackage, callingFeatureId, "getMeidForSlot")) {
2588             return null;
2589         }
2590 
2591         final long identity = Binder.clearCallingIdentity();
2592         try {
2593             return phone.getMeid();
2594         } finally {
2595             Binder.restoreCallingIdentity(identity);
2596         }
2597     }
2598 
2599     @Override
getManufacturerCodeForSlot(int slotIndex)2600     public String getManufacturerCodeForSlot(int slotIndex) {
2601         Phone phone = PhoneFactory.getPhone(slotIndex);
2602         String manufacturerCode = null;
2603         if (phone != null) {
2604             String meid = phone.getMeid();
2605             manufacturerCode = meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
2606         }
2607         return manufacturerCode;
2608     }
2609 
2610     @Override
getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage, String callingFeatureId)2611     public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage,
2612             String callingFeatureId) {
2613         Phone phone = PhoneFactory.getPhone(slotIndex);
2614         if (phone == null) {
2615             return null;
2616         }
2617         int subId = phone.getSubId();
2618         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2619                 mApp, subId, callingPackage, callingFeatureId,
2620                 "getDeviceSoftwareVersionForSlot")) {
2621             return null;
2622         }
2623 
2624         final long identity = Binder.clearCallingIdentity();
2625         try {
2626             return phone.getDeviceSvn();
2627         } finally {
2628             Binder.restoreCallingIdentity(identity);
2629         }
2630     }
2631 
2632     @Override
getSubscriptionCarrierId(int subId)2633     public int getSubscriptionCarrierId(int subId) {
2634         final long identity = Binder.clearCallingIdentity();
2635         try {
2636             final Phone phone = getPhone(subId);
2637             return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
2638         } finally {
2639             Binder.restoreCallingIdentity(identity);
2640         }
2641     }
2642 
2643     @Override
getSubscriptionCarrierName(int subId)2644     public String getSubscriptionCarrierName(int subId) {
2645         final long identity = Binder.clearCallingIdentity();
2646         try {
2647             final Phone phone = getPhone(subId);
2648             return phone == null ? null : phone.getCarrierName();
2649         } finally {
2650             Binder.restoreCallingIdentity(identity);
2651         }
2652     }
2653 
2654     @Override
getSubscriptionSpecificCarrierId(int subId)2655     public int getSubscriptionSpecificCarrierId(int subId) {
2656         final long identity = Binder.clearCallingIdentity();
2657         try {
2658             final Phone phone = getPhone(subId);
2659             return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
2660                     : phone.getSpecificCarrierId();
2661         } finally {
2662             Binder.restoreCallingIdentity(identity);
2663         }
2664     }
2665 
2666     @Override
getSubscriptionSpecificCarrierName(int subId)2667     public String getSubscriptionSpecificCarrierName(int subId) {
2668         final long identity = Binder.clearCallingIdentity();
2669         try {
2670             final Phone phone = getPhone(subId);
2671             return phone == null ? null : phone.getSpecificCarrierName();
2672         } finally {
2673             Binder.restoreCallingIdentity(identity);
2674         }
2675     }
2676 
2677     @Override
getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc)2678     public int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc) {
2679         if (!isSubscriptionMccMnc) {
2680             enforceReadPrivilegedPermission("getCarrierIdFromMccMnc");
2681         }
2682         final Phone phone = PhoneFactory.getPhone(slotIndex);
2683         if (phone == null) {
2684             return TelephonyManager.UNKNOWN_CARRIER_ID;
2685         }
2686         final long identity = Binder.clearCallingIdentity();
2687         try {
2688             return CarrierResolver.getCarrierIdFromMccMnc(phone.getContext(), mccmnc);
2689         } finally {
2690             Binder.restoreCallingIdentity(identity);
2691         }
2692     }
2693 
2694     //
2695     // Internal helper methods.
2696     //
2697 
2698     /**
2699      * Make sure the caller has the MODIFY_PHONE_STATE permission.
2700      *
2701      * @throws SecurityException if the caller does not have the required permission
2702      */
enforceModifyPermission()2703     private void enforceModifyPermission() {
2704         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
2705     }
2706 
2707     /**
2708      * Make sure the caller is system.
2709      *
2710      * @throws SecurityException if the caller is not system.
2711      */
enforceSystemCaller()2712     private void enforceSystemCaller() {
2713         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
2714             throw new SecurityException("Caller must be system");
2715         }
2716     }
2717 
enforceActiveEmergencySessionPermission()2718     private void enforceActiveEmergencySessionPermission() {
2719         mApp.enforceCallingOrSelfPermission(
2720                 android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
2721     }
2722 
2723     /**
2724      * Make sure the caller has the CALL_PHONE permission.
2725      *
2726      * @throws SecurityException if the caller does not have the required permission
2727      */
enforceCallPermission()2728     private void enforceCallPermission() {
2729         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
2730     }
2731 
enforceSettingsPermission()2732     private void enforceSettingsPermission() {
2733         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS, null);
2734     }
2735 
createTelUrl(String number)2736     private String createTelUrl(String number) {
2737         if (TextUtils.isEmpty(number)) {
2738             return null;
2739         }
2740 
2741         return "tel:" + number;
2742     }
2743 
log(String msg)2744     private static void log(String msg) {
2745         Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
2746     }
2747 
logv(String msg)2748     private static void logv(String msg) {
2749         Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
2750     }
2751 
loge(String msg)2752     private static void loge(String msg) {
2753         Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
2754     }
2755 
2756     @Override
getActivePhoneType()2757     public int getActivePhoneType() {
2758         return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
2759     }
2760 
2761     @Override
getActivePhoneTypeForSlot(int slotIndex)2762     public int getActivePhoneTypeForSlot(int slotIndex) {
2763         final long identity = Binder.clearCallingIdentity();
2764         try {
2765             final Phone phone = PhoneFactory.getPhone(slotIndex);
2766             if (phone == null) {
2767                 return PhoneConstants.PHONE_TYPE_NONE;
2768             } else {
2769                 return phone.getPhoneType();
2770             }
2771         } finally {
2772             Binder.restoreCallingIdentity(identity);
2773         }
2774     }
2775 
2776     /**
2777      * Returns the CDMA ERI icon index to display
2778      */
2779     @Override
getCdmaEriIconIndex(String callingPackage, String callingFeatureId)2780     public int getCdmaEriIconIndex(String callingPackage, String callingFeatureId) {
2781         return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage,
2782                 callingFeatureId);
2783     }
2784 
2785     @Override
getCdmaEriIconIndexForSubscriber(int subId, String callingPackage, String callingFeatureId)2786     public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
2787             String callingFeatureId) {
2788         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2789                 mApp, subId, callingPackage, callingFeatureId,
2790                 "getCdmaEriIconIndexForSubscriber")) {
2791             return -1;
2792         }
2793 
2794         final long identity = Binder.clearCallingIdentity();
2795         try {
2796             final Phone phone = getPhone(subId);
2797             if (phone != null) {
2798                 return phone.getCdmaEriIconIndex();
2799             } else {
2800                 return -1;
2801             }
2802         } finally {
2803             Binder.restoreCallingIdentity(identity);
2804         }
2805     }
2806 
2807     /**
2808      * Returns the CDMA ERI icon mode,
2809      * 0 - ON
2810      * 1 - FLASHING
2811      */
2812     @Override
getCdmaEriIconMode(String callingPackage, String callingFeatureId)2813     public int getCdmaEriIconMode(String callingPackage, String callingFeatureId) {
2814         return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage,
2815                 callingFeatureId);
2816     }
2817 
2818     @Override
getCdmaEriIconModeForSubscriber(int subId, String callingPackage, String callingFeatureId)2819     public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
2820             String callingFeatureId) {
2821         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2822                 mApp, subId, callingPackage, callingFeatureId,
2823                 "getCdmaEriIconModeForSubscriber")) {
2824             return -1;
2825         }
2826 
2827         final long identity = Binder.clearCallingIdentity();
2828         try {
2829             final Phone phone = getPhone(subId);
2830             if (phone != null) {
2831                 return phone.getCdmaEriIconMode();
2832             } else {
2833                 return -1;
2834             }
2835         } finally {
2836             Binder.restoreCallingIdentity(identity);
2837         }
2838     }
2839 
2840     /**
2841      * Returns the CDMA ERI text,
2842      */
2843     @Override
getCdmaEriText(String callingPackage, String callingFeatureId)2844     public String getCdmaEriText(String callingPackage, String callingFeatureId) {
2845         return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage,
2846                 callingFeatureId);
2847     }
2848 
2849     @Override
getCdmaEriTextForSubscriber(int subId, String callingPackage, String callingFeatureId)2850     public String getCdmaEriTextForSubscriber(int subId, String callingPackage,
2851             String callingFeatureId) {
2852         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2853                 mApp, subId, callingPackage, callingFeatureId,
2854                 "getCdmaEriIconTextForSubscriber")) {
2855             return null;
2856         }
2857 
2858         final long identity = Binder.clearCallingIdentity();
2859         try {
2860             final Phone phone = getPhone(subId);
2861             if (phone != null) {
2862                 return phone.getCdmaEriText();
2863             } else {
2864                 return null;
2865             }
2866         } finally {
2867             Binder.restoreCallingIdentity(identity);
2868         }
2869     }
2870 
2871     /**
2872      * Returns the CDMA MDN.
2873      */
2874     @Override
getCdmaMdn(int subId)2875     public String getCdmaMdn(int subId) {
2876         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2877                 mApp, subId, "getCdmaMdn");
2878 
2879         final long identity = Binder.clearCallingIdentity();
2880         try {
2881             final Phone phone = getPhone(subId);
2882             if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2883                 return phone.getLine1Number();
2884             } else {
2885                 loge("getCdmaMdn: no phone found. Invalid subId: " + subId);
2886                 return null;
2887             }
2888         } finally {
2889             Binder.restoreCallingIdentity(identity);
2890         }
2891     }
2892 
2893     /**
2894      * Returns the CDMA MIN.
2895      */
2896     @Override
getCdmaMin(int subId)2897     public String getCdmaMin(int subId) {
2898         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2899                 mApp, subId, "getCdmaMin");
2900 
2901         final long identity = Binder.clearCallingIdentity();
2902         try {
2903             final Phone phone = getPhone(subId);
2904             if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2905                 return phone.getCdmaMin();
2906             } else {
2907                 return null;
2908             }
2909         } finally {
2910             Binder.restoreCallingIdentity(identity);
2911         }
2912     }
2913 
2914     @Override
requestNumberVerification(PhoneNumberRange range, long timeoutMillis, INumberVerificationCallback callback, String callingPackage)2915     public void requestNumberVerification(PhoneNumberRange range, long timeoutMillis,
2916             INumberVerificationCallback callback, String callingPackage) {
2917         if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
2918                 != PERMISSION_GRANTED) {
2919             throw new SecurityException("Caller must hold the MODIFY_PHONE_STATE permission");
2920         }
2921         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2922 
2923         String authorizedPackage = NumberVerificationManager.getAuthorizedPackage(mApp);
2924         if (!TextUtils.equals(callingPackage, authorizedPackage)) {
2925             throw new SecurityException("Calling package must be configured in the device config");
2926         }
2927 
2928         if (range == null) {
2929             throw new NullPointerException("Range must be non-null");
2930         }
2931 
2932         timeoutMillis = Math.min(timeoutMillis,
2933                 TelephonyManager.getMaxNumberVerificationTimeoutMillis());
2934 
2935         NumberVerificationManager.getInstance().requestVerification(range, callback, timeoutMillis);
2936     }
2937 
2938     /**
2939      * Returns true if CDMA provisioning needs to run.
2940      */
needsOtaServiceProvisioning()2941     public boolean needsOtaServiceProvisioning() {
2942         final long identity = Binder.clearCallingIdentity();
2943         try {
2944             return getDefaultPhone().needsOtaServiceProvisioning();
2945         } finally {
2946             Binder.restoreCallingIdentity(identity);
2947         }
2948     }
2949 
2950     /**
2951      * Sets the voice mail number of a given subId.
2952      */
2953     @Override
setVoiceMailNumber(int subId, String alphaTag, String number)2954     public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
2955         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
2956                 mApp, subId, "setVoiceMailNumber");
2957 
2958         final long identity = Binder.clearCallingIdentity();
2959         try {
2960             Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
2961                     new Pair<String, String>(alphaTag, number), new Integer(subId));
2962             return success;
2963         } finally {
2964             Binder.restoreCallingIdentity(identity);
2965         }
2966     }
2967 
2968     @Override
getVisualVoicemailSettings(String callingPackage, int subId)2969     public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
2970         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2971         TelecomManager tm = mApp.getSystemService(TelecomManager.class);
2972         String systemDialer = tm.getSystemDialerPackage();
2973         if (!TextUtils.equals(callingPackage, systemDialer)) {
2974             throw new SecurityException("caller must be system dialer");
2975         }
2976 
2977         final long identity = Binder.clearCallingIdentity();
2978         try {
2979             PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
2980             if (phoneAccountHandle == null) {
2981                 return null;
2982             }
2983             return VisualVoicemailSettingsUtil.dump(mApp, phoneAccountHandle);
2984         } finally {
2985             Binder.restoreCallingIdentity(identity);
2986         }
2987     }
2988 
2989     @Override
getVisualVoicemailPackageName(String callingPackage, String callingFeatureId, int subId)2990     public String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId,
2991             int subId) {
2992         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2993         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2994                 mApp, subId, callingPackage, callingFeatureId,
2995                 "getVisualVoicemailPackageName")) {
2996             return null;
2997         }
2998 
2999         final long identity = Binder.clearCallingIdentity();
3000         try {
3001             return RemoteVvmTaskManager.getRemotePackage(mApp, subId).getPackageName();
3002         } finally {
3003             Binder.restoreCallingIdentity(identity);
3004         }
3005     }
3006 
3007     @Override
enableVisualVoicemailSmsFilter(String callingPackage, int subId, VisualVoicemailSmsFilterSettings settings)3008     public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
3009             VisualVoicemailSmsFilterSettings settings) {
3010         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3011 
3012         final long identity = Binder.clearCallingIdentity();
3013         try {
3014             VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
3015                     mApp, callingPackage, subId, settings);
3016         } finally {
3017             Binder.restoreCallingIdentity(identity);
3018         }
3019     }
3020 
3021     @Override
disableVisualVoicemailSmsFilter(String callingPackage, int subId)3022     public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
3023         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3024 
3025         final long identity = Binder.clearCallingIdentity();
3026         try {
3027             VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
3028                     mApp, callingPackage, subId);
3029         } finally {
3030             Binder.restoreCallingIdentity(identity);
3031         }
3032     }
3033 
3034     @Override
getVisualVoicemailSmsFilterSettings( String callingPackage, int subId)3035     public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
3036             String callingPackage, int subId) {
3037         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3038 
3039         final long identity = Binder.clearCallingIdentity();
3040         try {
3041             return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
3042                     mApp, callingPackage, subId);
3043         } finally {
3044             Binder.restoreCallingIdentity(identity);
3045         }
3046     }
3047 
3048     @Override
getActiveVisualVoicemailSmsFilterSettings(int subId)3049     public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
3050         enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
3051 
3052         final long identity = Binder.clearCallingIdentity();
3053         try {
3054             return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
3055                     mApp, subId);
3056         } finally {
3057             Binder.restoreCallingIdentity(identity);
3058         }
3059     }
3060 
3061     @Override
sendVisualVoicemailSmsForSubscriber(String callingPackage, String callingAttributionTag, int subId, String number, int port, String text, PendingIntent sentIntent)3062     public void sendVisualVoicemailSmsForSubscriber(String callingPackage,
3063             String callingAttributionTag, int subId, String number, int port, String text,
3064             PendingIntent sentIntent) {
3065         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3066         enforceVisualVoicemailPackage(callingPackage, subId);
3067         enforceSendSmsPermission();
3068         SmsController smsController = PhoneFactory.getSmsController();
3069         smsController.sendVisualVoicemailSmsForSubscriber(callingPackage, callingAttributionTag,
3070                 subId, number, port, text, sentIntent);
3071     }
3072 
3073     /**
3074      * Sets the voice activation state of a given subId.
3075      */
3076     @Override
setVoiceActivationState(int subId, int activationState)3077     public void setVoiceActivationState(int subId, int activationState) {
3078         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3079                 mApp, subId, "setVoiceActivationState");
3080 
3081         final long identity = Binder.clearCallingIdentity();
3082         try {
3083             final Phone phone = getPhone(subId);
3084             if (phone != null) {
3085                 phone.setVoiceActivationState(activationState);
3086             } else {
3087                 loge("setVoiceActivationState fails with invalid subId: " + subId);
3088             }
3089         } finally {
3090             Binder.restoreCallingIdentity(identity);
3091         }
3092     }
3093 
3094     /**
3095      * Sets the data activation state of a given subId.
3096      */
3097     @Override
setDataActivationState(int subId, int activationState)3098     public void setDataActivationState(int subId, int activationState) {
3099         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3100                 mApp, subId, "setDataActivationState");
3101 
3102         final long identity = Binder.clearCallingIdentity();
3103         try {
3104             final Phone phone = getPhone(subId);
3105             if (phone != null) {
3106                 phone.setDataActivationState(activationState);
3107             } else {
3108                 loge("setDataActivationState fails with invalid subId: " + subId);
3109             }
3110         } finally {
3111             Binder.restoreCallingIdentity(identity);
3112         }
3113     }
3114 
3115     /**
3116      * Returns the voice activation state of a given subId.
3117      */
3118     @Override
getVoiceActivationState(int subId, String callingPackage)3119     public int getVoiceActivationState(int subId, String callingPackage) {
3120         enforceReadPrivilegedPermission("getVoiceActivationState");
3121 
3122         final Phone phone = getPhone(subId);
3123         final long identity = Binder.clearCallingIdentity();
3124         try {
3125             if (phone != null) {
3126                 return phone.getVoiceActivationState();
3127             } else {
3128                 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
3129             }
3130         } finally {
3131             Binder.restoreCallingIdentity(identity);
3132         }
3133     }
3134 
3135     /**
3136      * Returns the data activation state of a given subId.
3137      */
3138     @Override
getDataActivationState(int subId, String callingPackage)3139     public int getDataActivationState(int subId, String callingPackage) {
3140         enforceReadPrivilegedPermission("getDataActivationState");
3141 
3142         final Phone phone = getPhone(subId);
3143         final long identity = Binder.clearCallingIdentity();
3144         try {
3145             if (phone != null) {
3146                 return phone.getDataActivationState();
3147             } else {
3148                 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
3149             }
3150         } finally {
3151             Binder.restoreCallingIdentity(identity);
3152         }
3153     }
3154 
3155     /**
3156      * Returns the unread count of voicemails for a subId
3157      */
3158     @Override
getVoiceMessageCountForSubscriber(int subId, String callingPackage, String callingFeatureId)3159     public int getVoiceMessageCountForSubscriber(int subId, String callingPackage,
3160             String callingFeatureId) {
3161         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3162                 mApp, subId, callingPackage, callingFeatureId,
3163                 "getVoiceMessageCountForSubscriber")) {
3164             return 0;
3165         }
3166         final long identity = Binder.clearCallingIdentity();
3167         try {
3168             final Phone phone = getPhone(subId);
3169             if (phone != null) {
3170                 return phone.getVoiceMessageCount();
3171             } else {
3172                 return 0;
3173             }
3174         } finally {
3175             Binder.restoreCallingIdentity(identity);
3176         }
3177     }
3178 
3179     /**
3180       * returns true, if the device is in a state where both voice and data
3181       * are supported simultaneously. This can change based on location or network condition.
3182      */
3183     @Override
isConcurrentVoiceAndDataAllowed(int subId)3184     public boolean isConcurrentVoiceAndDataAllowed(int subId) {
3185         final long identity = Binder.clearCallingIdentity();
3186         try {
3187             final Phone phone = getPhone(subId);
3188             return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
3189         } finally {
3190             Binder.restoreCallingIdentity(identity);
3191         }
3192     }
3193 
3194     /**
3195      * Send the dialer code if called from the current default dialer or the caller has
3196      * carrier privilege.
3197      * @param inputCode The dialer code to send
3198      */
3199     @Override
sendDialerSpecialCode(String callingPackage, String inputCode)3200     public void sendDialerSpecialCode(String callingPackage, String inputCode) {
3201         final Phone defaultPhone = getDefaultPhone();
3202         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3203         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
3204         String defaultDialer = tm.getDefaultDialerPackage();
3205         if (!TextUtils.equals(callingPackage, defaultDialer)) {
3206             TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
3207                     getDefaultSubscription(), "sendDialerSpecialCode");
3208         }
3209 
3210         final long identity = Binder.clearCallingIdentity();
3211         try {
3212             defaultPhone.sendDialerSpecialCode(inputCode);
3213         } finally {
3214             Binder.restoreCallingIdentity(identity);
3215         }
3216     }
3217 
3218     @Override
getNetworkSelectionMode(int subId)3219     public int getNetworkSelectionMode(int subId) {
3220         TelephonyPermissions
3221                     .enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3222                     mApp, subId, "getNetworkSelectionMode");
3223         final long identity = Binder.clearCallingIdentity();
3224         try {
3225             if (!isActiveSubscription(subId)) {
3226                 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
3227             }
3228             return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
3229         } finally {
3230             Binder.restoreCallingIdentity(identity);
3231         }
3232     }
3233 
3234     @Override
isInEmergencySmsMode()3235     public boolean isInEmergencySmsMode() {
3236         enforceReadPrivilegedPermission("isInEmergencySmsMode");
3237         final long identity = Binder.clearCallingIdentity();
3238         try {
3239             for (Phone phone : PhoneFactory.getPhones()) {
3240                 if (phone.isInEmergencySmsMode()) {
3241                     return true;
3242                 }
3243             }
3244         } finally {
3245             Binder.restoreCallingIdentity(identity);
3246         }
3247         return false;
3248     }
3249 
3250     /**
3251      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3252      * @param subId The subscription to use to check the configuration.
3253      * @param c The callback that will be used to send the result.
3254      */
3255     @Override
registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)3256     public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)
3257             throws RemoteException {
3258         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3259                 mApp, subId, "registerImsRegistrationCallback");
3260 
3261         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3262             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3263                     "IMS not available on device.");
3264         }
3265         final long token = Binder.clearCallingIdentity();
3266         try {
3267             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3268             ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3269                     .addRegistrationCallbackForSubscription(c, subId);
3270         } catch (ImsException e) {
3271             throw new ServiceSpecificException(e.getCode());
3272         } finally {
3273             Binder.restoreCallingIdentity(token);
3274         }
3275     }
3276 
3277     /**
3278      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3279      * @param subId The subscription to use to check the configuration.
3280      * @param c The callback that will be used to send the result.
3281      */
3282     @Override
unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c)3283     public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c) {
3284         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3285                 mApp, subId, "unregisterImsRegistrationCallback");
3286         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3287             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3288         }
3289         final long token = Binder.clearCallingIdentity();
3290         try {
3291             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
3292             ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3293                     .removeRegistrationCallbackForSubscription(c, subId);
3294         } catch (ImsException e) {
3295             Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
3296                     + "is inactive, ignoring unregister.");
3297             // If the subscription is no longer active, just return, since the callback
3298             // will already have been removed internally.
3299         } finally {
3300             Binder.restoreCallingIdentity(token);
3301         }
3302     }
3303 
3304     /**
3305      * Get the IMS service registration state for the MmTelFeature associated with this sub id.
3306      */
3307     @Override
getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer)3308     public void getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer) {
3309         enforceReadPrivilegedPermission("getImsMmTelRegistrationState");
3310         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3311             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3312                     "IMS not available on device.");
3313         }
3314         final long token = Binder.clearCallingIdentity();
3315         try {
3316             Phone phone = getPhone(subId);
3317             if (phone == null) {
3318                 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
3319                         + subId + "'");
3320                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3321             }
3322             phone.getImsRegistrationState(regState -> {
3323                 try {
3324                     consumer.accept((regState == null)
3325                             ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
3326                 } catch (RemoteException e) {
3327                     // Ignore if the remote process is no longer available to call back.
3328                     Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
3329                 }
3330             });
3331         } finally {
3332             Binder.restoreCallingIdentity(token);
3333         }
3334     }
3335 
3336     /**
3337      * Get the transport type for the IMS service registration state.
3338      */
3339     @Override
getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer)3340     public void getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer) {
3341         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3342                 mApp, subId, "getImsMmTelRegistrationTransportType");
3343         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3344             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3345                     "IMS not available on device.");
3346         }
3347         final long token = Binder.clearCallingIdentity();
3348         try {
3349             Phone phone = getPhone(subId);
3350             if (phone == null) {
3351                 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
3352                         + subId + "'");
3353                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3354             }
3355             phone.getImsRegistrationTech(regTech -> {
3356                 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
3357                 int regTechConverted = (regTech == null)
3358                         ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
3359                 regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
3360                         regTechConverted);
3361                 try {
3362                     consumer.accept(regTechConverted);
3363                 } catch (RemoteException e) {
3364                     // Ignore if the remote process is no longer available to call back.
3365                     Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
3366                 }
3367             });
3368         } finally {
3369             Binder.restoreCallingIdentity(token);
3370         }
3371     }
3372 
3373     /**
3374      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3375      * @param subId The subscription to use to check the configuration.
3376      * @param c The callback that will be used to send the result.
3377      */
3378     @Override
registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)3379     public void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)
3380             throws RemoteException {
3381         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3382                 mApp, subId, "registerMmTelCapabilityCallback");
3383         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3384             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3385                     "IMS not available on device.");
3386         }
3387         // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3388         final long token = Binder.clearCallingIdentity();
3389         try {
3390             ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3391                     .addCapabilitiesCallbackForSubscription(c, subId);
3392         } catch (ImsException e) {
3393             throw new ServiceSpecificException(e.getCode());
3394         } finally {
3395             Binder.restoreCallingIdentity(token);
3396         }
3397     }
3398 
3399     /**
3400      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3401      * @param subId The subscription to use to check the configuration.
3402      * @param c The callback that will be used to send the result.
3403      */
3404     @Override
unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)3405     public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
3406         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3407                 mApp, subId, "unregisterMmTelCapabilityCallback");
3408         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3409             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3410         }
3411 
3412         final long token = Binder.clearCallingIdentity();
3413         try {
3414             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
3415             ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3416                         .removeCapabilitiesCallbackForSubscription(c, subId);
3417         } catch (ImsException e) {
3418             Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
3419                      + "is inactive, ignoring unregister.");
3420              // If the subscription is no longer active, just return, since the callback
3421              // will already have been removed internally.
3422         } finally {
3423             Binder.restoreCallingIdentity(token);
3424         }
3425     }
3426 
3427     @Override
isCapable(int subId, int capability, int regTech)3428     public boolean isCapable(int subId, int capability, int regTech) {
3429         enforceReadPrivilegedPermission("isCapable");
3430         // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3431         final long token = Binder.clearCallingIdentity();
3432         try {
3433             return ImsManager.getInstance(mApp,
3434                     getSlotIndexOrException(subId)).queryMmTelCapability(capability, regTech);
3435         } catch (com.android.ims.ImsException e) {
3436             Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
3437             return false;
3438         } catch (ImsException e) {
3439             Log.i(LOG_TAG, "isCapable: " + subId + " is inactive, returning false.");
3440             return false;
3441         } finally {
3442             Binder.restoreCallingIdentity(token);
3443         }
3444     }
3445 
3446     @Override
isAvailable(int subId, int capability, int regTech)3447     public boolean isAvailable(int subId, int capability, int regTech) {
3448         enforceReadPrivilegedPermission("isAvailable");
3449         final long token = Binder.clearCallingIdentity();
3450         try {
3451             Phone phone = getPhone(subId);
3452             if (phone == null) return false;
3453             return phone.isImsCapabilityAvailable(capability, regTech);
3454         } catch (com.android.ims.ImsException e) {
3455             Log.w(LOG_TAG, "IMS isAvailable - service unavailable: " + e.getMessage());
3456             return false;
3457         } finally {
3458             Binder.restoreCallingIdentity(token);
3459         }
3460     }
3461 
3462     /**
3463      * Determines if the MmTel feature capability is supported by the carrier configuration for this
3464      * subscription.
3465      * @param subId The subscription to use to check the configuration.
3466      * @param callback The callback that will be used to send the result.
3467      * @param capability The MmTelFeature capability that will be used to send the result.
3468      * @param transportType The transport type of the MmTelFeature capability.
3469      */
3470     @Override
isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability, int transportType)3471     public void isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability,
3472             int transportType) {
3473         enforceReadPrivilegedPermission("isMmTelCapabilitySupported");
3474         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3475             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3476                     "IMS not available on device.");
3477         }
3478         final long token = Binder.clearCallingIdentity();
3479         try {
3480             int slotId = getSlotIndex(subId);
3481             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3482                 Log.w(LOG_TAG, "isMmTelCapabilitySupported: called with an inactive subscription '"
3483                         + subId + "'");
3484                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3485             }
3486             ImsManager.getInstance(mApp, slotId).isSupported(capability,
3487                     transportType, aBoolean -> {
3488                         try {
3489                             callback.accept((aBoolean == null) ? 0 : (aBoolean ? 1 : 0));
3490                         } catch (RemoteException e) {
3491                             Log.w(LOG_TAG, "isMmTelCapabilitySupported: remote caller is not "
3492                                     + "running. Ignore");
3493                         }
3494                     });
3495         } finally {
3496             Binder.restoreCallingIdentity(token);
3497         }
3498     }
3499 
3500     /**
3501      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3502      * @param subId The subscription to use to check the configuration.
3503      */
3504     @Override
isAdvancedCallingSettingEnabled(int subId)3505     public boolean isAdvancedCallingSettingEnabled(int subId) {
3506         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3507                 mApp, subId, "isAdvancedCallingSettingEnabled");
3508 
3509         // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3510         final long token = Binder.clearCallingIdentity();
3511         try {
3512             return ImsManager.getInstance(mApp,
3513                     getSlotIndexOrException(subId)).isEnhanced4gLteModeSettingEnabledByUser();
3514         } catch (ImsException e) {
3515             throw new ServiceSpecificException(e.getCode());
3516         } finally {
3517             Binder.restoreCallingIdentity(token);
3518         }
3519     }
3520 
3521     @Override
setAdvancedCallingSettingEnabled(int subId, boolean isEnabled)3522     public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
3523         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3524                 "setAdvancedCallingSettingEnabled");
3525         final long identity = Binder.clearCallingIdentity();
3526         try {
3527             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3528             ImsManager.getInstance(mApp,
3529                     getSlotIndexOrException(subId)).setEnhanced4gLteModeSetting(isEnabled);
3530         } catch (ImsException e) {
3531             throw new ServiceSpecificException(e.getCode());
3532         } finally {
3533             Binder.restoreCallingIdentity(identity);
3534         }
3535     }
3536 
3537     /**
3538      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3539      * @param subId The subscription to use to check the configuration.
3540      */
3541     @Override
isVtSettingEnabled(int subId)3542     public boolean isVtSettingEnabled(int subId) {
3543         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3544                 mApp, subId, "isVtSettingEnabled");
3545         final long identity = Binder.clearCallingIdentity();
3546         try {
3547             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3548             return ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).isVtEnabledByUser();
3549         } catch (ImsException e) {
3550             throw new ServiceSpecificException(e.getCode());
3551         } finally {
3552             Binder.restoreCallingIdentity(identity);
3553         }
3554     }
3555 
3556     @Override
setVtSettingEnabled(int subId, boolean isEnabled)3557     public void setVtSettingEnabled(int subId, boolean isEnabled) {
3558         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3559                 "setVtSettingEnabled");
3560         final long identity = Binder.clearCallingIdentity();
3561         try {
3562             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3563             ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setVtSetting(isEnabled);
3564         } catch (ImsException e) {
3565             throw new ServiceSpecificException(e.getCode());
3566         } finally {
3567             Binder.restoreCallingIdentity(identity);
3568         }
3569     }
3570 
3571     /**
3572      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3573      * @param subId The subscription to use to check the configuration.
3574      */
3575     @Override
isVoWiFiSettingEnabled(int subId)3576     public boolean isVoWiFiSettingEnabled(int subId) {
3577         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3578                 mApp, subId, "isVoWiFiSettingEnabled");
3579         final long identity = Binder.clearCallingIdentity();
3580         try {
3581             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3582             return ImsManager.getInstance(mApp,
3583                     getSlotIndexOrException(subId)).isWfcEnabledByUser();
3584         } catch (ImsException e) {
3585             throw new ServiceSpecificException(e.getCode());
3586         } finally {
3587             Binder.restoreCallingIdentity(identity);
3588         }
3589     }
3590 
3591     @Override
setVoWiFiSettingEnabled(int subId, boolean isEnabled)3592     public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
3593         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3594                 "setVoWiFiSettingEnabled");
3595         final long identity = Binder.clearCallingIdentity();
3596         try {
3597             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3598             ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setWfcSetting(isEnabled);
3599         } catch (ImsException e) {
3600             throw new ServiceSpecificException(e.getCode());
3601         } finally {
3602             Binder.restoreCallingIdentity(identity);
3603         }
3604     }
3605 
3606     /**
3607      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3608      * @param subId The subscription to use to check the configuration.
3609      */
3610     @Override
isVoWiFiRoamingSettingEnabled(int subId)3611     public boolean isVoWiFiRoamingSettingEnabled(int subId) {
3612         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3613                 mApp, subId, "isVoWiFiRoamingSettingEnabled");
3614         final long identity = Binder.clearCallingIdentity();
3615         try {
3616             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3617             return ImsManager.getInstance(mApp,
3618                     getSlotIndexOrException(subId)).isWfcRoamingEnabledByUser();
3619         } catch (ImsException e) {
3620             throw new ServiceSpecificException(e.getCode());
3621         } finally {
3622             Binder.restoreCallingIdentity(identity);
3623         }
3624     }
3625 
3626     @Override
setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled)3627     public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
3628         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3629                 "setVoWiFiRoamingSettingEnabled");
3630         final long identity = Binder.clearCallingIdentity();
3631         try {
3632             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3633             ImsManager.getInstance(mApp,
3634                     getSlotIndexOrException(subId)).setWfcRoamingSetting(isEnabled);
3635         } catch (ImsException e) {
3636             throw new ServiceSpecificException(e.getCode());
3637         } finally {
3638             Binder.restoreCallingIdentity(identity);
3639         }
3640     }
3641 
3642     @Override
setVoWiFiNonPersistent(int subId, boolean isCapable, int mode)3643     public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
3644         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3645                 "setVoWiFiNonPersistent");
3646         final long identity = Binder.clearCallingIdentity();
3647         try {
3648             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3649             ImsManager.getInstance(mApp,
3650                     getSlotIndexOrException(subId)).setWfcNonPersistent(isCapable, mode);
3651         } catch (ImsException e) {
3652             throw new ServiceSpecificException(e.getCode());
3653         } finally {
3654             Binder.restoreCallingIdentity(identity);
3655         }
3656     }
3657 
3658     /**
3659      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3660      * @param subId The subscription to use to check the configuration.
3661      */
3662     @Override
getVoWiFiModeSetting(int subId)3663     public int getVoWiFiModeSetting(int subId) {
3664         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3665                 mApp, subId, "getVoWiFiModeSetting");
3666         final long identity = Binder.clearCallingIdentity();
3667         try {
3668             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3669             return ImsManager.getInstance(mApp,
3670                     getSlotIndexOrException(subId)).getWfcMode(false /*isRoaming*/);
3671         } catch (ImsException e) {
3672             throw new ServiceSpecificException(e.getCode());
3673         } finally {
3674             Binder.restoreCallingIdentity(identity);
3675         }
3676     }
3677 
3678     @Override
setVoWiFiModeSetting(int subId, int mode)3679     public void setVoWiFiModeSetting(int subId, int mode) {
3680         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3681                 "setVoWiFiModeSetting");
3682         final long identity = Binder.clearCallingIdentity();
3683         try {
3684             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3685             ImsManager.getInstance(mApp,
3686                     getSlotIndexOrException(subId)).setWfcMode(mode, false /*isRoaming*/);
3687         } catch (ImsException e) {
3688             throw new ServiceSpecificException(e.getCode());
3689         } finally {
3690             Binder.restoreCallingIdentity(identity);
3691         }
3692     }
3693 
3694     @Override
getVoWiFiRoamingModeSetting(int subId)3695     public int getVoWiFiRoamingModeSetting(int subId) {
3696         enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
3697         final long identity = Binder.clearCallingIdentity();
3698         try {
3699             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3700             return ImsManager.getInstance(mApp,
3701                     getSlotIndexOrException(subId)).getWfcMode(true /*isRoaming*/);
3702         } catch (ImsException e) {
3703             throw new ServiceSpecificException(e.getCode());
3704         } finally {
3705             Binder.restoreCallingIdentity(identity);
3706         }
3707     }
3708 
3709     @Override
setVoWiFiRoamingModeSetting(int subId, int mode)3710     public void setVoWiFiRoamingModeSetting(int subId, int mode) {
3711         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3712                 "setVoWiFiRoamingModeSetting");
3713         final long identity = Binder.clearCallingIdentity();
3714         try {
3715             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3716             ImsManager.getInstance(mApp,
3717                     getSlotIndexOrException(subId)).setWfcMode(mode, true /*isRoaming*/);
3718         } catch (ImsException e) {
3719             throw new ServiceSpecificException(e.getCode());
3720         } finally {
3721             Binder.restoreCallingIdentity(identity);
3722         }
3723     }
3724 
3725     @Override
setRttCapabilitySetting(int subId, boolean isEnabled)3726     public void setRttCapabilitySetting(int subId, boolean isEnabled) {
3727         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3728                 "setRttCapabilityEnabled");
3729         final long identity = Binder.clearCallingIdentity();
3730         try {
3731             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3732             ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setRttEnabled(isEnabled);
3733         } catch (ImsException e) {
3734             throw new ServiceSpecificException(e.getCode());
3735         } finally {
3736             Binder.restoreCallingIdentity(identity);
3737         }
3738     }
3739 
3740     /**
3741      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3742      * @param subId The subscription to use to check the configuration.
3743      */
3744     @Override
isTtyOverVolteEnabled(int subId)3745     public boolean isTtyOverVolteEnabled(int subId) {
3746         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3747                 mApp, subId, "isTtyOverVolteEnabled");
3748         final long identity = Binder.clearCallingIdentity();
3749         try {
3750             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3751             return ImsManager.getInstance(mApp,
3752                     getSlotIndexOrException(subId)).isTtyOnVoLteCapable();
3753         } catch (ImsException e) {
3754             throw new ServiceSpecificException(e.getCode());
3755         } finally {
3756             Binder.restoreCallingIdentity(identity);
3757         }
3758     }
3759 
3760     @Override
registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback)3761     public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
3762         enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
3763         final long identity = Binder.clearCallingIdentity();
3764         try {
3765             if (!isImsAvailableOnDevice()) {
3766                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3767                         "IMS not available on device.");
3768             }
3769             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3770             ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3771                     .addProvisioningCallbackForSubscription(callback, subId);
3772         } catch (ImsException e) {
3773             throw new ServiceSpecificException(e.getCode());
3774         } finally {
3775             Binder.restoreCallingIdentity(identity);
3776         }
3777     }
3778 
3779     @Override
unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback)3780     public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
3781         enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
3782         final long identity = Binder.clearCallingIdentity();
3783         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3784             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3785         }
3786         try {
3787             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3788             ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3789                     .removeProvisioningCallbackForSubscription(callback, subId);
3790         } catch (ImsException e) {
3791             Log.i(LOG_TAG, "unregisterImsProvisioningChangedCallback: " + subId
3792                     + "is inactive, ignoring unregister.");
3793             // If the subscription is no longer active, just return, since the callback will already
3794             // have been removed internally.
3795         } finally {
3796             Binder.restoreCallingIdentity(identity);
3797         }
3798     }
3799 
3800 
checkModifyPhoneStatePermission(int subId, String message)3801     private void checkModifyPhoneStatePermission(int subId, String message) {
3802         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3803                 message);
3804     }
3805 
isImsProvisioningRequired(int subId, int capability, boolean isMmtelCapability)3806     private boolean isImsProvisioningRequired(int subId, int capability,
3807             boolean isMmtelCapability) {
3808         Phone phone = getPhone(subId);
3809         if (phone == null) {
3810             loge("phone instance null for subid " + subId);
3811             return false;
3812         }
3813         if (isMmtelCapability) {
3814             if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
3815                 return false;
3816             }
3817         } else {
3818             if (!doesRcsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
3819                 return false;
3820             }
3821         }
3822         return true;
3823     }
3824 
3825     @Override
setRcsProvisioningStatusForCapability(int subId, int capability, boolean isProvisioned)3826     public void setRcsProvisioningStatusForCapability(int subId, int capability,
3827             boolean isProvisioned) {
3828         checkModifyPhoneStatePermission(subId, "setRcsProvisioningStatusForCapability");
3829 
3830         final long identity = Binder.clearCallingIdentity();
3831         try {
3832             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3833             if (!isImsProvisioningRequired(subId, capability, false)) {
3834                 return;
3835             }
3836 
3837             // this capability requires provisioning, route to the correct API.
3838             ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3839             switch (capability) {
3840                 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
3841                 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
3842                     ims.setEabProvisioned(isProvisioned);
3843                     break;
3844                 default: {
3845                     throw new IllegalArgumentException("Tried to set provisioning for "
3846                             + "rcs capability '" + capability + "', which does not require "
3847                             + "provisioning.");
3848                 }
3849             }
3850         } finally {
3851             Binder.restoreCallingIdentity(identity);
3852         }
3853 
3854     }
3855 
3856 
3857     @Override
getRcsProvisioningStatusForCapability(int subId, int capability)3858     public boolean getRcsProvisioningStatusForCapability(int subId, int capability) {
3859         enforceReadPrivilegedPermission("getRcsProvisioningStatusForCapability");
3860         final long identity = Binder.clearCallingIdentity();
3861         try {
3862             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3863             if (!isImsProvisioningRequired(subId, capability, false)) {
3864                 return true;
3865             }
3866 
3867             ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3868             switch (capability) {
3869                 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
3870                 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
3871                     return ims.isEabProvisionedOnDevice();
3872 
3873                 default: {
3874                     throw new IllegalArgumentException("Tried to get rcs provisioning for "
3875                             + "capability '" + capability + "', which does not require "
3876                             + "provisioning.");
3877                 }
3878             }
3879 
3880         } finally {
3881             Binder.restoreCallingIdentity(identity);
3882         }
3883     }
3884 
3885     @Override
setImsProvisioningStatusForCapability(int subId, int capability, int tech, boolean isProvisioned)3886     public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
3887             boolean isProvisioned) {
3888         if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3889                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3890             throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3891         }
3892         checkModifyPhoneStatePermission(subId, "setImsProvisioningStatusForCapability");
3893         final long identity = Binder.clearCallingIdentity();
3894         try {
3895             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3896             if (!isImsProvisioningRequired(subId, capability, true)) {
3897                 return;
3898             }
3899 
3900             // this capability requires provisioning, route to the correct API.
3901             ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3902             switch (capability) {
3903                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
3904                     if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3905                         ims.setVolteProvisioned(isProvisioned);
3906                     } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
3907                         ims.setWfcProvisioned(isProvisioned);
3908                     }
3909                     break;
3910                 }
3911                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3912                     // There is currently no difference in VT provisioning type.
3913                     ims.setVtProvisioned(isProvisioned);
3914                     break;
3915                 }
3916                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3917                     // There is no "deprecated" UT provisioning mechanism through ImsConfig, so
3918                     // change the capability of the feature instead if needed.
3919                     if (isMmTelCapabilityProvisionedInCache(subId, capability, tech)
3920                             == isProvisioned) {
3921                         // No change in provisioning.
3922                         return;
3923                     }
3924                     cacheMmTelCapabilityProvisioning(subId, capability, tech, isProvisioned);
3925                     try {
3926                         ims.changeMmTelCapability(capability, tech, isProvisioned);
3927                     } catch (com.android.ims.ImsException e) {
3928                         loge("setImsProvisioningStatusForCapability: couldn't change UT capability"
3929                                 + ", Exception" + e.getMessage());
3930                     }
3931                     break;
3932                 }
3933                 default: {
3934                     throw new IllegalArgumentException("Tried to set provisioning for "
3935                             + "MmTel capability '" + capability + "', which does not require "
3936                             + "provisioning. ");
3937                 }
3938             }
3939 
3940         } finally {
3941             Binder.restoreCallingIdentity(identity);
3942         }
3943     }
3944 
3945     @Override
getImsProvisioningStatusForCapability(int subId, int capability, int tech)3946     public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
3947         if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3948                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3949             throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3950         }
3951         enforceReadPrivilegedPermission("getProvisioningStatusForCapability");
3952         final long identity = Binder.clearCallingIdentity();
3953         try {
3954             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3955             if (!isImsProvisioningRequired(subId, capability, true)) {
3956                 return true;
3957             }
3958 
3959             ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3960             switch (capability) {
3961                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
3962                     if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3963                         return ims.isVolteProvisionedOnDevice();
3964                     } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
3965                         return ims.isWfcProvisionedOnDevice();
3966                     }
3967                     // This should never happen, since we are checking tech above to make sure it
3968                     // is either LTE or IWLAN.
3969                     throw new IllegalArgumentException("Invalid radio technology for voice "
3970                             + "capability.");
3971                 }
3972                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3973                     // There is currently no difference in VT provisioning type.
3974                     return ims.isVtProvisionedOnDevice();
3975                 }
3976                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3977                     // There is no "deprecated" UT provisioning mechanism, so get from shared prefs.
3978                     return isMmTelCapabilityProvisionedInCache(subId, capability, tech);
3979                 }
3980                 default: {
3981                     throw new IllegalArgumentException(
3982                             "Tried to get provisioning for MmTel capability '" + capability
3983                                     + "', which does not require provisioning.");
3984                 }
3985             }
3986 
3987         } finally {
3988             Binder.restoreCallingIdentity(identity);
3989         }
3990     }
3991 
3992     @Override
isMmTelCapabilityProvisionedInCache(int subId, int capability, int tech)3993     public boolean isMmTelCapabilityProvisionedInCache(int subId, int capability, int tech) {
3994         if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3995                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3996             throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3997         }
3998         enforceReadPrivilegedPermission("isMmTelCapabilityProvisionedInCache");
3999         int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
4000         return (provisionedBits & capability) > 0;
4001     }
4002 
4003     @Override
cacheMmTelCapabilityProvisioning(int subId, int capability, int tech, boolean isProvisioned)4004     public void cacheMmTelCapabilityProvisioning(int subId, int capability, int tech,
4005             boolean isProvisioned) {
4006         if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4007                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4008             throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4009         }
4010         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4011                 "setProvisioningStatusForCapability");
4012         int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
4013         // If the current provisioning status for capability already matches isProvisioned,
4014         // do nothing.
4015         if (((provisionedBits & capability) > 0) == isProvisioned) {
4016             return;
4017         }
4018         if (isProvisioned) {
4019             setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits | capability));
4020         } else {
4021             setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits & ~capability));
4022         }
4023     }
4024 
4025     /**
4026      * @return the bitfield containing the MmTel provisioning for the provided subscription and
4027      * technology. The bitfield should mirror the bitfield defined by
4028      * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}.
4029      */
getMmTelCapabilityProvisioningBitfield(int subId, int tech)4030     private int getMmTelCapabilityProvisioningBitfield(int subId, int tech) {
4031         String key = getMmTelProvisioningKey(subId, tech);
4032         // Default is no capabilities are provisioned.
4033         return mTelephonySharedPreferences.getInt(key, 0 /*default*/);
4034     }
4035 
4036     /**
4037      * Sets the MmTel capability provisioning bitfield (defined by
4038      *     {@link MmTelFeature.MmTelCapabilities.MmTelCapability}) for the subscription and
4039      *     technology specified.
4040      *
4041      * Note: This is a synchronous command and should not be called on UI thread.
4042      */
setMmTelCapabilityProvisioningBitfield(int subId, int tech, int newField)4043     private void setMmTelCapabilityProvisioningBitfield(int subId, int tech, int newField) {
4044         final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
4045         String key = getMmTelProvisioningKey(subId, tech);
4046         editor.putInt(key, newField);
4047         editor.commit();
4048     }
4049 
getMmTelProvisioningKey(int subId, int tech)4050     private static String getMmTelProvisioningKey(int subId, int tech) {
4051         // resulting key is provision_ims_mmtel_{subId}_{tech}
4052         return PREF_PROVISION_IMS_MMTEL_PREFIX + subId + "_" + tech;
4053     }
4054 
4055     /**
4056      * Query CarrierConfig to see if the specified capability requires provisioning for the
4057      * carrier associated with the subscription id.
4058      */
doesImsCapabilityRequireProvisioning(Context context, int subId, int capability)4059     private boolean doesImsCapabilityRequireProvisioning(Context context, int subId,
4060             int capability) {
4061         CarrierConfigManager configManager = new CarrierConfigManager(context);
4062         PersistableBundle c = configManager.getConfigForSubId(subId);
4063         boolean requireUtProvisioning = c.getBoolean(
4064                 CarrierConfigManager.KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, false)
4065                 && c.getBoolean(CarrierConfigManager.KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL,
4066                 false);
4067         boolean requireVoiceVtProvisioning = c.getBoolean(
4068                 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
4069 
4070         // First check to make sure that the capability requires provisioning.
4071         switch (capability) {
4072             case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE:
4073                 // intentional fallthrough
4074             case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
4075                 if (requireVoiceVtProvisioning) {
4076                     // Voice and Video requires provisioning
4077                     return true;
4078                 }
4079                 break;
4080             }
4081             case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
4082                 if (requireUtProvisioning) {
4083                     // UT requires provisioning
4084                     return true;
4085                 }
4086                 break;
4087             }
4088         }
4089         return false;
4090     }
4091 
doesRcsCapabilityRequireProvisioning(Context context, int subId, int capability)4092     private boolean doesRcsCapabilityRequireProvisioning(Context context, int subId,
4093             int capability) {
4094         CarrierConfigManager configManager = new CarrierConfigManager(context);
4095         PersistableBundle c = configManager.getConfigForSubId(subId);
4096 
4097         boolean requireRcsProvisioning = c.getBoolean(
4098                 CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, false);
4099 
4100         // First check to make sure that the capability requires provisioning.
4101         switch (capability) {
4102             case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
4103                 // intentional fallthrough
4104             case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE: {
4105                 if (requireRcsProvisioning) {
4106                     // OPTION or PRESENCE requires provisioning
4107                     return true;
4108                 }
4109                 break;
4110             }
4111         }
4112         return false;
4113     }
4114 
4115     @Override
getImsProvisioningInt(int subId, int key)4116     public int getImsProvisioningInt(int subId, int key) {
4117         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4118             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4119         }
4120         enforceReadPrivilegedPermission("getImsProvisioningInt");
4121         final long identity = Binder.clearCallingIdentity();
4122         try {
4123             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4124             int slotId = getSlotIndex(subId);
4125             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4126                 Log.w(LOG_TAG, "getImsProvisioningInt: called with an inactive subscription '"
4127                         + subId + "' for key:" + key);
4128                 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
4129             }
4130             return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigInt(key);
4131         } catch (com.android.ims.ImsException e) {
4132             Log.w(LOG_TAG, "getImsProvisioningInt: ImsService is not available for subscription '"
4133                     + subId + "' for key:" + key);
4134             return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
4135         } finally {
4136             Binder.restoreCallingIdentity(identity);
4137         }
4138     }
4139 
4140     @Override
getImsProvisioningString(int subId, int key)4141     public String getImsProvisioningString(int subId, int key) {
4142         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4143             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4144         }
4145         enforceReadPrivilegedPermission("getImsProvisioningString");
4146         final long identity = Binder.clearCallingIdentity();
4147         try {
4148             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4149             int slotId = getSlotIndex(subId);
4150             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4151                 Log.w(LOG_TAG, "getImsProvisioningString: called for an inactive subscription id '"
4152                         + subId + "' for key:" + key);
4153                 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_GENERIC;
4154             }
4155             return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigString(key);
4156         } catch (com.android.ims.ImsException e) {
4157             Log.w(LOG_TAG, "getImsProvisioningString: ImsService is not available for sub '"
4158                     + subId + "' for key:" + key);
4159             return ProvisioningManager.STRING_QUERY_RESULT_ERROR_NOT_READY;
4160         } finally {
4161             Binder.restoreCallingIdentity(identity);
4162         }
4163     }
4164 
4165     @Override
setImsProvisioningInt(int subId, int key, int value)4166     public int setImsProvisioningInt(int subId, int key, int value) {
4167         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4168             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4169         }
4170         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4171                 "setImsProvisioningInt");
4172         final long identity = Binder.clearCallingIdentity();
4173         try {
4174             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4175             int slotId = getSlotIndex(subId);
4176             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4177                 Log.w(LOG_TAG, "setImsProvisioningInt: called with an inactive subscription id '"
4178                         + subId + "' for key:" + key);
4179                 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4180             }
4181             return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
4182         } catch (com.android.ims.ImsException e) {
4183             Log.w(LOG_TAG, "setImsProvisioningInt: ImsService unavailable for sub '" + subId
4184                     + "' for key:" + key);
4185             return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4186         } finally {
4187             Binder.restoreCallingIdentity(identity);
4188         }
4189     }
4190 
4191     @Override
setImsProvisioningString(int subId, int key, String value)4192     public int setImsProvisioningString(int subId, int key, String value) {
4193         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4194             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4195         }
4196         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4197                 "setImsProvisioningString");
4198         final long identity = Binder.clearCallingIdentity();
4199         try {
4200             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4201             int slotId = getSlotIndex(subId);
4202             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4203                 Log.w(LOG_TAG, "setImsProvisioningString: called with an inactive subscription id '"
4204                         + subId + "' for key:" + key);
4205                 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4206             }
4207             return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
4208         } catch (com.android.ims.ImsException e) {
4209             Log.w(LOG_TAG, "setImsProvisioningString: ImsService unavailable for sub '" + subId
4210                     + "' for key:" + key);
4211             return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4212         } finally {
4213             Binder.restoreCallingIdentity(identity);
4214         }
4215     }
4216 
getSlotIndexOrException(int subId)4217     private int getSlotIndexOrException(int subId) throws ImsException {
4218         int slotId = SubscriptionManager.getSlotIndex(subId);
4219         if (!SubscriptionManager.isValidSlotIndex(slotId)) {
4220             throw new ImsException("Invalid Subscription Id, subId=" + subId,
4221                     ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4222         }
4223         return slotId;
4224     }
4225 
getSlotIndex(int subId)4226     private int getSlotIndex(int subId) {
4227         int slotId = SubscriptionManager.getSlotIndex(subId);
4228         if (!SubscriptionManager.isValidSlotIndex(slotId)) {
4229             return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
4230         }
4231         return slotId;
4232     }
4233 
4234     /**
4235      * Returns the data network type for a subId; does not throw SecurityException.
4236      */
4237     @Override
getNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId)4238     public int getNetworkTypeForSubscriber(int subId, String callingPackage,
4239             String callingFeatureId) {
4240         final int targetSdk = getTargetSdk(callingPackage);
4241         if (targetSdk > android.os.Build.VERSION_CODES.Q) {
4242             return getDataNetworkTypeForSubscriber(subId, callingPackage, callingFeatureId);
4243         } else if (targetSdk == android.os.Build.VERSION_CODES.Q
4244                 && !TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
4245                         mApp, subId, callingPackage, callingFeatureId,
4246                 "getNetworkTypeForSubscriber")) {
4247             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4248         }
4249 
4250         final long identity = Binder.clearCallingIdentity();
4251         try {
4252             final Phone phone = getPhone(subId);
4253             if (phone != null) {
4254                 return phone.getServiceState().getDataNetworkType();
4255             } else {
4256                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4257             }
4258         } finally {
4259             Binder.restoreCallingIdentity(identity);
4260         }
4261     }
4262 
4263     /**
4264      * Returns the data network type
4265      */
4266     @Override
getDataNetworkType(String callingPackage, String callingFeatureId)4267     public int getDataNetworkType(String callingPackage, String callingFeatureId) {
4268         return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage,
4269                 callingFeatureId);
4270     }
4271 
4272     /**
4273      * Returns the data network type for a subId
4274      */
4275     @Override
getDataNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId)4276     public int getDataNetworkTypeForSubscriber(int subId, String callingPackage,
4277             String callingFeatureId) {
4278         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4279                 mApp, subId, callingPackage, callingFeatureId,
4280                 "getDataNetworkTypeForSubscriber")) {
4281             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4282         }
4283 
4284         final long identity = Binder.clearCallingIdentity();
4285         try {
4286             final Phone phone = getPhone(subId);
4287             if (phone != null) {
4288                 return phone.getServiceState().getDataNetworkType();
4289             } else {
4290                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4291             }
4292         } finally {
4293             Binder.restoreCallingIdentity(identity);
4294         }
4295     }
4296 
4297     /**
4298      * Returns the Voice network type for a subId
4299      */
4300     @Override
getVoiceNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId)4301     public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage,
4302             String callingFeatureId) {
4303         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4304                 mApp, subId, callingPackage, callingFeatureId,
4305                 "getDataNetworkTypeForSubscriber")) {
4306             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4307         }
4308 
4309         final long identity = Binder.clearCallingIdentity();
4310         try {
4311             final Phone phone = getPhone(subId);
4312             if (phone != null) {
4313                 return phone.getServiceState().getVoiceNetworkType();
4314             } else {
4315                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4316             }
4317         } finally {
4318             Binder.restoreCallingIdentity(identity);
4319         }
4320     }
4321 
4322     /**
4323      * @return true if a ICC card is present
4324      */
hasIccCard()4325     public boolean hasIccCard() {
4326         // FIXME Make changes to pass defaultSimId of type int
4327         return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
4328                 getDefaultSubscription()));
4329     }
4330 
4331     /**
4332      * @return true if a ICC card is present for a slotIndex
4333      */
4334     @Override
hasIccCardUsingSlotIndex(int slotIndex)4335     public boolean hasIccCardUsingSlotIndex(int slotIndex) {
4336         final long identity = Binder.clearCallingIdentity();
4337         try {
4338             final Phone phone = PhoneFactory.getPhone(slotIndex);
4339             if (phone != null) {
4340                 return phone.getIccCard().hasIccCard();
4341             } else {
4342                 return false;
4343             }
4344         } finally {
4345             Binder.restoreCallingIdentity(identity);
4346         }
4347     }
4348 
4349     /**
4350      * Return if the current radio is LTE on CDMA. This
4351      * is a tri-state return value as for a period of time
4352      * the mode may be unknown.
4353      *
4354      * @param callingPackage the name of the package making the call.
4355      * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
4356      * or {@link Phone#LTE_ON_CDMA_TRUE}
4357      */
4358     @Override
getLteOnCdmaMode(String callingPackage, String callingFeatureId)4359     public int getLteOnCdmaMode(String callingPackage, String callingFeatureId) {
4360         return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage,
4361                 callingFeatureId);
4362     }
4363 
4364     @Override
getLteOnCdmaModeForSubscriber(int subId, String callingPackage, String callingFeatureId)4365     public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage,
4366             String callingFeatureId) {
4367         try {
4368             enforceReadPrivilegedPermission("getLteOnCdmaModeForSubscriber");
4369         } catch (SecurityException e) {
4370             return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
4371         }
4372 
4373         final long identity = Binder.clearCallingIdentity();
4374         try {
4375             final Phone phone = getPhone(subId);
4376             if (phone == null) {
4377                 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
4378             } else {
4379                 return phone.getLteOnCdmaMode();
4380             }
4381         } finally {
4382             Binder.restoreCallingIdentity(identity);
4383         }
4384     }
4385 
4386     /**
4387      * {@hide}
4388      * Returns Default subId, 0 in the case of single standby.
4389      */
getDefaultSubscription()4390     private int getDefaultSubscription() {
4391         return mSubscriptionController.getDefaultSubId();
4392     }
4393 
getSlotForDefaultSubscription()4394     private int getSlotForDefaultSubscription() {
4395         return mSubscriptionController.getPhoneId(getDefaultSubscription());
4396     }
4397 
getPreferredVoiceSubscription()4398     private int getPreferredVoiceSubscription() {
4399         return mSubscriptionController.getDefaultVoiceSubId();
4400     }
4401 
isActiveSubscription(int subId)4402     private boolean isActiveSubscription(int subId) {
4403         return mSubscriptionController.isActiveSubId(subId);
4404     }
4405 
4406     /**
4407      * @see android.telephony.TelephonyManager.WifiCallingChoices
4408      */
getWhenToMakeWifiCalls()4409     public int getWhenToMakeWifiCalls() {
4410         final long identity = Binder.clearCallingIdentity();
4411         try {
4412             return Settings.System.getInt(mApp.getContentResolver(),
4413                     Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
4414                     getWhenToMakeWifiCallsDefaultPreference());
4415         } finally {
4416             Binder.restoreCallingIdentity(identity);
4417         }
4418     }
4419 
4420     /**
4421      * @see android.telephony.TelephonyManager.WifiCallingChoices
4422      */
setWhenToMakeWifiCalls(int preference)4423     public void setWhenToMakeWifiCalls(int preference) {
4424         final long identity = Binder.clearCallingIdentity();
4425         try {
4426             if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
4427             Settings.System.putInt(mApp.getContentResolver(),
4428                     Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
4429         } finally {
4430             Binder.restoreCallingIdentity(identity);
4431         }
4432     }
4433 
getWhenToMakeWifiCallsDefaultPreference()4434     private static int getWhenToMakeWifiCallsDefaultPreference() {
4435         // TODO: Use a build property to choose this value.
4436         return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
4437     }
4438 
getPhoneFromSlotIdOrThrowException(int slotIndex)4439     private Phone getPhoneFromSlotIdOrThrowException(int slotIndex) {
4440         int phoneId = UiccController.getInstance().getPhoneIdFromSlotId(slotIndex);
4441         if (phoneId == -1) {
4442             throw new IllegalArgumentException("Given slot index: " + slotIndex
4443                     + " does not correspond to an active phone");
4444         }
4445         return PhoneFactory.getPhone(phoneId);
4446     }
4447 
4448     @Override
iccOpenLogicalChannel( int subId, String callingPackage, String aid, int p2)4449     public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
4450             int subId, String callingPackage, String aid, int p2) {
4451         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4452                 mApp, subId, "iccOpenLogicalChannel");
4453         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4454         if (DBG) {
4455             log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
4456         }
4457         return iccOpenLogicalChannelWithPermission(getPhoneFromSubId(subId), callingPackage, aid,
4458                 p2);
4459     }
4460 
4461 
4462     @Override
iccOpenLogicalChannelBySlot( int slotIndex, String callingPackage, String aid, int p2)4463     public IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(
4464             int slotIndex, String callingPackage, String aid, int p2) {
4465         enforceModifyPermission();
4466         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4467         if (DBG) {
4468             log("iccOpenLogicalChannelBySlot: slot=" + slotIndex + " aid=" + aid + " p2=" + p2);
4469         }
4470         return iccOpenLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
4471                 callingPackage, aid, p2);
4472     }
4473 
iccOpenLogicalChannelWithPermission(Phone phone, String callingPackage, String aid, int p2)4474     private IccOpenLogicalChannelResponse iccOpenLogicalChannelWithPermission(Phone phone,
4475             String callingPackage, String aid, int p2) {
4476         final long identity = Binder.clearCallingIdentity();
4477         try {
4478             if (TextUtils.equals(ISDR_AID, aid)) {
4479                 // Only allows LPA to open logical channel to ISD-R.
4480                 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
4481                         .getContext().getPackageManager());
4482                 if (bestComponent == null
4483                         || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
4484                     loge("The calling package is not allowed to access ISD-R.");
4485                     throw new SecurityException(
4486                             "The calling package is not allowed to access ISD-R.");
4487                 }
4488             }
4489 
4490             IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
4491                     CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), phone,
4492                     null /* workSource */);
4493             if (DBG) log("iccOpenLogicalChannelWithPermission: " + response);
4494             return response;
4495         } finally {
4496             Binder.restoreCallingIdentity(identity);
4497         }
4498     }
4499 
4500     @Override
iccCloseLogicalChannel(int subId, int channel)4501     public boolean iccCloseLogicalChannel(int subId, int channel) {
4502         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4503                 mApp, subId, "iccCloseLogicalChannel");
4504         if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
4505         return iccCloseLogicalChannelWithPermission(getPhoneFromSubId(subId), channel);
4506     }
4507 
4508     @Override
iccCloseLogicalChannelBySlot(int slotIndex, int channel)4509     public boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel) {
4510         enforceModifyPermission();
4511         if (DBG) log("iccCloseLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel);
4512         return iccCloseLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
4513                 channel);
4514     }
4515 
iccCloseLogicalChannelWithPermission(Phone phone, int channel)4516     private boolean iccCloseLogicalChannelWithPermission(Phone phone, int channel) {
4517         final long identity = Binder.clearCallingIdentity();
4518         try {
4519             if (channel < 0) {
4520                 return false;
4521             }
4522             Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, channel, phone,
4523                     null /* workSource */);
4524             if (DBG) log("iccCloseLogicalChannelWithPermission: " + success);
4525             return success;
4526         } finally {
4527             Binder.restoreCallingIdentity(identity);
4528         }
4529     }
4530 
4531     @Override
iccTransmitApduLogicalChannel(int subId, int channel, int cla, int command, int p1, int p2, int p3, String data)4532     public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
4533             int command, int p1, int p2, int p3, String data) {
4534         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4535                 mApp, subId, "iccTransmitApduLogicalChannel");
4536         if (DBG) {
4537             log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
4538                     + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
4539                     + p3 + " data=" + data);
4540         }
4541         return iccTransmitApduLogicalChannelWithPermission(getPhoneFromSubId(subId), channel, cla,
4542                 command, p1, p2, p3, data);
4543     }
4544 
4545     @Override
iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla, int command, int p1, int p2, int p3, String data)4546     public String iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla,
4547             int command, int p1, int p2, int p3, String data) {
4548         enforceModifyPermission();
4549         if (DBG) {
4550             log("iccTransmitApduLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel
4551                     + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
4552                     + p3 + " data=" + data);
4553         }
4554         return iccTransmitApduLogicalChannelWithPermission(
4555                 getPhoneFromSlotIdOrThrowException(slotIndex), channel, cla, command, p1, p2, p3,
4556                 data);
4557     }
4558 
iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla, int command, int p1, int p2, int p3, String data)4559     private String iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla,
4560             int command, int p1, int p2, int p3, String data) {
4561         final long identity = Binder.clearCallingIdentity();
4562         try {
4563             if (channel <= 0) {
4564                 return "";
4565             }
4566 
4567             IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
4568                     new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), phone,
4569                     null /* workSource */);
4570             if (DBG) log("iccTransmitApduLogicalChannelWithPermission: " + response);
4571 
4572             // Append the returned status code to the end of the response payload.
4573             String s = Integer.toHexString(
4574                     (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
4575             if (response.payload != null) {
4576                 s = IccUtils.bytesToHexString(response.payload) + s;
4577             }
4578             return s;
4579         } finally {
4580             Binder.restoreCallingIdentity(identity);
4581         }
4582     }
4583 
4584     @Override
iccTransmitApduBasicChannel(int subId, String callingPackage, int cla, int command, int p1, int p2, int p3, String data)4585     public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
4586             int command, int p1, int p2, int p3, String data) {
4587         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4588                 mApp, subId, "iccTransmitApduBasicChannel");
4589         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4590         if (DBG) {
4591             log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
4592                     + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
4593         }
4594         return iccTransmitApduBasicChannelWithPermission(getPhoneFromSubId(subId), callingPackage,
4595                 cla, command, p1, p2, p3, data);
4596     }
4597 
4598     @Override
iccTransmitApduBasicChannelBySlot(int slotIndex, String callingPackage, int cla, int command, int p1, int p2, int p3, String data)4599     public String iccTransmitApduBasicChannelBySlot(int slotIndex, String callingPackage, int cla,
4600             int command, int p1, int p2, int p3, String data) {
4601         enforceModifyPermission();
4602         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4603         if (DBG) {
4604             log("iccTransmitApduBasicChannelBySlot: slotIndex=" + slotIndex + " cla=" + cla
4605                     + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3
4606                     + " data=" + data);
4607         }
4608 
4609         return iccTransmitApduBasicChannelWithPermission(
4610                 getPhoneFromSlotIdOrThrowException(slotIndex), callingPackage, cla, command, p1,
4611                 p2, p3, data);
4612     }
4613 
4614     // open APDU basic channel assuming the caller has sufficient permissions
iccTransmitApduBasicChannelWithPermission(Phone phone, String callingPackage, int cla, int command, int p1, int p2, int p3, String data)4615     private String iccTransmitApduBasicChannelWithPermission(Phone phone, String callingPackage,
4616             int cla, int command, int p1, int p2, int p3, String data) {
4617         final long identity = Binder.clearCallingIdentity();
4618         try {
4619             if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
4620                     && TextUtils.equals(ISDR_AID, data)) {
4621                 // Only allows LPA to select ISD-R.
4622                 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
4623                         .getContext().getPackageManager());
4624                 if (bestComponent == null
4625                         || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
4626                     loge("The calling package is not allowed to select ISD-R.");
4627                     throw new SecurityException(
4628                             "The calling package is not allowed to select ISD-R.");
4629                 }
4630             }
4631 
4632             IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
4633                     new IccAPDUArgument(0, cla, command, p1, p2, p3, data), phone,
4634                     null /* workSource */);
4635             if (DBG) log("iccTransmitApduBasicChannelWithPermission: " + response);
4636 
4637             // Append the returned status code to the end of the response payload.
4638             String s = Integer.toHexString(
4639                     (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
4640             if (response.payload != null) {
4641                 s = IccUtils.bytesToHexString(response.payload) + s;
4642             }
4643             return s;
4644         } finally {
4645             Binder.restoreCallingIdentity(identity);
4646         }
4647     }
4648 
4649     @Override
iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3, String filePath)4650     public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
4651             String filePath) {
4652         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4653                 mApp, subId, "iccExchangeSimIO");
4654 
4655         final long identity = Binder.clearCallingIdentity();
4656         try {
4657             if (DBG) {
4658                 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
4659                         + p1 + " " + p2 + " " + p3 + ":" + filePath);
4660             }
4661 
4662             IccIoResult response =
4663                     (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
4664                             new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
4665                             subId);
4666 
4667             if (DBG) {
4668                 log("Exchange SIM_IO [R]" + response);
4669             }
4670 
4671             byte[] result = null;
4672             int length = 2;
4673             if (response.payload != null) {
4674                 length = 2 + response.payload.length;
4675                 result = new byte[length];
4676                 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
4677             } else {
4678                 result = new byte[length];
4679             }
4680 
4681             result[length - 1] = (byte) response.sw2;
4682             result[length - 2] = (byte) response.sw1;
4683             return result;
4684         } finally {
4685             Binder.restoreCallingIdentity(identity);
4686         }
4687     }
4688 
4689     /**
4690      * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
4691      * on a particular subscription
4692      */
getForbiddenPlmns(int subId, int appType, String callingPackage, String callingFeatureId)4693     public String[] getForbiddenPlmns(int subId, int appType, String callingPackage,
4694             String callingFeatureId) {
4695         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4696                 mApp, subId, callingPackage, callingFeatureId, "getForbiddenPlmns")) {
4697             return null;
4698         }
4699 
4700         final long identity = Binder.clearCallingIdentity();
4701         try {
4702             if (appType != TelephonyManager.APPTYPE_USIM
4703                     && appType != TelephonyManager.APPTYPE_SIM) {
4704                 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
4705                 return null;
4706             }
4707             Object response = sendRequest(
4708                     CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
4709             if (response instanceof String[]) {
4710                 return (String[]) response;
4711             }
4712             // Response is an Exception of some kind
4713             // which is signalled to the user as a NULL retval
4714             return null;
4715         } finally {
4716             Binder.restoreCallingIdentity(identity);
4717         }
4718     }
4719 
4720     /**
4721      * Set the forbidden PLMN list from the given app type (ex APPTYPE_USIM) on a particular
4722      * subscription.
4723      *
4724      * @param subId the id of the subscription.
4725      * @param appType the uicc app type, must be USIM or SIM.
4726      * @param fplmns the Forbiden plmns list that needed to be written to the SIM.
4727      * @param callingPackage the op Package name.
4728      * @param callingFeatureId the feature in the package.
4729      * @return number of fplmns that is successfully written to the SIM.
4730      */
setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage, String callingFeatureId)4731     public int setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage,
4732             String callingFeatureId) {
4733         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
4734                 callingFeatureId, "setForbiddenPlmns")) {
4735             if (DBG) logv("no permissions for setForbiddenplmns");
4736             throw new IllegalStateException("No Permissions for setForbiddenPlmns");
4737         }
4738         if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
4739             loge("setForbiddenPlmnList(): App Type must be USIM or SIM");
4740             throw new IllegalArgumentException("Invalid appType: App Type must be USIM or SIM");
4741         }
4742         if (fplmns == null) {
4743             throw new IllegalArgumentException("Fplmn List provided is null");
4744         }
4745         for (String fplmn : fplmns) {
4746             if (!CellIdentity.isValidPlmn(fplmn)) {
4747                 throw new IllegalArgumentException("Invalid fplmn provided: " + fplmn);
4748             }
4749         }
4750         final long identity = Binder.clearCallingIdentity();
4751         try {
4752             Object response = sendRequest(
4753                     CMD_SET_FORBIDDEN_PLMNS,
4754                     new Pair<Integer, List<String>>(new Integer(appType), fplmns),
4755                     subId);
4756             return (int) response;
4757         } finally {
4758             Binder.restoreCallingIdentity(identity);
4759         }
4760     }
4761 
4762     @Override
sendEnvelopeWithStatus(int subId, String content)4763     public String sendEnvelopeWithStatus(int subId, String content) {
4764         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4765                 mApp, subId, "sendEnvelopeWithStatus");
4766 
4767         final long identity = Binder.clearCallingIdentity();
4768         try {
4769             IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
4770             if (response.payload == null) {
4771                 return "";
4772             }
4773 
4774             // Append the returned status code to the end of the response payload.
4775             String s = Integer.toHexString(
4776                     (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
4777             s = IccUtils.bytesToHexString(response.payload) + s;
4778             return s;
4779         } finally {
4780             Binder.restoreCallingIdentity(identity);
4781         }
4782     }
4783 
4784     /**
4785      * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
4786      * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
4787      *
4788      * @param itemID the ID of the item to read
4789      * @return the NV item as a String, or null on error.
4790      */
4791     @Override
nvReadItem(int itemID)4792     public String nvReadItem(int itemID) {
4793         WorkSource workSource = getWorkSource(Binder.getCallingUid());
4794         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4795                 mApp, getDefaultSubscription(), "nvReadItem");
4796 
4797         final long identity = Binder.clearCallingIdentity();
4798         try {
4799             if (DBG) log("nvReadItem: item " + itemID);
4800             String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
4801             if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
4802             return value;
4803         } finally {
4804             Binder.restoreCallingIdentity(identity);
4805         }
4806     }
4807 
4808     /**
4809      * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
4810      * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
4811      *
4812      * @param itemID the ID of the item to read
4813      * @param itemValue the value to write, as a String
4814      * @return true on success; false on any failure
4815      */
4816     @Override
nvWriteItem(int itemID, String itemValue)4817     public boolean nvWriteItem(int itemID, String itemValue) {
4818         WorkSource workSource = getWorkSource(Binder.getCallingUid());
4819         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4820                 mApp, getDefaultSubscription(), "nvWriteItem");
4821 
4822         final long identity = Binder.clearCallingIdentity();
4823         try {
4824             if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
4825             Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
4826                     new Pair<Integer, String>(itemID, itemValue), workSource);
4827             if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
4828             return success;
4829         } finally {
4830             Binder.restoreCallingIdentity(identity);
4831         }
4832     }
4833 
4834     /**
4835      * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
4836      * Used for device configuration by some CDMA operators.
4837      *
4838      * @param preferredRoamingList byte array containing the new PRL
4839      * @return true on success; false on any failure
4840      */
4841     @Override
nvWriteCdmaPrl(byte[] preferredRoamingList)4842     public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
4843         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4844                 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
4845 
4846         final long identity = Binder.clearCallingIdentity();
4847         try {
4848             if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
4849             Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
4850             if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
4851             return success;
4852         } finally {
4853             Binder.restoreCallingIdentity(identity);
4854         }
4855     }
4856 
4857     /**
4858      * Rollback modem configurations to factory default except some config which are in whitelist.
4859      * Used for device configuration by some CDMA operators.
4860      *
4861      * @param slotIndex - device slot.
4862      *
4863      * @return true on success; false on any failure
4864      */
4865     @Override
resetModemConfig(int slotIndex)4866     public boolean resetModemConfig(int slotIndex) {
4867         Phone phone = PhoneFactory.getPhone(slotIndex);
4868         if (phone != null) {
4869             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4870                     mApp, phone.getSubId(), "resetModemConfig");
4871 
4872             final long identity = Binder.clearCallingIdentity();
4873             try {
4874                 Boolean success = (Boolean) sendRequest(CMD_RESET_MODEM_CONFIG, null);
4875                 if (DBG) log("resetModemConfig:" + ' ' + (success ? "ok" : "fail"));
4876                 return success;
4877             } finally {
4878                 Binder.restoreCallingIdentity(identity);
4879             }
4880         }
4881         return false;
4882     }
4883 
4884     /**
4885      * Generate a radio modem reset. Used for device configuration by some CDMA operators.
4886      *
4887      * @param slotIndex - device slot.
4888      *
4889      * @return true on success; false on any failure
4890      */
4891     @Override
rebootModem(int slotIndex)4892     public boolean rebootModem(int slotIndex) {
4893         Phone phone = PhoneFactory.getPhone(slotIndex);
4894         if (phone != null) {
4895             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4896                     mApp, phone.getSubId(), "rebootModem");
4897 
4898             final long identity = Binder.clearCallingIdentity();
4899             try {
4900                 Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
4901                 if (DBG) log("rebootModem:" + ' ' + (success ? "ok" : "fail"));
4902                 return success;
4903             } finally {
4904                 Binder.restoreCallingIdentity(identity);
4905             }
4906         }
4907         return false;
4908     }
4909 
getPcscfAddress(String apnType, String callingPackage, String callingFeatureId)4910     public String[] getPcscfAddress(String apnType, String callingPackage,
4911             String callingFeatureId) {
4912         final Phone defaultPhone = getDefaultPhone();
4913         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
4914                 callingPackage, callingFeatureId, "getPcscfAddress")) {
4915             return new String[0];
4916         }
4917 
4918         final long identity = Binder.clearCallingIdentity();
4919         try {
4920             return defaultPhone.getPcscfAddress(apnType);
4921         } finally {
4922             Binder.restoreCallingIdentity(identity);
4923         }
4924     }
4925 
4926     /**
4927      * Toggle IMS disable and enable for the framework to reset it. See {@link #enableIms(int)} and
4928      * {@link #disableIms(int)}.
4929      * @param slotIndex device slot.
4930      */
resetIms(int slotIndex)4931     public void resetIms(int slotIndex) {
4932         enforceModifyPermission();
4933 
4934         final long identity = Binder.clearCallingIdentity();
4935         try {
4936             if (mImsResolver == null) {
4937                 // may happen if the does not support IMS.
4938                 return;
4939             }
4940             mImsResolver.disableIms(slotIndex);
4941             mImsResolver.enableIms(slotIndex);
4942         } finally {
4943             Binder.restoreCallingIdentity(identity);
4944         }
4945     }
4946 
4947     /**
4948      * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
4949      * status updates, if not already enabled.
4950      */
enableIms(int slotId)4951     public void enableIms(int slotId) {
4952         enforceModifyPermission();
4953 
4954         final long identity = Binder.clearCallingIdentity();
4955         try {
4956             if (mImsResolver == null) {
4957                 // may happen if the device does not support IMS.
4958                 return;
4959             }
4960             mImsResolver.enableIms(slotId);
4961         } finally {
4962             Binder.restoreCallingIdentity(identity);
4963         }
4964     }
4965 
4966     /**
4967      * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
4968      * status updates to disabled.
4969      */
disableIms(int slotId)4970     public void disableIms(int slotId) {
4971         enforceModifyPermission();
4972 
4973         final long identity = Binder.clearCallingIdentity();
4974         try {
4975             if (mImsResolver == null) {
4976                 // may happen if the device does not support IMS.
4977                 return;
4978             }
4979             mImsResolver.disableIms(slotId);
4980         } finally {
4981             Binder.restoreCallingIdentity(identity);
4982         }
4983     }
4984 
4985     /**
4986      * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id for the MMTel
4987      * feature or {@link null} if the service is not available. If the feature is available, the
4988      * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
4989      */
getMmTelFeatureAndListen(int slotId, IImsServiceFeatureCallback callback)4990     public IImsMmTelFeature getMmTelFeatureAndListen(int slotId,
4991             IImsServiceFeatureCallback callback) {
4992         enforceModifyPermission();
4993 
4994         final long identity = Binder.clearCallingIdentity();
4995         try {
4996             if (mImsResolver == null) {
4997                 // may happen if the device does not support IMS.
4998                 return null;
4999             }
5000             return mImsResolver.getMmTelFeatureAndListen(slotId, callback);
5001         } finally {
5002             Binder.restoreCallingIdentity(identity);
5003         }
5004     }
5005 
5006     /**
5007      * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id for the RCS
5008      * feature during emergency calling or {@link null} if the service is not available. If the
5009      * feature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
5010      * listener for feature updates.
5011      */
getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback)5012     public IImsRcsFeature getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback) {
5013         enforceModifyPermission();
5014 
5015         final long identity = Binder.clearCallingIdentity();
5016         try {
5017             if (mImsResolver == null) {
5018                 // may happen if the device does not support IMS.
5019                 return null;
5020             }
5021             return mImsResolver.getRcsFeatureAndListen(slotId, callback);
5022         } finally {
5023             Binder.restoreCallingIdentity(identity);
5024         }
5025     }
5026 
5027     /**
5028      * Unregister a previously registered IImsServiceFeatureCallback associated with an ImsFeature.
5029      */
unregisterImsFeatureCallback(int slotId, int featureType, IImsServiceFeatureCallback callback)5030     public void unregisterImsFeatureCallback(int slotId, int featureType,
5031             IImsServiceFeatureCallback callback) {
5032         enforceModifyPermission();
5033 
5034         final long identity = Binder.clearCallingIdentity();
5035         try {
5036             if (mImsResolver == null) return;
5037             mImsResolver.unregisterImsFeatureCallback(slotId, featureType, callback);
5038         } finally {
5039             Binder.restoreCallingIdentity(identity);
5040         }
5041     }
5042 
5043     /**
5044      * Returns the {@link IImsRegistration} structure associated with the slotId and feature
5045      * specified or null if IMS is not supported on the slot specified.
5046      */
getImsRegistration(int slotId, int feature)5047     public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
5048         enforceModifyPermission();
5049 
5050         final long identity = Binder.clearCallingIdentity();
5051         try {
5052             if (mImsResolver == null) {
5053                 // may happen if the device does not support IMS.
5054                 return null;
5055             }
5056             return mImsResolver.getImsRegistration(slotId, feature);
5057         } finally {
5058             Binder.restoreCallingIdentity(identity);
5059         }
5060     }
5061 
5062     /**
5063      * Returns the {@link IImsConfig} structure associated with the slotId and feature
5064      * specified or null if IMS is not supported on the slot specified.
5065      */
getImsConfig(int slotId, int feature)5066     public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
5067         enforceModifyPermission();
5068 
5069         final long identity = Binder.clearCallingIdentity();
5070         try {
5071             if (mImsResolver == null) {
5072                 // may happen if the device does not support IMS.
5073                 return null;
5074             }
5075             return mImsResolver.getImsConfig(slotId, feature);
5076         } finally {
5077             Binder.restoreCallingIdentity(identity);
5078         }
5079     }
5080 
5081     /**
5082      * Sets the ImsService Package Name that Telephony will bind to.
5083      *
5084      * @param slotIndex the slot ID that the ImsService should bind for.
5085      * @param isCarrierService true if the ImsService is the carrier override, false if the
5086      *         ImsService is the device default ImsService.
5087      * @param featureTypes An integer array of feature types associated with a packageName.
5088      * @param packageName The name of the package that the current configuration will be replaced
5089      *                    with.
5090      * @return true if setting the ImsService to bind to succeeded, false if it did not.
5091      */
setBoundImsServiceOverride(int slotIndex, boolean isCarrierService, int[] featureTypes, String packageName)5092     public boolean setBoundImsServiceOverride(int slotIndex, boolean isCarrierService,
5093             int[] featureTypes, String packageName) {
5094         int[] subIds = SubscriptionManager.getSubId(slotIndex);
5095         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setBoundImsServiceOverride");
5096         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
5097                 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
5098                 "setBoundImsServiceOverride");
5099 
5100         final long identity = Binder.clearCallingIdentity();
5101         try {
5102             if (mImsResolver == null) {
5103                 // may happen if the device does not support IMS.
5104                 return false;
5105             }
5106             Map<Integer, String> featureConfig = new HashMap<>();
5107             for (int featureType : featureTypes) {
5108                 featureConfig.put(featureType, packageName);
5109             }
5110             return mImsResolver.overrideImsServiceConfiguration(slotIndex, isCarrierService,
5111                     featureConfig);
5112         } finally {
5113             Binder.restoreCallingIdentity(identity);
5114         }
5115     }
5116 
5117     /**
5118      * Return the package name of the currently bound ImsService.
5119      *
5120      * @param slotId The slot that the ImsService is associated with.
5121      * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
5122      *         the device default.
5123      * @param featureType The feature associated with the queried configuration.
5124      * @return the package name of the ImsService configuration.
5125      */
getBoundImsServicePackage(int slotId, boolean isCarrierImsService, @ImsFeature.FeatureType int featureType)5126     public String getBoundImsServicePackage(int slotId, boolean isCarrierImsService,
5127             @ImsFeature.FeatureType int featureType) {
5128         int[] subIds = SubscriptionManager.getSubId(slotId);
5129         TelephonyPermissions
5130                 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5131                 mApp, (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
5132                 "getBoundImsServicePackage");
5133 
5134         final long identity = Binder.clearCallingIdentity();
5135         try {
5136             if (mImsResolver == null) {
5137                 // may happen if the device does not support IMS.
5138                 return "";
5139             }
5140             // TODO: change API to query RCS separately.
5141             return mImsResolver.getImsServiceConfiguration(slotId, isCarrierImsService,
5142                     featureType);
5143         } finally {
5144             Binder.restoreCallingIdentity(identity);
5145         }
5146     }
5147 
5148     /**
5149      * Get the MmTelFeature state associated with the requested subscription id.
5150      * @param subId The subscription that the MmTelFeature is associated with.
5151      * @param callback A callback with an integer containing the
5152      * {@link android.telephony.ims.feature.ImsFeature.ImsState} associated with the MmTelFeature.
5153      */
5154     @Override
getImsMmTelFeatureState(int subId, IIntegerConsumer callback)5155     public void getImsMmTelFeatureState(int subId, IIntegerConsumer callback) {
5156         enforceReadPrivilegedPermission("getImsMmTelFeatureState");
5157         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
5158             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5159                     "IMS not available on device.");
5160         }
5161         final long token = Binder.clearCallingIdentity();
5162         try {
5163             int slotId = getSlotIndex(subId);
5164             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5165                 Log.w(LOG_TAG, "getImsMmTelFeatureState: called with an inactive subscription '"
5166                         + subId + "'");
5167                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
5168             }
5169             ImsManager.getInstance(mApp, slotId).getImsServiceState(anInteger -> {
5170                 try {
5171                     callback.accept(anInteger == null ? ImsFeature.STATE_UNAVAILABLE : anInteger);
5172                 } catch (RemoteException e) {
5173                     Log.w(LOG_TAG, "getImsMmTelFeatureState: remote caller is no longer running. "
5174                             + "Ignore");
5175                 }
5176             });
5177         } finally {
5178             Binder.restoreCallingIdentity(token);
5179         }
5180     }
5181 
setImsRegistrationState(boolean registered)5182     public void setImsRegistrationState(boolean registered) {
5183         enforceModifyPermission();
5184 
5185         final long identity = Binder.clearCallingIdentity();
5186         try {
5187             getDefaultPhone().setImsRegistrationState(registered);
5188         } finally {
5189             Binder.restoreCallingIdentity(identity);
5190         }
5191     }
5192 
5193     /**
5194      * Set the network selection mode to automatic.
5195      *
5196      */
5197     @Override
setNetworkSelectionModeAutomatic(int subId)5198     public void setNetworkSelectionModeAutomatic(int subId) {
5199         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5200                 mApp, subId, "setNetworkSelectionModeAutomatic");
5201 
5202         final long identity = Binder.clearCallingIdentity();
5203         try {
5204             if (!isActiveSubscription(subId)) {
5205                 return;
5206             }
5207             if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
5208             sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
5209         } finally {
5210             Binder.restoreCallingIdentity(identity);
5211         }
5212     }
5213 
5214    /**
5215      * Ask the radio to connect to the input network and change selection mode to manual.
5216      *
5217      * @param subId the id of the subscription.
5218      * @param operatorInfo the operator information, included the PLMN, long name and short name of
5219      * the operator to attach to.
5220      * @param persistSelection whether the selection will persist until reboot. If true, only allows
5221      * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
5222      * normal network selection next time.
5223      * @return {@code true} on success; {@code true} on any failure.
5224      */
5225     @Override
setNetworkSelectionModeManual( int subId, OperatorInfo operatorInfo, boolean persistSelection)5226     public boolean setNetworkSelectionModeManual(
5227             int subId, OperatorInfo operatorInfo, boolean persistSelection) {
5228         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5229                 mApp, subId, "setNetworkSelectionModeManual");
5230 
5231         if (!isActiveSubscription(subId)) {
5232             return false;
5233         }
5234 
5235         final long identity = Binder.clearCallingIdentity();
5236         try {
5237             ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
5238                     persistSelection);
5239             if (DBG) {
5240                 log("setNetworkSelectionModeManual: subId: " + subId
5241                         + " operator: " + operatorInfo);
5242             }
5243             return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
5244         } finally {
5245             Binder.restoreCallingIdentity(identity);
5246         }
5247     }
5248      /**
5249      * Get the manual network selection
5250      *
5251      * @param subId the id of the subscription.
5252      *
5253      * @return the previously saved user selected PLMN
5254      */
5255     @Override
getManualNetworkSelectionPlmn(int subId)5256     public String getManualNetworkSelectionPlmn(int subId) {
5257         TelephonyPermissions
5258                     .enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5259                     mApp, subId, "getManualNetworkSelectionPlmn");
5260 
5261         final long identity = Binder.clearCallingIdentity();
5262         try {
5263             if (!isActiveSubscription(subId)) {
5264                 return "";
5265             }
5266 
5267             final Phone phone = getPhone(subId);
5268             if (phone == null) {
5269                 return "";
5270             }
5271             OperatorInfo networkSelection = phone.getSavedNetworkSelection();
5272             return TextUtils.isEmpty(networkSelection.getOperatorNumeric())
5273                 ? phone.getManualNetworkSelectionPlmn() : networkSelection.getOperatorNumeric();
5274         } finally {
5275             Binder.restoreCallingIdentity(identity);
5276         }
5277     }
5278 
5279     /**
5280      * Scans for available networks.
5281      */
5282     @Override
getCellNetworkScanResults(int subId, String callingPackage, String callingFeatureId)5283     public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage,
5284             String callingFeatureId) {
5285         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5286                 mApp, subId, "getCellNetworkScanResults");
5287         LocationAccessPolicy.LocationPermissionResult locationResult =
5288                 LocationAccessPolicy.checkLocationPermission(mApp,
5289                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
5290                                 .setCallingPackage(callingPackage)
5291                                 .setCallingFeatureId(callingFeatureId)
5292                                 .setCallingPid(Binder.getCallingPid())
5293                                 .setCallingUid(Binder.getCallingUid())
5294                                 .setMethod("getCellNetworkScanResults")
5295                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
5296                                 .build());
5297         switch (locationResult) {
5298             case DENIED_HARD:
5299                 throw new SecurityException("Not allowed to access scan results -- location");
5300             case DENIED_SOFT:
5301                 return null;
5302         }
5303 
5304         long identity = Binder.clearCallingIdentity();
5305         try {
5306             if (DBG) log("getCellNetworkScanResults: subId " + subId);
5307             return (CellNetworkScanResult) sendRequest(
5308                     CMD_PERFORM_NETWORK_SCAN, null, subId);
5309         } finally {
5310             Binder.restoreCallingIdentity(identity);
5311         }
5312     }
5313 
5314     /**
5315      * Get the call forwarding info, given the call forwarding reason.
5316      */
5317     @Override
getCallForwarding(int subId, int callForwardingReason)5318     public CallForwardingInfo getCallForwarding(int subId, int callForwardingReason) {
5319         enforceReadPrivilegedPermission("getCallForwarding");
5320         long identity = Binder.clearCallingIdentity();
5321         try {
5322             if (DBG) {
5323                 log("getCallForwarding: subId " + subId
5324                         + " callForwardingReason" + callForwardingReason);
5325             }
5326             return (CallForwardingInfo) sendRequest(
5327                     CMD_GET_CALL_FORWARDING, callForwardingReason, subId);
5328         } finally {
5329             Binder.restoreCallingIdentity(identity);
5330         }
5331     }
5332 
5333     /**
5334      * Sets the voice call forwarding info including status (enable/disable), call forwarding
5335      * reason, the number to forward, and the timeout before the forwarding is attempted.
5336      */
5337     @Override
setCallForwarding(int subId, CallForwardingInfo callForwardingInfo)5338     public boolean setCallForwarding(int subId, CallForwardingInfo callForwardingInfo) {
5339         enforceModifyPermission();
5340         long identity = Binder.clearCallingIdentity();
5341         try {
5342             if (DBG) {
5343                 log("setCallForwarding: subId " + subId
5344                         + " callForwardingInfo" + callForwardingInfo);
5345             }
5346             return (Boolean) sendRequest(CMD_SET_CALL_FORWARDING, callForwardingInfo, subId);
5347         } finally {
5348             Binder.restoreCallingIdentity(identity);
5349         }
5350     }
5351 
5352     /**
5353      * Get the call forwarding info, given the call forwarding reason.
5354      */
5355     @Override
getCallWaitingStatus(int subId)5356     public int getCallWaitingStatus(int subId) {
5357         enforceReadPrivilegedPermission("getCallForwarding");
5358         long identity = Binder.clearCallingIdentity();
5359         try {
5360             if (DBG) log("getCallWaitingStatus: subId " + subId);
5361             return (Integer) sendRequest(CMD_GET_CALL_WAITING, null, subId);
5362         } finally {
5363             Binder.restoreCallingIdentity(identity);
5364         }
5365     }
5366 
5367     /**
5368      * Sets the voice call forwarding info including status (enable/disable), call forwarding
5369      * reason, the number to forward, and the timeout before the forwarding is attempted.
5370      */
5371     @Override
setCallWaitingStatus(int subId, boolean isEnable)5372     public boolean setCallWaitingStatus(int subId, boolean isEnable) {
5373         enforceModifyPermission();
5374         long identity = Binder.clearCallingIdentity();
5375         try {
5376             if (DBG) log("setCallWaitingStatus: subId " + subId + " isEnable: " + isEnable);
5377             return (Boolean) sendRequest(CMD_SET_CALL_WAITING, isEnable, subId);
5378         } finally {
5379             Binder.restoreCallingIdentity(identity);
5380         }
5381     }
5382 
5383     /**
5384      * Starts a new network scan and returns the id of this scan.
5385      *
5386      * @param subId id of the subscription
5387      * @param request contains the radio access networks with bands/channels to scan
5388      * @param messenger callback messenger for scan results or errors
5389      * @param binder for the purpose of auto clean when the user thread crashes
5390      * @return the id of the requested scan which can be used to stop the scan.
5391      */
5392     @Override
requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger, IBinder binder, String callingPackage, String callingFeatureId)5393     public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
5394             IBinder binder, String callingPackage, String callingFeatureId) {
5395         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5396                 mApp, subId, "requestNetworkScan");
5397         LocationAccessPolicy.LocationPermissionResult locationResult =
5398                 LocationAccessPolicy.checkLocationPermission(mApp,
5399                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
5400                                 .setCallingPackage(callingPackage)
5401                                 .setCallingFeatureId(callingFeatureId)
5402                                 .setCallingPid(Binder.getCallingPid())
5403                                 .setCallingUid(Binder.getCallingUid())
5404                                 .setMethod("requestNetworkScan")
5405                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
5406                                 .build());
5407         if (locationResult != LocationAccessPolicy.LocationPermissionResult.ALLOWED) {
5408             SecurityException e = checkNetworkRequestForSanitizedLocationAccess(request, subId);
5409             if (e != null) {
5410                 if (locationResult == LocationAccessPolicy.LocationPermissionResult.DENIED_HARD) {
5411                     throw e;
5412                 } else {
5413                     loge(e.getMessage());
5414                     return TelephonyScanManager.INVALID_SCAN_ID;
5415                 }
5416             }
5417         }
5418         int callingUid = Binder.getCallingUid();
5419         int callingPid = Binder.getCallingPid();
5420         final long identity = Binder.clearCallingIdentity();
5421         try {
5422             return mNetworkScanRequestTracker.startNetworkScan(
5423                     request, messenger, binder, getPhone(subId),
5424                     callingUid, callingPid, callingPackage);
5425         } finally {
5426             Binder.restoreCallingIdentity(identity);
5427         }
5428     }
5429 
checkNetworkRequestForSanitizedLocationAccess( NetworkScanRequest request, int subId)5430     private SecurityException checkNetworkRequestForSanitizedLocationAccess(
5431             NetworkScanRequest request, int subId) {
5432         boolean hasCarrierPriv = getCarrierPrivilegeStatusForUid(subId, Binder.getCallingUid())
5433                 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
5434         boolean hasNetworkScanPermission =
5435                 mApp.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SCAN)
5436                 == PERMISSION_GRANTED;
5437 
5438         if (!hasCarrierPriv && !hasNetworkScanPermission) {
5439             return new SecurityException("permission.NETWORK_SCAN or carrier privileges is needed"
5440                     + " for network scans without location access.");
5441         }
5442 
5443         if (request.getSpecifiers() != null && request.getSpecifiers().length > 0) {
5444             for (RadioAccessSpecifier ras : request.getSpecifiers()) {
5445                 if (ras.getChannels() != null && ras.getChannels().length > 0) {
5446                     return new SecurityException("Specific channels must not be"
5447                             + " scanned without location access.");
5448                 }
5449             }
5450         }
5451 
5452         return null;
5453     }
5454 
5455     /**
5456      * Stops an existing network scan with the given scanId.
5457      *
5458      * @param subId id of the subscription
5459      * @param scanId id of the scan that needs to be stopped
5460      */
5461     @Override
stopNetworkScan(int subId, int scanId)5462     public void stopNetworkScan(int subId, int scanId) {
5463         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5464                 mApp, subId, "stopNetworkScan");
5465 
5466         int callingUid = Binder.getCallingUid();
5467         final long identity = Binder.clearCallingIdentity();
5468         try {
5469             mNetworkScanRequestTracker.stopNetworkScan(scanId, callingUid);
5470         } finally {
5471             Binder.restoreCallingIdentity(identity);
5472         }
5473     }
5474 
5475     /**
5476      * Get the calculated preferred network type.
5477      * Used for debugging incorrect network type.
5478      *
5479      * @return the preferred network type, defined in RILConstants.java.
5480      */
5481     @Override
getCalculatedPreferredNetworkType(String callingPackage, String callingFeatureId)5482     public int getCalculatedPreferredNetworkType(String callingPackage, String callingFeatureId) {
5483         final Phone defaultPhone = getDefaultPhone();
5484         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
5485                 callingPackage, callingFeatureId, "getCalculatedPreferredNetworkType")) {
5486             return RILConstants.PREFERRED_NETWORK_MODE;
5487         }
5488 
5489         final long identity = Binder.clearCallingIdentity();
5490         try {
5491             // FIXME: need to get SubId from somewhere.
5492             return PhoneFactory.calculatePreferredNetworkType(defaultPhone.getContext(), 0);
5493         } finally {
5494             Binder.restoreCallingIdentity(identity);
5495         }
5496     }
5497 
5498     /**
5499      * Get the preferred network type.
5500      * Used for device configuration by some CDMA operators.
5501      *
5502      * @return the preferred network type, defined in RILConstants.java.
5503      */
5504     @Override
getPreferredNetworkType(int subId)5505     public int getPreferredNetworkType(int subId) {
5506         TelephonyPermissions
5507                 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5508                         mApp, subId, "getPreferredNetworkType");
5509 
5510         final long identity = Binder.clearCallingIdentity();
5511         try {
5512             if (DBG) log("getPreferredNetworkType");
5513             int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
5514             int networkType = (result != null ? result[0] : -1);
5515             if (DBG) log("getPreferredNetworkType: " + networkType);
5516             return networkType;
5517         } finally {
5518             Binder.restoreCallingIdentity(identity);
5519         }
5520     }
5521 
5522     /**
5523      * Set the preferred network type.
5524      *
5525      * @param networkType the preferred network type, defined in RILConstants.java.
5526      * @return true on success; false on any failure.
5527      */
5528     @Override
setPreferredNetworkType(int subId, int networkType)5529     public boolean setPreferredNetworkType(int subId, int networkType) {
5530         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5531                 mApp, subId, "setPreferredNetworkType");
5532 
5533         final long identity = Binder.clearCallingIdentity();
5534         try {
5535             Settings.Global.putInt(mApp.getContentResolver(),
5536                     Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
5537 
5538             Boolean success = (Boolean) sendRequest(
5539                     CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
5540             if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
5541             return success;
5542         } finally {
5543             Binder.restoreCallingIdentity(identity);
5544         }
5545     }
5546 
5547     /**
5548      * Get the allowed network types that store in the telephony provider.
5549      *
5550      * @param subId the id of the subscription.
5551      * @return allowedNetworkTypes the allowed network types.
5552      */
5553     @Override
getAllowedNetworkTypes(int subId)5554     public long getAllowedNetworkTypes(int subId) {
5555         TelephonyPermissions
5556                 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5557                     mApp, subId, "getAllowedNetworkTypes");
5558 
5559         final long identity = Binder.clearCallingIdentity();
5560         try {
5561             return SubscriptionManager.getLongSubscriptionProperty(
5562                     subId, SubscriptionManager.ALLOWED_NETWORK_TYPES, -1, mApp);
5563         } finally {
5564             Binder.restoreCallingIdentity(identity);
5565         }
5566     }
5567 
5568     /**
5569      * Set the allowed network types.
5570      *
5571      * @param subId the id of the subscription.
5572      * @param allowedNetworkTypes the allowed network types.
5573      * @return true on success; false on any failure.
5574      */
5575     @Override
setAllowedNetworkTypes(int subId, long allowedNetworkTypes)5576     public boolean setAllowedNetworkTypes(int subId, long allowedNetworkTypes) {
5577         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5578                 mApp, subId, "setAllowedNetworkTypes");
5579 
5580         SubscriptionManager.setSubscriptionProperty(subId,
5581                 SubscriptionManager.ALLOWED_NETWORK_TYPES,
5582                 String.valueOf(allowedNetworkTypes));
5583 
5584         int preferredNetworkMode = Settings.Global.getInt(mApp.getContentResolver(),
5585                 Settings.Global.PREFERRED_NETWORK_MODE + subId,
5586                 RILConstants.PREFERRED_NETWORK_MODE);
5587         return setPreferredNetworkType(subId, preferredNetworkMode);
5588     }
5589 
5590     /**
5591      * Get the allowed network types for certain reason.
5592      *
5593      * @param subId the id of the subscription.
5594      * @param reason the reason the allowed network type change is taking place
5595      * @return the allowed network types.
5596      */
5597     @Override
getAllowedNetworkTypesForReason(int subId, @TelephonyManager.AllowedNetworkTypesReason int reason)5598     public long getAllowedNetworkTypesForReason(int subId,
5599             @TelephonyManager.AllowedNetworkTypesReason int reason) {
5600         TelephonyPermissions
5601                 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5602                         mApp, subId, "getAllowedNetworkTypesForReason");
5603         final long identity = Binder.clearCallingIdentity();
5604         try {
5605             return getPhoneFromSubId(subId).getAllowedNetworkTypes(reason);
5606         } finally {
5607             Binder.restoreCallingIdentity(identity);
5608         }
5609     }
5610 
5611     /**
5612      * Get the effective allowed network types on the device.
5613      * This API will return an intersection of allowed network types for all reasons,
5614      * including the configuration done through setAllowedNetworkTypes
5615      *
5616      * @param subId the id of the subscription.
5617      * @return the allowed network types
5618      */
5619     @Override
getEffectiveAllowedNetworkTypes(int subId)5620     public long getEffectiveAllowedNetworkTypes(int subId) {
5621         TelephonyPermissions
5622                 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5623                         mApp, subId, "getEffectiveAllowedNetworkTypes");
5624         final long identity = Binder.clearCallingIdentity();
5625         try {
5626             return getPhoneFromSubId(subId).getEffectiveAllowedNetworkTypes();
5627         } finally {
5628             Binder.restoreCallingIdentity(identity);
5629         }
5630     }
5631 
5632     /**
5633      * Set the allowed network types of the device and
5634      * provide the reason triggering the allowed network change.
5635      *
5636      * @param subId the id of the subscription.
5637      * @param reason the reason the allowed network type change is taking place
5638      * @param allowedNetworkTypes the allowed network types.
5639      * @return true on success; false on any failure.
5640      */
5641     @Override
setAllowedNetworkTypesForReason(int subId, @TelephonyManager.AllowedNetworkTypesReason int reason, long allowedNetworkTypes)5642     public boolean setAllowedNetworkTypesForReason(int subId,
5643             @TelephonyManager.AllowedNetworkTypesReason int reason, long allowedNetworkTypes) {
5644         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5645                 mApp, subId, "setAllowedNetworkTypesForReason");
5646         final long identity = Binder.clearCallingIdentity();
5647         try {
5648             getPhoneFromSubId(subId).setAllowedNetworkTypes(reason, allowedNetworkTypes);
5649             int preferredNetworkMode = Settings.Global.getInt(mApp.getContentResolver(),
5650                     Settings.Global.PREFERRED_NETWORK_MODE + subId,
5651                     RILConstants.PREFERRED_NETWORK_MODE);
5652             return setPreferredNetworkType(subId, preferredNetworkMode);
5653         } finally {
5654             Binder.restoreCallingIdentity(identity);
5655         }
5656     }
5657 
5658     /**
5659      * Check whether DUN APN is required for tethering with subId.
5660      *
5661      * @param subId the id of the subscription to require tethering.
5662      * @return {@code true} if DUN APN is required for tethering.
5663      * @hide
5664      */
5665     @Override
isTetheringApnRequiredForSubscriber(int subId)5666     public boolean isTetheringApnRequiredForSubscriber(int subId) {
5667         enforceModifyPermission();
5668         final long identity = Binder.clearCallingIdentity();
5669         final Phone phone = getPhone(subId);
5670         try {
5671             if (phone != null) {
5672                 return phone.hasMatchedTetherApnSetting();
5673             } else {
5674                 return false;
5675             }
5676         } finally {
5677             Binder.restoreCallingIdentity(identity);
5678         }
5679     }
5680 
5681     /**
5682      * Set mobile data enabled
5683      * Used by the user through settings etc to turn on/off mobile data
5684      *
5685      * @param enable {@code true} turn turn data on, else {@code false}
5686      */
5687     @Override
setUserDataEnabled(int subId, boolean enable)5688     public void setUserDataEnabled(int subId, boolean enable) {
5689         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5690                 mApp, subId, "setUserDataEnabled");
5691 
5692         final long identity = Binder.clearCallingIdentity();
5693         try {
5694             int phoneId = mSubscriptionController.getPhoneId(subId);
5695             if (DBG) log("setUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
5696             Phone phone = PhoneFactory.getPhone(phoneId);
5697             if (phone != null) {
5698                 if (DBG) log("setUserDataEnabled: subId=" + subId + " enable=" + enable);
5699                 phone.getDataEnabledSettings().setUserDataEnabled(enable);
5700             } else {
5701                 loge("setUserDataEnabled: no phone found. Invalid subId=" + subId);
5702             }
5703         } finally {
5704             Binder.restoreCallingIdentity(identity);
5705         }
5706     }
5707 
5708     /**
5709      * Enable or disable always reporting signal strength changes from radio.
5710      *
5711      * @param isEnable {@code true} for enabling; {@code false} for disabling.
5712      */
5713     @Override
setAlwaysReportSignalStrength(int subId, boolean isEnable)5714     public void setAlwaysReportSignalStrength(int subId, boolean isEnable) {
5715         enforceModifyPermission();
5716         enforceSystemCaller();
5717 
5718         final long identity = Binder.clearCallingIdentity();
5719         final Phone phone = getPhone(subId);
5720         try {
5721             if (phone != null) {
5722                 if (DBG) {
5723                     log("setAlwaysReportSignalStrength: subId=" + subId
5724                             + " isEnable=" + isEnable);
5725                 }
5726                 phone.setAlwaysReportSignalStrength(isEnable);
5727             } else {
5728                 loge("setAlwaysReportSignalStrength: no phone found for subId="
5729                         + subId);
5730             }
5731         } finally {
5732             Binder.restoreCallingIdentity(identity);
5733         }
5734     }
5735 
5736     /**
5737      * Get the user enabled state of Mobile Data.
5738      *
5739      * TODO: remove and use isUserDataEnabled.
5740      * This can't be removed now because some vendor codes
5741      * calls through ITelephony directly while they should
5742      * use TelephonyManager.
5743      *
5744      * @return true on enabled
5745      */
5746     @Override
getDataEnabled(int subId)5747     public boolean getDataEnabled(int subId) {
5748         return isUserDataEnabled(subId);
5749     }
5750 
5751     /**
5752      * Get whether mobile data is enabled per user setting.
5753      *
5754      * There are other factors deciding whether mobile data is actually enabled, but they are
5755      * not considered here. See {@link #isDataEnabled(int)} for more details.
5756      *
5757      * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
5758      *
5759      * @return {@code true} if data is enabled else {@code false}
5760      */
5761     @Override
isUserDataEnabled(int subId)5762     public boolean isUserDataEnabled(int subId) {
5763         try {
5764             mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
5765                     null);
5766         } catch (Exception e) {
5767             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5768                     mApp, subId, "isUserDataEnabled");
5769         }
5770 
5771         final long identity = Binder.clearCallingIdentity();
5772         try {
5773             int phoneId = mSubscriptionController.getPhoneId(subId);
5774             if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
5775             Phone phone = PhoneFactory.getPhone(phoneId);
5776             if (phone != null) {
5777                 boolean retVal = phone.isUserDataEnabled();
5778                 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
5779                 return retVal;
5780             } else {
5781                 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
5782                 return false;
5783             }
5784         } finally {
5785             Binder.restoreCallingIdentity(identity);
5786         }
5787     }
5788 
5789     /**
5790      * Checks if the device is capable of mobile data by considering whether whether the
5791      * user has enabled mobile data, whether the carrier has enabled mobile data, and
5792      * whether the network policy allows data connections.
5793      *
5794      * @return {@code true} if the overall data connection is capable; {@code false} if not.
5795      */
5796     @Override
isDataEnabled(int subId)5797     public boolean isDataEnabled(int subId) {
5798         enforceReadPrivilegedPermission("isDataEnabled");
5799 
5800         final long identity = Binder.clearCallingIdentity();
5801         try {
5802             int phoneId = mSubscriptionController.getPhoneId(subId);
5803             if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
5804             Phone phone = PhoneFactory.getPhone(phoneId);
5805             if (phone != null) {
5806                 boolean retVal = phone.getDataEnabledSettings().isDataEnabled();
5807                 if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
5808                 return retVal;
5809             } else {
5810                 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
5811                 return false;
5812             }
5813         } finally {
5814             Binder.restoreCallingIdentity(identity);
5815         }
5816     }
5817 
getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, int uid, Phone phone)5818     private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, int uid,
5819             Phone phone) {
5820         if (uid == Process.SYSTEM_UID || uid == Process.PHONE_UID) {
5821             // Skip the check if it's one of these special uids
5822             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
5823         }
5824 
5825         //load access rules from carrier configs, and check those as well: b/139133814
5826         SubscriptionController subController = SubscriptionController.getInstance();
5827         if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
5828                 || subController == null) return privilegeFromSim;
5829 
5830         PackageManager pkgMgr = phone.getContext().getPackageManager();
5831         String[] packages = pkgMgr.getPackagesForUid(uid);
5832 
5833         final long identity = Binder.clearCallingIdentity();
5834         try {
5835             SubscriptionInfo subInfo = subController.getSubscriptionInfo(phone.getSubId());
5836             SubscriptionManager subManager = (SubscriptionManager)
5837                     phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
5838             for (String pkg : packages) {
5839                 if (subManager.canManageSubscription(subInfo, pkg)) {
5840                     return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
5841                 }
5842             }
5843             return privilegeFromSim;
5844         } finally {
5845             Binder.restoreCallingIdentity(identity);
5846         }
5847     }
5848 
getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, Phone phone, String pkgName)5849     private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, Phone phone,
5850             String pkgName) {
5851         //load access rules from carrier configs, and check those as well: b/139133814
5852         SubscriptionController subController = SubscriptionController.getInstance();
5853         if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
5854                 || subController == null) return privilegeFromSim;
5855 
5856         final long identity = Binder.clearCallingIdentity();
5857         try {
5858             SubscriptionInfo subInfo = subController.getSubscriptionInfo(phone.getSubId());
5859             SubscriptionManager subManager = (SubscriptionManager)
5860                     phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
5861             return subManager.canManageSubscription(subInfo, pkgName)
5862                 ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS : privilegeFromSim;
5863         } finally {
5864             Binder.restoreCallingIdentity(identity);
5865         }
5866     }
5867 
5868     @Override
getCarrierPrivilegeStatus(int subId)5869     public int getCarrierPrivilegeStatus(int subId) {
5870         final Phone phone = getPhone(subId);
5871         if (phone == null) {
5872             loge("getCarrierPrivilegeStatus: Invalid subId");
5873             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
5874         }
5875         UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
5876         if (card == null) {
5877             loge("getCarrierPrivilegeStatus: No UICC");
5878             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
5879         }
5880 
5881         return getCarrierPrivilegeStatusFromCarrierConfigRules(
5882             card.getCarrierPrivilegeStatusForCurrentTransaction(
5883                 phone.getContext().getPackageManager()), Binder.getCallingUid(), phone);
5884     }
5885 
5886     @Override
getCarrierPrivilegeStatusForUid(int subId, int uid)5887     public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
5888         enforceReadPrivilegedPermission("getCarrierPrivilegeStatusForUid");
5889         final Phone phone = getPhone(subId);
5890         if (phone == null) {
5891             loge("getCarrierPrivilegeStatusForUid: Invalid subId");
5892             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
5893         }
5894         UiccProfile profile =
5895                 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
5896         if (profile == null) {
5897             loge("getCarrierPrivilegeStatusForUid: No UICC");
5898             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
5899         }
5900         return getCarrierPrivilegeStatusFromCarrierConfigRules(
5901                 profile.getCarrierPrivilegeStatusForUid(
5902                         phone.getContext().getPackageManager(), uid), uid, phone);
5903     }
5904 
5905     @Override
checkCarrierPrivilegesForPackage(int subId, String pkgName)5906     public int checkCarrierPrivilegesForPackage(int subId, String pkgName) {
5907         if (TextUtils.isEmpty(pkgName)) {
5908             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
5909         }
5910 
5911         int phoneId = SubscriptionManager.getPhoneId(subId);
5912         UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
5913         if (card == null) {
5914             loge("checkCarrierPrivilegesForPackage: No UICC on subId " + subId);
5915             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
5916         }
5917         return getCarrierPrivilegeStatusFromCarrierConfigRules(
5918             card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
5919             getPhone(phoneId), pkgName);
5920     }
5921 
5922     @Override
checkCarrierPrivilegesForPackageAnyPhone(String pkgName)5923     public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
5924         if (TextUtils.isEmpty(pkgName))
5925             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
5926         int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
5927         for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
5928             UiccCard card = UiccController.getInstance().getUiccCard(i);
5929             if (card == null) {
5930               // No UICC in that slot.
5931               continue;
5932             }
5933 
5934             result = getCarrierPrivilegeStatusFromCarrierConfigRules(
5935                 card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
5936                 getPhone(i), pkgName);
5937             if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
5938                 break;
5939             }
5940         }
5941 
5942         return result;
5943     }
5944 
5945     @Override
getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId)5946     public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
5947         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
5948             loge("phoneId " + phoneId + " is not valid.");
5949             return null;
5950         }
5951         UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
5952         if (card == null) {
5953             loge("getCarrierPackageNamesForIntentAndPhone: No UICC");
5954             return null ;
5955         }
5956         return card.getCarrierPackageNamesForIntent(mApp.getPackageManager(), intent);
5957     }
5958 
5959     @Override
getPackagesWithCarrierPrivileges(int phoneId)5960     public List<String> getPackagesWithCarrierPrivileges(int phoneId) {
5961         PackageManager pm = mApp.getPackageManager();
5962         List<String> privilegedPackages = new ArrayList<>();
5963         List<PackageInfo> packages = null;
5964         UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
5965         // has UICC in that slot.
5966         if (card != null) {
5967             if (card.hasCarrierPrivilegeRules()) {
5968                 if (packages == null) {
5969                     // Only check packages in user 0 for now
5970                     packages = pm.getInstalledPackagesAsUser(
5971                         PackageManager.MATCH_DISABLED_COMPONENTS
5972                             | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
5973                             | PackageManager.GET_SIGNING_CERTIFICATES,
5974                             UserHandle.SYSTEM.getIdentifier());
5975                 }
5976                 for (int p = packages.size() - 1; p >= 0; p--) {
5977                     PackageInfo pkgInfo = packages.get(p);
5978                     if (pkgInfo != null && pkgInfo.packageName != null
5979                             && card.getCarrierPrivilegeStatus(pkgInfo)
5980                             == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
5981                         privilegedPackages.add(pkgInfo.packageName);
5982                     }
5983                 }
5984             }
5985         }
5986         return privilegedPackages;
5987     }
5988 
5989     @Override
getPackagesWithCarrierPrivilegesForAllPhones()5990     public List<String> getPackagesWithCarrierPrivilegesForAllPhones() {
5991         enforceReadPrivilegedPermission("getPackagesWithCarrierPrivilegesForAllPhones");
5992 
5993         final long identity = Binder.clearCallingIdentity();
5994 
5995         List<String> privilegedPackages = new ArrayList<>();
5996         try {
5997             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
5998                 privilegedPackages.addAll(getPackagesWithCarrierPrivileges(i));
5999             }
6000         } finally {
6001             Binder.restoreCallingIdentity(identity);
6002         }
6003         return privilegedPackages;
6004     }
6005 
getIccId(int subId)6006     private String getIccId(int subId) {
6007         final Phone phone = getPhone(subId);
6008         UiccCard card = phone == null ? null : phone.getUiccCard();
6009         if (card == null) {
6010             loge("getIccId: No UICC");
6011             return null;
6012         }
6013         String iccId = card.getIccId();
6014         if (TextUtils.isEmpty(iccId)) {
6015             loge("getIccId: ICC ID is null or empty.");
6016             return null;
6017         }
6018         return iccId;
6019     }
6020 
6021     @Override
setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, String number)6022     public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
6023             String number) {
6024         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
6025                 subId, "setLine1NumberForDisplayForSubscriber");
6026 
6027         final long identity = Binder.clearCallingIdentity();
6028         try {
6029             final String iccId = getIccId(subId);
6030             final Phone phone = getPhone(subId);
6031             if (phone == null) {
6032                 return false;
6033             }
6034             final String subscriberId = phone.getSubscriberId();
6035 
6036             if (DBG_MERGE) {
6037                 Rlog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
6038                         + subscriberId + " to " + number);
6039             }
6040 
6041             if (TextUtils.isEmpty(iccId)) {
6042                 return false;
6043             }
6044 
6045             final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
6046 
6047             final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
6048             if (alphaTag == null) {
6049                 editor.remove(alphaTagPrefKey);
6050             } else {
6051                 editor.putString(alphaTagPrefKey, alphaTag);
6052             }
6053 
6054             // Record both the line number and IMSI for this ICCID, since we need to
6055             // track all merged IMSIs based on line number
6056             final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
6057             final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
6058             if (number == null) {
6059                 editor.remove(numberPrefKey);
6060                 editor.remove(subscriberPrefKey);
6061             } else {
6062                 editor.putString(numberPrefKey, number);
6063                 editor.putString(subscriberPrefKey, subscriberId);
6064             }
6065 
6066             editor.commit();
6067             return true;
6068         } finally {
6069             Binder.restoreCallingIdentity(identity);
6070         }
6071     }
6072 
6073     @Override
getLine1NumberForDisplay(int subId, String callingPackage, String callingFeatureId)6074     public String getLine1NumberForDisplay(int subId, String callingPackage,
6075             String callingFeatureId) {
6076         // This is open to apps with WRITE_SMS.
6077         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
6078                 mApp, subId, callingPackage, callingFeatureId, "getLine1NumberForDisplay")) {
6079             if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
6080             return null;
6081         }
6082 
6083         final long identity = Binder.clearCallingIdentity();
6084         try {
6085             String iccId = getIccId(subId);
6086             if (iccId != null) {
6087                 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
6088                 if (DBG_MERGE) {
6089                     log("getLine1NumberForDisplay returning "
6090                             + mTelephonySharedPreferences.getString(numberPrefKey, null));
6091                 }
6092                 return mTelephonySharedPreferences.getString(numberPrefKey, null);
6093             }
6094             if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
6095             return null;
6096         } finally {
6097             Binder.restoreCallingIdentity(identity);
6098         }
6099     }
6100 
6101     @Override
getLine1AlphaTagForDisplay(int subId, String callingPackage, String callingFeatureId)6102     public String getLine1AlphaTagForDisplay(int subId, String callingPackage,
6103             String callingFeatureId) {
6104         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6105                 mApp, subId, callingPackage, callingFeatureId, "getLine1AlphaTagForDisplay")) {
6106             return null;
6107         }
6108 
6109         final long identity = Binder.clearCallingIdentity();
6110         try {
6111             String iccId = getIccId(subId);
6112             if (iccId != null) {
6113                 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
6114                 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
6115             }
6116             return null;
6117         } finally {
6118             Binder.restoreCallingIdentity(identity);
6119         }
6120     }
6121 
6122     @Override
getMergedSubscriberIds(int subId, String callingPackage, String callingFeatureId)6123     public String[] getMergedSubscriberIds(int subId, String callingPackage,
6124             String callingFeatureId) {
6125         // This API isn't public, so no need to provide a valid subscription ID - we're not worried
6126         // about carrier-privileged callers not having access.
6127         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6128                 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
6129                 callingFeatureId, "getMergedSubscriberIds")) {
6130             return null;
6131         }
6132 
6133         // Clear calling identity, when calling TelephonyManager, because callerUid must be
6134         // the process, where TelephonyManager was instantiated.
6135         // Otherwise AppOps check will fail.
6136         final long identity  = Binder.clearCallingIdentity();
6137         try {
6138             final Context context = mApp;
6139             final TelephonyManager tele = TelephonyManager.from(context);
6140             final SubscriptionManager sub = SubscriptionManager.from(context);
6141 
6142             // Figure out what subscribers are currently active
6143             final ArraySet<String> activeSubscriberIds = new ArraySet<>();
6144 
6145             // Only consider subs which match the current subId
6146             // This logic can be simplified. See b/131189269 for progress.
6147             if (isActiveSubscription(subId)) {
6148                 activeSubscriberIds.add(tele.getSubscriberId(subId));
6149             }
6150 
6151             // First pass, find a number override for an active subscriber
6152             String mergeNumber = null;
6153             final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
6154             for (String key : prefs.keySet()) {
6155                 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
6156                     final String subscriberId = (String) prefs.get(key);
6157                     if (activeSubscriberIds.contains(subscriberId)) {
6158                         final String iccId = key.substring(
6159                                 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
6160                         final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
6161                         mergeNumber = (String) prefs.get(numberKey);
6162                         if (DBG_MERGE) {
6163                             Rlog.d(LOG_TAG, "Found line number " + mergeNumber
6164                                     + " for active subscriber " + subscriberId);
6165                         }
6166                         if (!TextUtils.isEmpty(mergeNumber)) {
6167                             break;
6168                         }
6169                     }
6170                 }
6171             }
6172 
6173             // Shortcut when no active merged subscribers
6174             if (TextUtils.isEmpty(mergeNumber)) {
6175                 return null;
6176             }
6177 
6178             // Second pass, find all subscribers under that line override
6179             final ArraySet<String> result = new ArraySet<>();
6180             for (String key : prefs.keySet()) {
6181                 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
6182                     final String number = (String) prefs.get(key);
6183                     if (mergeNumber.equals(number)) {
6184                         final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
6185                         final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
6186                         final String subscriberId = (String) prefs.get(subscriberKey);
6187                         if (!TextUtils.isEmpty(subscriberId)) {
6188                             result.add(subscriberId);
6189                         }
6190                     }
6191                 }
6192             }
6193 
6194             final String[] resultArray = result.toArray(new String[result.size()]);
6195             Arrays.sort(resultArray);
6196             if (DBG_MERGE) {
6197                 Rlog.d(LOG_TAG,
6198                         "Found subscribers " + Arrays.toString(resultArray) + " after merge");
6199             }
6200             return resultArray;
6201         } finally {
6202             Binder.restoreCallingIdentity(identity);
6203         }
6204     }
6205 
6206     @Override
getMergedImsisFromGroup(int subId, String callingPackage)6207     public String[] getMergedImsisFromGroup(int subId, String callingPackage) {
6208         enforceReadPrivilegedPermission("getMergedImsisFromGroup");
6209 
6210         final long identity = Binder.clearCallingIdentity();
6211         try {
6212             final TelephonyManager telephonyManager = mApp.getSystemService(
6213                     TelephonyManager.class);
6214             String subscriberId = telephonyManager.getSubscriberId(subId);
6215             if (subscriberId == null) {
6216                 if (DBG) {
6217                     log("getMergedImsisFromGroup can't find subscriberId for subId "
6218                             + subId);
6219                 }
6220                 return null;
6221             }
6222 
6223             final SubscriptionInfo info = SubscriptionController.getInstance()
6224                     .getSubscriptionInfo(subId);
6225             final ParcelUuid groupUuid = info.getGroupUuid();
6226             // If it doesn't belong to any group, return just subscriberId of itself.
6227             if (groupUuid == null) {
6228                 return new String[]{subscriberId};
6229             }
6230 
6231             // Get all subscriberIds from the group.
6232             final List<String> mergedSubscriberIds = new ArrayList<>();
6233             final List<SubscriptionInfo> groupInfos = SubscriptionController.getInstance()
6234                     .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
6235                             mApp.getAttributionTag());
6236             for (SubscriptionInfo subInfo : groupInfos) {
6237                 subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
6238                 if (subscriberId != null) {
6239                     mergedSubscriberIds.add(subscriberId);
6240                 }
6241             }
6242 
6243             return mergedSubscriberIds.toArray(new String[mergedSubscriberIds.size()]);
6244         } finally {
6245             Binder.restoreCallingIdentity(identity);
6246 
6247         }
6248     }
6249 
6250     @Override
setOperatorBrandOverride(int subId, String brand)6251     public boolean setOperatorBrandOverride(int subId, String brand) {
6252         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
6253                 subId, "setOperatorBrandOverride");
6254 
6255         final long identity = Binder.clearCallingIdentity();
6256         try {
6257             final Phone phone = getPhone(subId);
6258             return phone == null ? false : phone.setOperatorBrandOverride(brand);
6259         } finally {
6260             Binder.restoreCallingIdentity(identity);
6261         }
6262     }
6263 
6264     @Override
setRoamingOverride(int subId, List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList)6265     public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
6266             List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
6267             List<String> cdmaNonRoamingList) {
6268         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
6269                 mApp, subId, "setRoamingOverride");
6270 
6271         final long identity = Binder.clearCallingIdentity();
6272         try {
6273             final Phone phone = getPhone(subId);
6274             if (phone == null) {
6275                 return false;
6276             }
6277             return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
6278                     cdmaNonRoamingList);
6279         } finally {
6280             Binder.restoreCallingIdentity(identity);
6281         }
6282     }
6283 
6284     @Override
6285     @Deprecated
invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp)6286     public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
6287         enforceModifyPermission();
6288 
6289         int returnValue = 0;
6290         try {
6291             AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
6292             if(result.exception == null) {
6293                 if (result.result != null) {
6294                     byte[] responseData = (byte[])(result.result);
6295                     if(responseData.length > oemResp.length) {
6296                         Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
6297                                 responseData.length +  "bytes. Buffer Size is " +
6298                                 oemResp.length + "bytes.");
6299                     }
6300                     System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
6301                     returnValue = responseData.length;
6302                 }
6303             } else {
6304                 CommandException ex = (CommandException) result.exception;
6305                 returnValue = ex.getCommandError().ordinal();
6306                 if(returnValue > 0) returnValue *= -1;
6307             }
6308         } catch (RuntimeException e) {
6309             Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
6310             returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
6311             if(returnValue > 0) returnValue *= -1;
6312         }
6313 
6314         return returnValue;
6315     }
6316 
6317     @Override
setRadioCapability(RadioAccessFamily[] rafs)6318     public void setRadioCapability(RadioAccessFamily[] rafs) {
6319         try {
6320             ProxyController.getInstance().setRadioCapability(rafs);
6321         } catch (RuntimeException e) {
6322             Log.w(LOG_TAG, "setRadioCapability: Runtime Exception");
6323         }
6324     }
6325 
6326     @Override
getRadioAccessFamily(int phoneId, String callingPackage)6327     public int getRadioAccessFamily(int phoneId, String callingPackage) {
6328         Phone phone = PhoneFactory.getPhone(phoneId);
6329         int raf = RadioAccessFamily.RAF_UNKNOWN;
6330         if (phone == null) {
6331             return raf;
6332         }
6333         final long identity = Binder.clearCallingIdentity();
6334         try {
6335             TelephonyPermissions
6336                     .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6337                             mApp, phone.getSubId(), "getRadioAccessFamily");
6338             raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
6339         } finally {
6340             Binder.restoreCallingIdentity(identity);
6341         }
6342         return raf;
6343     }
6344 
6345     @Override
enableVideoCalling(boolean enable)6346     public void enableVideoCalling(boolean enable) {
6347         final Phone defaultPhone = getDefaultPhone();
6348         enforceModifyPermission();
6349 
6350         final long identity = Binder.clearCallingIdentity();
6351         try {
6352             ImsManager.getInstance(defaultPhone.getContext(),
6353                     defaultPhone.getPhoneId()).setVtSetting(enable);
6354         } finally {
6355             Binder.restoreCallingIdentity(identity);
6356         }
6357     }
6358 
6359     @Override
isVideoCallingEnabled(String callingPackage, String callingFeatureId)6360     public boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId) {
6361         final Phone defaultPhone = getDefaultPhone();
6362         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
6363                 callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
6364             return false;
6365         }
6366 
6367         final long identity = Binder.clearCallingIdentity();
6368         try {
6369             // Check the user preference and the  system-level IMS setting. Even if the user has
6370             // enabled video calling, if IMS is disabled we aren't able to support video calling.
6371             // In the long run, we may instead need to check if there exists a connection service
6372             // which can support video calling.
6373             ImsManager imsManager =
6374                     ImsManager.getInstance(defaultPhone.getContext(), defaultPhone.getPhoneId());
6375             return imsManager.isVtEnabledByPlatform()
6376                     && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
6377                     && imsManager.isVtEnabledByUser();
6378         } finally {
6379             Binder.restoreCallingIdentity(identity);
6380         }
6381     }
6382 
6383     @Override
canChangeDtmfToneLength(int subId, String callingPackage, String callingFeatureId)6384     public boolean canChangeDtmfToneLength(int subId, String callingPackage,
6385             String callingFeatureId) {
6386         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6387                 mApp, subId, callingPackage, callingFeatureId,
6388                 "isVideoCallingEnabled")) {
6389             return false;
6390         }
6391 
6392         final long identity = Binder.clearCallingIdentity();
6393         try {
6394             CarrierConfigManager configManager =
6395                     (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
6396             return configManager.getConfigForSubId(subId)
6397                     .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
6398         } finally {
6399             Binder.restoreCallingIdentity(identity);
6400         }
6401     }
6402 
6403     @Override
isWorldPhone(int subId, String callingPackage, String callingFeatureId)6404     public boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId) {
6405         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6406                 mApp, subId, callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
6407             return false;
6408         }
6409 
6410         final long identity = Binder.clearCallingIdentity();
6411         try {
6412             CarrierConfigManager configManager =
6413                     (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
6414             return configManager.getConfigForSubId(subId)
6415                     .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
6416         } finally {
6417             Binder.restoreCallingIdentity(identity);
6418         }
6419     }
6420 
6421     @Override
isTtyModeSupported()6422     public boolean isTtyModeSupported() {
6423         TelecomManager telecomManager = mApp.getSystemService(TelecomManager.class);
6424         return telecomManager.isTtySupported();
6425     }
6426 
6427     @Override
isHearingAidCompatibilitySupported()6428     public boolean isHearingAidCompatibilitySupported() {
6429         final long identity = Binder.clearCallingIdentity();
6430         try {
6431             return mApp.getResources().getBoolean(R.bool.hac_enabled);
6432         } finally {
6433             Binder.restoreCallingIdentity(identity);
6434         }
6435     }
6436 
6437     /**
6438      * Determines whether the device currently supports RTT (Real-time text). Based both on carrier
6439      * support for the feature and device firmware support.
6440      *
6441      * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
6442      */
6443     @Override
isRttSupported(int subscriptionId)6444     public boolean isRttSupported(int subscriptionId) {
6445         final long identity = Binder.clearCallingIdentity();
6446         final Phone phone = getPhone(subscriptionId);
6447         if (phone == null) {
6448             loge("isRttSupported: no Phone found. Invalid subId:" + subscriptionId);
6449             return false;
6450         }
6451         try {
6452             boolean isCarrierSupported = mApp.getCarrierConfigForSubId(subscriptionId).getBoolean(
6453                     CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
6454             boolean isDeviceSupported =
6455                     phone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
6456             return isCarrierSupported && isDeviceSupported;
6457         } finally {
6458             Binder.restoreCallingIdentity(identity);
6459         }
6460     }
6461 
6462     /**
6463      * Determines whether the user has turned on RTT. If the carrier wants to ignore the user-set
6464      * RTT setting, will return true if the device and carrier both support RTT.
6465      * Otherwise. only returns true if the device and carrier both also support RTT.
6466      */
isRttEnabled(int subscriptionId)6467     public boolean isRttEnabled(int subscriptionId) {
6468         final long identity = Binder.clearCallingIdentity();
6469         try {
6470             boolean isRttSupported = isRttSupported(subscriptionId);
6471             boolean isUserRttSettingOn = Settings.Secure.getInt(
6472                     mApp.getContentResolver(), Settings.Secure.RTT_CALLING_MODE, 0) != 0;
6473             boolean shouldIgnoreUserRttSetting = mApp.getCarrierConfigForSubId(subscriptionId)
6474                     .getBoolean(CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL);
6475             return isRttSupported && (isUserRttSettingOn || shouldIgnoreUserRttSetting);
6476         } finally {
6477             Binder.restoreCallingIdentity(identity);
6478         }
6479     }
6480 
6481     @Deprecated
6482     @Override
getDeviceId(String callingPackage)6483     public String getDeviceId(String callingPackage) {
6484         return getDeviceIdWithFeature(callingPackage, null);
6485     }
6486 
6487     /**
6488      * Returns the unique device ID of phone, for example, the IMEI for
6489      * GSM and the MEID for CDMA phones. Return null if device ID is not available.
6490      *
6491      * <p>Requires Permission:
6492      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
6493      */
6494     @Override
getDeviceIdWithFeature(String callingPackage, String callingFeatureId)6495     public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
6496         final Phone phone = PhoneFactory.getPhone(0);
6497         if (phone == null) {
6498             return null;
6499         }
6500         int subId = phone.getSubId();
6501         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
6502                 callingPackage, callingFeatureId, "getDeviceId")) {
6503             return null;
6504         }
6505 
6506         final long identity = Binder.clearCallingIdentity();
6507         try {
6508             return phone.getDeviceId();
6509         } finally {
6510             Binder.restoreCallingIdentity(identity);
6511         }
6512     }
6513 
6514     /**
6515      * {@hide}
6516      * Returns the IMS Registration Status on a particular subid
6517      *
6518      * @param subId
6519      */
isImsRegistered(int subId)6520     public boolean isImsRegistered(int subId) {
6521         Phone phone = getPhone(subId);
6522         if (phone != null) {
6523             return phone.isImsRegistered();
6524         } else {
6525             return false;
6526         }
6527     }
6528 
6529     @Override
getSubIdForPhoneAccount(PhoneAccount phoneAccount)6530     public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
6531         final long identity = Binder.clearCallingIdentity();
6532         try {
6533             return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
6534         } finally {
6535             Binder.restoreCallingIdentity(identity);
6536         }
6537     }
6538 
6539     @Override
getSubIdForPhoneAccountHandle( PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId)6540     public int getSubIdForPhoneAccountHandle(
6541             PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId) {
6542         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, getDefaultSubscription(),
6543                 callingPackage, callingFeatureId, "getSubIdForPhoneAccountHandle")) {
6544             throw new SecurityException("Requires READ_PHONE_STATE permission.");
6545         }
6546         final long identity = Binder.clearCallingIdentity();
6547         try {
6548             return PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle);
6549         } finally {
6550             Binder.restoreCallingIdentity(identity);
6551         }
6552     }
6553 
6554     @Override
getPhoneAccountHandleForSubscriptionId(int subscriptionId)6555     public @Nullable PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId) {
6556         final long identity = Binder.clearCallingIdentity();
6557         try {
6558             Phone phone = getPhone(subscriptionId);
6559             if (phone == null) {
6560                 return null;
6561             }
6562             return PhoneUtils.makePstnPhoneAccountHandle(phone);
6563         } finally {
6564             Binder.restoreCallingIdentity(identity);
6565         }
6566     }
6567 
6568     /**
6569      * @return the VoWiFi calling availability.
6570      */
isWifiCallingAvailable(int subId)6571     public boolean isWifiCallingAvailable(int subId) {
6572         final long identity = Binder.clearCallingIdentity();
6573         try {
6574             Phone phone = getPhone(subId);
6575             if (phone != null) {
6576                 return phone.isWifiCallingEnabled();
6577             } else {
6578                 return false;
6579             }
6580         } finally {
6581             Binder.restoreCallingIdentity(identity);
6582         }
6583     }
6584 
6585     /**
6586      * @return the VT calling availability.
6587      */
isVideoTelephonyAvailable(int subId)6588     public boolean isVideoTelephonyAvailable(int subId) {
6589         final long identity = Binder.clearCallingIdentity();
6590         try {
6591             Phone phone = getPhone(subId);
6592             if (phone != null) {
6593                 return phone.isVideoEnabled();
6594             } else {
6595                 return false;
6596             }
6597         } finally {
6598             Binder.restoreCallingIdentity(identity);
6599         }
6600     }
6601 
6602     /**
6603      * @return the IMS registration technology for the MMTEL feature. Valid return values are
6604      * defined in {@link ImsRegistrationImplBase}.
6605      */
getImsRegTechnologyForMmTel(int subId)6606     public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
6607         final long identity = Binder.clearCallingIdentity();
6608         try {
6609             Phone phone = getPhone(subId);
6610             if (phone != null) {
6611                 return phone.getImsRegistrationTech();
6612             } else {
6613                 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
6614             }
6615         } finally {
6616             Binder.restoreCallingIdentity(identity);
6617         }
6618     }
6619 
6620     @Override
factoryReset(int subId)6621     public void factoryReset(int subId) {
6622         enforceSettingsPermission();
6623         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
6624             return;
6625         }
6626 
6627         final long identity = Binder.clearCallingIdentity();
6628 
6629         try {
6630             if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
6631                     UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
6632                 setUserDataEnabled(subId, getDefaultDataEnabled());
6633                 setNetworkSelectionModeAutomatic(subId);
6634                 setPreferredNetworkType(subId, getDefaultNetworkType(subId));
6635                 setDataRoamingEnabled(subId, getDefaultDataRoamingEnabled(subId));
6636                 CarrierInfoManager.deleteAllCarrierKeysForImsiEncryption(mApp);
6637             }
6638             // There has been issues when Sms raw table somehow stores orphan
6639             // fragments. They lead to garbled message when new fragments come
6640             // in and combined with those stale ones. In case this happens again,
6641             // user can reset all network settings which will clean up this table.
6642             cleanUpSmsRawTable(getDefaultPhone().getContext());
6643             // Clean up IMS settings as well here.
6644             int slotId = getSlotIndex(subId);
6645             if (slotId > SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
6646                 ImsManager.getInstance(mApp, slotId).factoryReset();
6647             }
6648 
6649             // Erase modem config if erase modem on network setting is enabled.
6650             String configValue = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_TELEPHONY,
6651                     RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED);
6652             if (configValue != null && Boolean.parseBoolean(configValue)) {
6653               sendEraseModemConfig(getDefaultPhone());
6654             }
6655         } finally {
6656             Binder.restoreCallingIdentity(identity);
6657         }
6658     }
6659 
cleanUpSmsRawTable(Context context)6660     private void cleanUpSmsRawTable(Context context) {
6661         ContentResolver resolver = context.getContentResolver();
6662         Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
6663         resolver.delete(uri, null, null);
6664     }
6665 
6666     @Override
getSimLocaleForSubscriber(int subId)6667     public String getSimLocaleForSubscriber(int subId) {
6668         enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
6669         final Phone phone = getPhone(subId);
6670         if (phone == null) {
6671             log("getSimLocaleForSubscriber, invalid subId");
6672             return null;
6673         }
6674         final long identity = Binder.clearCallingIdentity();
6675         try {
6676             final SubscriptionInfo info = mSubscriptionController.getActiveSubscriptionInfo(subId,
6677                     phone.getContext().getOpPackageName(), phone.getContext().getAttributionTag());
6678             if (info == null) {
6679                 log("getSimLocaleForSubscriber, inactive subId: " + subId);
6680                 return null;
6681             }
6682             // Try and fetch the locale from the carrier properties or from the SIM language
6683             // preferences (EF-PL and EF-LI)...
6684             final int mcc = info.getMcc();
6685             String simLanguage = null;
6686             final Locale localeFromDefaultSim = phone.getLocaleFromSimAndCarrierPrefs();
6687             if (localeFromDefaultSim != null) {
6688                 if (!localeFromDefaultSim.getCountry().isEmpty()) {
6689                     if (DBG) log("Using locale from subId: " + subId + " locale: "
6690                             + localeFromDefaultSim);
6691                     return localeFromDefaultSim.toLanguageTag();
6692                 } else {
6693                     simLanguage = localeFromDefaultSim.getLanguage();
6694                 }
6695             }
6696 
6697             // The SIM language preferences only store a language (e.g. fr = French), not an
6698             // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
6699             // the SIM and carrier preferences does not include a country we add the country
6700             // determined from the SIM MCC to provide an exact locale.
6701             final Locale mccLocale = LocaleUtils.getLocaleFromMcc(mApp, mcc, simLanguage);
6702             if (mccLocale != null) {
6703                 if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale);
6704                 return mccLocale.toLanguageTag();
6705             }
6706 
6707             if (DBG) log("No locale found - returning null");
6708             return null;
6709         } finally {
6710             Binder.restoreCallingIdentity(identity);
6711         }
6712     }
6713 
getAllSubscriptionInfoList()6714     private List<SubscriptionInfo> getAllSubscriptionInfoList() {
6715         return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName(),
6716                 mApp.getAttributionTag());
6717     }
6718 
6719     /**
6720      * NOTE: this method assumes permission checks are done and caller identity has been cleared.
6721      */
getActiveSubscriptionInfoListPrivileged()6722     private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
6723         return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName(),
6724                 mApp.getAttributionTag());
6725     }
6726 
6727     private final ModemActivityInfo mLastModemActivityInfo =
6728             new ModemActivityInfo(0, 0, 0, new int[0], 0);
6729 
6730     /**
6731      * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
6732      * representing the state of the modem.
6733      *
6734      * NOTE: The underlying implementation clears the modem state, so there should only ever be one
6735      * caller to it. Everyone should call this class to get cumulative data.
6736      * @hide
6737      */
6738     @Override
requestModemActivityInfo(ResultReceiver result)6739     public void requestModemActivityInfo(ResultReceiver result) {
6740         enforceModifyPermission();
6741         WorkSource workSource = getWorkSource(Binder.getCallingUid());
6742 
6743         final long identity = Binder.clearCallingIdentity();
6744         try {
6745             sendRequestAsync(CMD_GET_MODEM_ACTIVITY_INFO, result, null, workSource);
6746         } finally {
6747             Binder.restoreCallingIdentity(identity);
6748         }
6749     }
6750 
6751     // Checks that ModemActivityInfo is valid. Sleep time, Idle time, Rx time and Tx time should be
6752     // less than total activity duration.
isModemActivityInfoValid(ModemActivityInfo info)6753     private boolean isModemActivityInfoValid(ModemActivityInfo info) {
6754         if (info == null) {
6755             return false;
6756         }
6757         int activityDurationMs =
6758             (int) (info.getTimestamp() - mLastModemActivityInfo.getTimestamp());
6759         int totalTxTimeMs = 0;
6760         int[] txTimeMs = info.getTransmitTimeMillis();
6761         for (int i = 0; i < info.getTransmitPowerInfo().size(); i++) {
6762             totalTxTimeMs += txTimeMs[i];
6763         }
6764         return (info.isValid()
6765             && (info.getSleepTimeMillis() <= activityDurationMs)
6766             && (info.getIdleTimeMillis() <= activityDurationMs)
6767             && (info.getReceiveTimeMillis() <= activityDurationMs)
6768             && (totalTxTimeMs <= activityDurationMs));
6769     }
6770 
6771     /**
6772      * {@hide}
6773      * Returns the service state information on specified subscription.
6774      */
6775     @Override
getServiceStateForSubscriber(int subId, String callingPackage, String callingFeatureId)6776     public ServiceState getServiceStateForSubscriber(int subId, String callingPackage,
6777             String callingFeatureId) {
6778         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6779                 mApp, subId, callingPackage, callingFeatureId, "getServiceStateForSubscriber")) {
6780             return null;
6781         }
6782 
6783         LocationAccessPolicy.LocationPermissionResult fineLocationResult =
6784                 LocationAccessPolicy.checkLocationPermission(mApp,
6785                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
6786                                 .setCallingPackage(callingPackage)
6787                                 .setCallingFeatureId(callingFeatureId)
6788                                 .setCallingPid(Binder.getCallingPid())
6789                                 .setCallingUid(Binder.getCallingUid())
6790                                 .setMethod("getServiceStateForSubscriber")
6791                                 .setLogAsInfo(true)
6792                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
6793                                 .build());
6794 
6795         LocationAccessPolicy.LocationPermissionResult coarseLocationResult =
6796                 LocationAccessPolicy.checkLocationPermission(mApp,
6797                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
6798                                 .setCallingPackage(callingPackage)
6799                                 .setCallingFeatureId(callingFeatureId)
6800                                 .setCallingPid(Binder.getCallingPid())
6801                                 .setCallingUid(Binder.getCallingUid())
6802                                 .setMethod("getServiceStateForSubscriber")
6803                                 .setLogAsInfo(true)
6804                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
6805                                 .build());
6806         // We don't care about hard or soft here -- all we need to know is how much info to scrub.
6807         boolean hasFinePermission =
6808                 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
6809         boolean hasCoarsePermission =
6810                 coarseLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
6811 
6812         final long identity = Binder.clearCallingIdentity();
6813         try {
6814             final Phone phone = getPhone(subId);
6815             if (phone == null) {
6816                 return null;
6817             }
6818 
6819             ServiceState ss = phone.getServiceState();
6820 
6821             // Scrub out the location info in ServiceState depending on what level of access
6822             // the caller has.
6823             if (hasFinePermission) return ss;
6824             if (hasCoarsePermission) return ss.createLocationInfoSanitizedCopy(false);
6825             return ss.createLocationInfoSanitizedCopy(true);
6826         } finally {
6827             Binder.restoreCallingIdentity(identity);
6828         }
6829     }
6830 
6831     /**
6832      * Returns the URI for the per-account voicemail ringtone set in Phone settings.
6833      *
6834      * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
6835      * voicemail ringtone.
6836      * @return The URI for the ringtone to play when receiving a voicemail from a specific
6837      * PhoneAccount.
6838      */
6839     @Override
getVoicemailRingtoneUri(PhoneAccountHandle accountHandle)6840     public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
6841         final long identity = Binder.clearCallingIdentity();
6842         try {
6843             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
6844             if (phone == null) {
6845                 phone = getDefaultPhone();
6846             }
6847 
6848             return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
6849         } finally {
6850             Binder.restoreCallingIdentity(identity);
6851         }
6852     }
6853 
6854     /**
6855      * Sets the per-account voicemail ringtone.
6856      *
6857      * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
6858      * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
6859      *
6860      * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
6861      * voicemail ringtone.
6862      * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
6863      * PhoneAccount.
6864      */
6865     @Override
setVoicemailRingtoneUri(String callingPackage, PhoneAccountHandle phoneAccountHandle, Uri uri)6866     public void setVoicemailRingtoneUri(String callingPackage,
6867             PhoneAccountHandle phoneAccountHandle, Uri uri) {
6868         final Phone defaultPhone = getDefaultPhone();
6869         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
6870         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
6871         if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
6872             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6873                     mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
6874                     "setVoicemailRingtoneUri");
6875         }
6876 
6877         final long identity = Binder.clearCallingIdentity();
6878         try {
6879             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
6880             if (phone == null) {
6881                 phone = defaultPhone;
6882             }
6883             VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
6884         } finally {
6885             Binder.restoreCallingIdentity(identity);
6886         }
6887     }
6888 
6889     /**
6890      * Returns whether vibration is set for voicemail notification in Phone settings.
6891      *
6892      * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
6893      * voicemail vibration setting.
6894      * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
6895      */
6896     @Override
isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle)6897     public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
6898         final long identity = Binder.clearCallingIdentity();
6899         try {
6900             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
6901             if (phone == null) {
6902                 phone = getDefaultPhone();
6903             }
6904 
6905             return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
6906         } finally {
6907             Binder.restoreCallingIdentity(identity);
6908         }
6909     }
6910 
6911     /**
6912      * Sets the per-account voicemail vibration.
6913      *
6914      * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
6915      * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
6916      *
6917      * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
6918      * voicemail vibration setting.
6919      * @param enabled Whether to enable or disable vibration for voicemail notifications from a
6920      * specific PhoneAccount.
6921      */
6922     @Override
setVoicemailVibrationEnabled(String callingPackage, PhoneAccountHandle phoneAccountHandle, boolean enabled)6923     public void setVoicemailVibrationEnabled(String callingPackage,
6924             PhoneAccountHandle phoneAccountHandle, boolean enabled) {
6925         final Phone defaultPhone = getDefaultPhone();
6926         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
6927         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
6928         if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
6929             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6930                     mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
6931                     "setVoicemailVibrationEnabled");
6932         }
6933 
6934         final long identity = Binder.clearCallingIdentity();
6935         try {
6936             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
6937             if (phone == null) {
6938                 phone = defaultPhone;
6939             }
6940             VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
6941         } finally {
6942             Binder.restoreCallingIdentity(identity);
6943         }
6944     }
6945 
6946     /**
6947      * Make sure either called from same process as self (phone) or IPC caller has read privilege.
6948      *
6949      * @throws SecurityException if the caller does not have the required permission
6950      */
enforceReadPrivilegedPermission(String message)6951     private void enforceReadPrivilegedPermission(String message) {
6952         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
6953                 message);
6954     }
6955 
6956     /**
6957      * Make sure either called from same process as self (phone) or IPC caller has send SMS
6958      * permission.
6959      *
6960      * @throws SecurityException if the caller does not have the required permission
6961      */
enforceSendSmsPermission()6962     private void enforceSendSmsPermission() {
6963         mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
6964     }
6965 
6966     /**
6967      * Make sure called from the package in charge of visual voicemail.
6968      *
6969      * @throws SecurityException if the caller is not the visual voicemail package.
6970      */
enforceVisualVoicemailPackage(String callingPackage, int subId)6971     private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
6972         final long identity = Binder.clearCallingIdentity();
6973         try {
6974             ComponentName componentName =
6975                     RemoteVvmTaskManager.getRemotePackage(mApp, subId);
6976             if (componentName == null) {
6977                 throw new SecurityException(
6978                         "Caller not current active visual voicemail package[null]");
6979             }
6980             String vvmPackage = componentName.getPackageName();
6981             if (!callingPackage.equals(vvmPackage)) {
6982                 throw new SecurityException("Caller not current active visual voicemail package["
6983                         + vvmPackage + "]");
6984             }
6985         } finally {
6986             Binder.restoreCallingIdentity(identity);
6987         }
6988     }
6989 
6990     /**
6991      * Return the application ID for the app type.
6992      *
6993      * @param subId the subscription ID that this request applies to.
6994      * @param appType the uicc app type.
6995      * @return Application ID for specificied app type, or null if no uicc.
6996      */
6997     @Override
getAidForAppType(int subId, int appType)6998     public String getAidForAppType(int subId, int appType) {
6999         enforceReadPrivilegedPermission("getAidForAppType");
7000         Phone phone = getPhone(subId);
7001 
7002         final long identity = Binder.clearCallingIdentity();
7003         try {
7004             if (phone == null) {
7005                 return null;
7006             }
7007             String aid = null;
7008             try {
7009                 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
7010                         .getApplicationByType(appType).getAid();
7011             } catch (Exception e) {
7012                 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
7013             }
7014             return aid;
7015         } finally {
7016             Binder.restoreCallingIdentity(identity);
7017         }
7018     }
7019 
7020     /**
7021      * Return the Electronic Serial Number.
7022      *
7023      * @param subId the subscription ID that this request applies to.
7024      * @return ESN or null if error.
7025      */
7026     @Override
getEsn(int subId)7027     public String getEsn(int subId) {
7028         enforceReadPrivilegedPermission("getEsn");
7029         Phone phone = getPhone(subId);
7030 
7031         final long identity = Binder.clearCallingIdentity();
7032         try {
7033             if (phone == null) {
7034                 return null;
7035             }
7036             String esn = null;
7037             try {
7038                 esn = phone.getEsn();
7039             } catch (Exception e) {
7040                 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
7041             }
7042             return esn;
7043         } finally {
7044             Binder.restoreCallingIdentity(identity);
7045         }
7046     }
7047 
7048     /**
7049      * Return the Preferred Roaming List Version.
7050      *
7051      * @param subId the subscription ID that this request applies to.
7052      * @return PRLVersion or null if error.
7053      */
7054     @Override
getCdmaPrlVersion(int subId)7055     public String getCdmaPrlVersion(int subId) {
7056         enforceReadPrivilegedPermission("getCdmaPrlVersion");
7057         Phone phone = getPhone(subId);
7058 
7059         final long identity = Binder.clearCallingIdentity();
7060         try {
7061             if (phone == null) {
7062                 return null;
7063             }
7064             String cdmaPrlVersion = null;
7065             try {
7066                 cdmaPrlVersion = phone.getCdmaPrlVersion();
7067             } catch (Exception e) {
7068                 Log.e(LOG_TAG, "Not getting PRLVersion", e);
7069             }
7070             return cdmaPrlVersion;
7071         } finally {
7072             Binder.restoreCallingIdentity(identity);
7073         }
7074     }
7075 
7076     /**
7077      * Get snapshot of Telephony histograms
7078      * @return List of Telephony histograms
7079      * @hide
7080      */
7081     @Override
getTelephonyHistograms()7082     public List<TelephonyHistogram> getTelephonyHistograms() {
7083         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7084                 mApp, getDefaultSubscription(), "getTelephonyHistograms");
7085 
7086         final long identity = Binder.clearCallingIdentity();
7087         try {
7088             return RIL.getTelephonyRILTimingHistograms();
7089         } finally {
7090             Binder.restoreCallingIdentity(identity);
7091         }
7092     }
7093 
7094     /**
7095      * {@hide}
7096      * Set the allowed carrier list and the excluded carrier list, indicating the priority between
7097      * the two lists.
7098      * Require system privileges. In the future we may add this to carrier APIs.
7099      *
7100      * @return Integer with the result of the operation, as defined in {@link TelephonyManager}.
7101      */
7102     @Override
7103     @TelephonyManager.SetCarrierRestrictionResult
setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules)7104     public int setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules) {
7105         enforceModifyPermission();
7106         WorkSource workSource = getWorkSource(Binder.getCallingUid());
7107 
7108         if (carrierRestrictionRules == null) {
7109             throw new NullPointerException("carrier restriction cannot be null");
7110         }
7111 
7112         final long identity = Binder.clearCallingIdentity();
7113         try {
7114             return (int) sendRequest(CMD_SET_ALLOWED_CARRIERS, carrierRestrictionRules,
7115                     workSource);
7116         } finally {
7117             Binder.restoreCallingIdentity(identity);
7118         }
7119     }
7120 
7121     /**
7122      * {@hide}
7123      * Get the allowed carrier list and the excluded carrier list, including the priority between
7124      * the two lists.
7125      * Require system privileges. In the future we may add this to carrier APIs.
7126      *
7127      * @return {@link android.telephony.CarrierRestrictionRules}
7128      */
7129     @Override
getAllowedCarriers()7130     public CarrierRestrictionRules getAllowedCarriers() {
7131         enforceReadPrivilegedPermission("getAllowedCarriers");
7132         WorkSource workSource = getWorkSource(Binder.getCallingUid());
7133 
7134         final long identity = Binder.clearCallingIdentity();
7135         try {
7136             Object response = sendRequest(CMD_GET_ALLOWED_CARRIERS, null, workSource);
7137             if (response instanceof CarrierRestrictionRules) {
7138                 return (CarrierRestrictionRules) response;
7139             }
7140             // Response is an Exception of some kind,
7141             // which is signalled to the user as a NULL retval
7142             return null;
7143         } catch (Exception e) {
7144             Log.e(LOG_TAG, "getAllowedCarriers. Exception ex=" + e);
7145             return null;
7146         } finally {
7147             Binder.restoreCallingIdentity(identity);
7148         }
7149     }
7150 
7151     /**
7152      * Action set from carrier signalling broadcast receivers to enable/disable metered apns
7153      * @param subId the subscription ID that this action applies to.
7154      * @param enabled control enable or disable metered apns.
7155      * {@hide}
7156      */
7157     @Override
carrierActionSetMeteredApnsEnabled(int subId, boolean enabled)7158     public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
7159         enforceModifyPermission();
7160         final Phone phone = getPhone(subId);
7161 
7162         final long identity = Binder.clearCallingIdentity();
7163         if (phone == null) {
7164             loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId);
7165             return;
7166         }
7167         try {
7168             phone.carrierActionSetMeteredApnsEnabled(enabled);
7169         } catch (Exception e) {
7170             Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e);
7171         } finally {
7172             Binder.restoreCallingIdentity(identity);
7173         }
7174     }
7175 
7176     /**
7177      * Action set from carrier signalling broadcast receivers to enable/disable radio
7178      * @param subId the subscription ID that this action applies to.
7179      * @param enabled control enable or disable radio.
7180      * {@hide}
7181      */
7182     @Override
carrierActionSetRadioEnabled(int subId, boolean enabled)7183     public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
7184         enforceModifyPermission();
7185         final Phone phone = getPhone(subId);
7186 
7187         final long identity = Binder.clearCallingIdentity();
7188         if (phone == null) {
7189             loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
7190             return;
7191         }
7192         try {
7193             phone.carrierActionSetRadioEnabled(enabled);
7194         } catch (Exception e) {
7195             Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
7196         } finally {
7197             Binder.restoreCallingIdentity(identity);
7198         }
7199     }
7200 
7201     /**
7202      * Action set from carrier signalling broadcast receivers to start/stop reporting the default
7203      * network status based on which carrier apps could apply actions accordingly,
7204      * enable/disable default url handler for example.
7205      *
7206      * @param subId the subscription ID that this action applies to.
7207      * @param report control start/stop reporting the default network status.
7208      * {@hide}
7209      */
7210     @Override
carrierActionReportDefaultNetworkStatus(int subId, boolean report)7211     public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
7212         enforceModifyPermission();
7213         final Phone phone = getPhone(subId);
7214 
7215         final long identity = Binder.clearCallingIdentity();
7216         if (phone == null) {
7217             loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
7218             return;
7219         }
7220         try {
7221             phone.carrierActionReportDefaultNetworkStatus(report);
7222         } catch (Exception e) {
7223             Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
7224         } finally {
7225             Binder.restoreCallingIdentity(identity);
7226         }
7227     }
7228 
7229     /**
7230      * Action set from carrier signalling broadcast receivers to reset all carrier actions
7231      * @param subId the subscription ID that this action applies to.
7232      * {@hide}
7233      */
7234     @Override
carrierActionResetAll(int subId)7235     public void carrierActionResetAll(int subId) {
7236         enforceModifyPermission();
7237         final Phone phone = getPhone(subId);
7238         if (phone == null) {
7239             loge("carrierAction: ResetAll fails with invalid sibId: " + subId);
7240             return;
7241         }
7242         try {
7243             phone.carrierActionResetAll();
7244         } catch (Exception e) {
7245             Log.e(LOG_TAG, "carrierAction: ResetAll fails. Exception ex=" + e);
7246         }
7247     }
7248 
7249     /**
7250      * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
7251      * bug report is being generated.
7252      */
7253     @Override
dump(FileDescriptor fd, PrintWriter writer, String[] args)7254     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
7255         if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
7256                 != PackageManager.PERMISSION_GRANTED) {
7257             writer.println("Permission Denial: can't dump Phone from pid="
7258                     + Binder.getCallingPid()
7259                     + ", uid=" + Binder.getCallingUid()
7260                     + "without permission "
7261                     + android.Manifest.permission.DUMP);
7262             return;
7263         }
7264         DumpsysHandler.dump(mApp, fd, writer, args);
7265     }
7266 
7267     @Override
handleShellCommand(@onNull ParcelFileDescriptor in, @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, @NonNull String[] args)7268     public int handleShellCommand(@NonNull ParcelFileDescriptor in,
7269             @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
7270             @NonNull String[] args) {
7271         return new TelephonyShellCommand(this, getDefaultPhone().getContext()).exec(
7272                 this, in.getFileDescriptor(), out.getFileDescriptor(),
7273                         err.getFileDescriptor(), args);
7274     }
7275 
7276     /**
7277      * Policy control of data connection. Usually used when data limit is passed.
7278      * @param enabled True if enabling the data, otherwise disabling.
7279      * @param subId Subscription index
7280      * {@hide}
7281      */
7282     @Override
setPolicyDataEnabled(boolean enabled, int subId)7283     public void setPolicyDataEnabled(boolean enabled, int subId) {
7284         enforceModifyPermission();
7285 
7286         final long identity = Binder.clearCallingIdentity();
7287         try {
7288             Phone phone = getPhone(subId);
7289             if (phone != null) {
7290                 phone.getDataEnabledSettings().setPolicyDataEnabled(enabled);
7291             }
7292         } finally {
7293             Binder.restoreCallingIdentity(identity);
7294         }
7295     }
7296 
7297     /**
7298      * Get Client request stats
7299      * @return List of Client Request Stats
7300      * @hide
7301      */
7302     @Override
getClientRequestStats(String callingPackage, String callingFeatureId, int subId)7303     public List<ClientRequestStats> getClientRequestStats(String callingPackage,
7304             String callingFeatureId, int subId) {
7305         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
7306                 mApp, subId, callingPackage, callingFeatureId, "getClientRequestStats")) {
7307             return null;
7308         }
7309         Phone phone = getPhone(subId);
7310 
7311         final long identity = Binder.clearCallingIdentity();
7312         try {
7313             if (phone != null) {
7314                 return phone.getClientRequestStats();
7315             }
7316 
7317             return null;
7318         } finally {
7319             Binder.restoreCallingIdentity(identity);
7320         }
7321     }
7322 
getWorkSource(int uid)7323     private WorkSource getWorkSource(int uid) {
7324         String packageName = mApp.getPackageManager().getNameForUid(uid);
7325         return new WorkSource(uid, packageName);
7326     }
7327 
7328     /**
7329      * Set SIM card power state.
7330      *
7331      * @param slotIndex SIM slot id.
7332      * @param state  State of SIM (power down, power up, pass through)
7333      * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
7334      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
7335      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
7336      *
7337      **/
7338     @Override
setSimPowerStateForSlot(int slotIndex, int state)7339     public void setSimPowerStateForSlot(int slotIndex, int state) {
7340         enforceModifyPermission();
7341         Phone phone = PhoneFactory.getPhone(slotIndex);
7342 
7343         WorkSource workSource = getWorkSource(Binder.getCallingUid());
7344 
7345         final long identity = Binder.clearCallingIdentity();
7346         try {
7347             if (phone != null) {
7348                 phone.setSimPowerState(state, workSource);
7349             }
7350         } finally {
7351             Binder.restoreCallingIdentity(identity);
7352         }
7353     }
7354 
isUssdApiAllowed(int subId)7355     private boolean isUssdApiAllowed(int subId) {
7356         CarrierConfigManager configManager =
7357                 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
7358         if (configManager == null) {
7359             return false;
7360         }
7361         PersistableBundle pb = configManager.getConfigForSubId(subId);
7362         if (pb == null) {
7363             return false;
7364         }
7365         return pb.getBoolean(
7366                 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
7367     }
7368 
7369     /**
7370      * Check if phone is in emergency callback mode
7371      * @return true if phone is in emergency callback mode
7372      * @param subId sub id
7373      */
7374     @Override
getEmergencyCallbackMode(int subId)7375     public boolean getEmergencyCallbackMode(int subId) {
7376         enforceReadPrivilegedPermission("getEmergencyCallbackMode");
7377         final Phone phone = getPhone(subId);
7378 
7379         final long identity = Binder.clearCallingIdentity();
7380         try {
7381             if (phone != null) {
7382                 return phone.isInEcm();
7383             } else {
7384                 return false;
7385             }
7386         } finally {
7387             Binder.restoreCallingIdentity(identity);
7388         }
7389     }
7390 
7391     /**
7392      * Get the current signal strength information for the given subscription.
7393      * Because this information is not updated when the device is in a low power state
7394      * it should not be relied-upon to be current.
7395      * @param subId Subscription index
7396      * @return the most recent cached signal strength info from the modem
7397      */
7398     @Override
getSignalStrength(int subId)7399     public SignalStrength getSignalStrength(int subId) {
7400         final long identity = Binder.clearCallingIdentity();
7401         try {
7402             Phone p = getPhone(subId);
7403             if (p == null) {
7404                 return null;
7405             }
7406 
7407             return p.getSignalStrength();
7408         } finally {
7409             Binder.restoreCallingIdentity(identity);
7410         }
7411     }
7412 
7413     /**
7414      * Get the current modem radio state for the given slot.
7415      * @param slotIndex slot index.
7416      * @param callingPackage the name of the package making the call.
7417      * @param callingFeatureId The feature in the package.
7418      * @return the current radio power state from the modem
7419      */
7420     @Override
getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId)7421     public int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId) {
7422         Phone phone = PhoneFactory.getPhone(slotIndex);
7423         if (phone != null) {
7424             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, phone.getSubId(),
7425                     callingPackage, callingFeatureId, "getRadioPowerState")) {
7426                 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
7427             }
7428 
7429             final long identity = Binder.clearCallingIdentity();
7430             try {
7431                 return phone.getRadioPowerState();
7432             } finally {
7433                 Binder.restoreCallingIdentity(identity);
7434             }
7435         }
7436         return TelephonyManager.RADIO_POWER_UNAVAILABLE;
7437     }
7438 
7439     /**
7440      * Checks if data roaming is enabled on the subscription with id {@code subId}.
7441      *
7442      * <p>Requires one of the following permissions:
7443      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
7444      * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
7445      * privileges.
7446      *
7447      * @param subId subscription id
7448      * @return {@code true} if data roaming is enabled on this subscription, otherwise return
7449      * {@code false}.
7450      */
7451     @Override
isDataRoamingEnabled(int subId)7452     public boolean isDataRoamingEnabled(int subId) {
7453         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
7454                 null /* message */);
7455 
7456         boolean isEnabled = false;
7457         final long identity = Binder.clearCallingIdentity();
7458         try {
7459             Phone phone = getPhone(subId);
7460             isEnabled =  phone != null ? phone.getDataRoamingEnabled() : false;
7461         } catch (Exception e) {
7462             TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
7463                     mApp, subId, "isDataRoamingEnabled");
7464         } finally {
7465             Binder.restoreCallingIdentity(identity);
7466         }
7467         return isEnabled;
7468     }
7469 
7470 
7471     /**
7472      * Enables/Disables the data roaming on the subscription with id {@code subId}.
7473      *
7474      * <p> Requires permission:
7475      * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
7476      * privileges.
7477      *
7478      * @param subId subscription id
7479      * @param isEnabled {@code true} means enable, {@code false} means disable.
7480      */
7481     @Override
setDataRoamingEnabled(int subId, boolean isEnabled)7482     public void setDataRoamingEnabled(int subId, boolean isEnabled) {
7483         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7484                 mApp, subId, "setDataRoamingEnabled");
7485 
7486         final long identity = Binder.clearCallingIdentity();
7487         try {
7488             Phone phone = getPhone(subId);
7489             if (phone != null) {
7490                 phone.setDataRoamingEnabled(isEnabled);
7491             }
7492         } finally {
7493             Binder.restoreCallingIdentity(identity);
7494         }
7495     }
7496 
7497     @Override
isManualNetworkSelectionAllowed(int subId)7498     public boolean isManualNetworkSelectionAllowed(int subId) {
7499         TelephonyPermissions
7500                 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
7501                 mApp, subId, "isManualNetworkSelectionAllowed");
7502 
7503         boolean isAllowed = true;
7504         final long identity = Binder.clearCallingIdentity();
7505         try {
7506             Phone phone = getPhone(subId);
7507             if (phone != null) {
7508                 isAllowed = phone.isCspPlmnEnabled();
7509             }
7510         } finally {
7511             Binder.restoreCallingIdentity(identity);
7512         }
7513         return isAllowed;
7514     }
7515 
7516     @Override
getUiccCardsInfo(String callingPackage)7517     public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
7518         // Verify that tha callingPackage belongs to the calling UID
7519         mApp.getSystemService(AppOpsManager.class)
7520                 .checkPackage(Binder.getCallingUid(), callingPackage);
7521 
7522         boolean hasReadPermission = false;
7523         try {
7524             enforceReadPrivilegedPermission("getUiccCardsInfo");
7525             hasReadPermission = true;
7526         } catch (SecurityException e) {
7527             // even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
7528             // has carrier privileges on an active UICC
7529             if (checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
7530                         != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
7531                 throw new SecurityException("Caller does not have permission.");
7532             }
7533         }
7534 
7535         final long identity = Binder.clearCallingIdentity();
7536         try {
7537             UiccController uiccController = UiccController.getInstance();
7538             ArrayList<UiccCardInfo> cardInfos = uiccController.getAllUiccCardInfos();
7539             if (hasReadPermission) {
7540                 return cardInfos;
7541             }
7542 
7543             // Remove private info if the caller doesn't have access
7544             ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
7545             for (UiccCardInfo cardInfo : cardInfos) {
7546                 // For an inactive eUICC, the UiccCard will be null even though the UiccCardInfo
7547                 // is available
7548                 UiccCard card = uiccController.getUiccCardForSlot(cardInfo.getSlotIndex());
7549                 if (card == null || card.getUiccProfile() == null) {
7550                     // assume no access if the card or profile is unavailable
7551                     filteredInfos.add(cardInfo.getUnprivileged());
7552                     continue;
7553                 }
7554                 UiccProfile profile = card.getUiccProfile();
7555                 if (profile.getCarrierPrivilegeStatus(mApp.getPackageManager(), callingPackage)
7556                         == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
7557                     filteredInfos.add(cardInfo);
7558                 } else {
7559                     filteredInfos.add(cardInfo.getUnprivileged());
7560                 }
7561             }
7562             return filteredInfos;
7563         } finally {
7564             Binder.restoreCallingIdentity(identity);
7565         }
7566     }
7567 
7568     @Override
getUiccSlotsInfo()7569     public UiccSlotInfo[] getUiccSlotsInfo() {
7570         enforceReadPrivilegedPermission("getUiccSlotsInfo");
7571 
7572         final long identity = Binder.clearCallingIdentity();
7573         try {
7574             UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
7575             if (slots == null) {
7576                 Rlog.i(LOG_TAG, "slots is null.");
7577                 return null;
7578             }
7579 
7580             UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
7581             for (int i = 0; i < slots.length; i++) {
7582                 UiccSlot slot = slots[i];
7583                 if (slot == null) {
7584                     continue;
7585                 }
7586 
7587                 String cardId;
7588                 UiccCard card = slot.getUiccCard();
7589                 if (card != null) {
7590                     cardId = card.getCardId();
7591                 } else {
7592                     cardId = slot.getEid();
7593                     if (TextUtils.isEmpty(cardId)) {
7594                         cardId = slot.getIccId();
7595                     }
7596                 }
7597 
7598                 if (cardId != null) {
7599                     // if cardId is an ICCID, strip off trailing Fs before exposing to user
7600                     // if cardId is an EID, it's all digits so this is fine
7601                     cardId = IccUtils.stripTrailingFs(cardId);
7602                 }
7603 
7604                 int cardState = 0;
7605                 switch (slot.getCardState()) {
7606                     case CARDSTATE_ABSENT:
7607                         cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
7608                         break;
7609                     case CARDSTATE_PRESENT:
7610                         cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
7611                         break;
7612                     case CARDSTATE_ERROR:
7613                         cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
7614                         break;
7615                     case CARDSTATE_RESTRICTED:
7616                         cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
7617                         break;
7618                     default:
7619                         break;
7620 
7621                 }
7622 
7623                 infos[i] = new UiccSlotInfo(
7624                         slot.isActive(),
7625                         slot.isEuicc(),
7626                         cardId,
7627                         cardState,
7628                         slot.getPhoneId(),
7629                         slot.isExtendedApduSupported(),
7630                         slot.isRemovable());
7631             }
7632             return infos;
7633         } finally {
7634             Binder.restoreCallingIdentity(identity);
7635         }
7636     }
7637 
7638     @Override
switchSlots(int[] physicalSlots)7639     public boolean switchSlots(int[] physicalSlots) {
7640         enforceModifyPermission();
7641 
7642         final long identity = Binder.clearCallingIdentity();
7643         try {
7644             return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
7645         } finally {
7646             Binder.restoreCallingIdentity(identity);
7647         }
7648     }
7649 
7650     @Override
getCardIdForDefaultEuicc(int subId, String callingPackage)7651     public int getCardIdForDefaultEuicc(int subId, String callingPackage) {
7652         final long identity = Binder.clearCallingIdentity();
7653         try {
7654             return UiccController.getInstance().getCardIdForDefaultEuicc();
7655         } finally {
7656             Binder.restoreCallingIdentity(identity);
7657         }
7658     }
7659 
7660     /**
7661      * A test API to reload the UICC profile.
7662      *
7663      * <p>Requires that the calling app has permission
7664      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
7665      * @hide
7666      */
7667     @Override
refreshUiccProfile(int subId)7668     public void refreshUiccProfile(int subId) {
7669         enforceModifyPermission();
7670 
7671         final long identity = Binder.clearCallingIdentity();
7672         try {
7673             Phone phone = getPhone(subId);
7674             if (phone == null) {
7675                 return;
7676             }
7677             UiccCard uiccCard = phone.getUiccCard();
7678             if (uiccCard == null) {
7679                 return;
7680             }
7681             UiccProfile uiccProfile = uiccCard.getUiccProfile();
7682             if (uiccProfile == null) {
7683                 return;
7684             }
7685             uiccProfile.refresh();
7686         } finally {
7687             Binder.restoreCallingIdentity(identity);
7688         }
7689     }
7690 
7691     /**
7692      * Returns false if the mobile data is disabled by default, otherwise return true.
7693      */
getDefaultDataEnabled()7694     private boolean getDefaultDataEnabled() {
7695         return TelephonyProperties.mobile_data().orElse(true);
7696     }
7697 
7698     /**
7699      * Returns true if the data roaming is enabled by default, i.e the system property
7700      * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
7701      * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
7702      */
getDefaultDataRoamingEnabled(int subId)7703     private boolean getDefaultDataRoamingEnabled(int subId) {
7704         final CarrierConfigManager configMgr = (CarrierConfigManager)
7705                 mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
7706         boolean isDataRoamingEnabled = TelephonyProperties.data_roaming().orElse(true);
7707         isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
7708                 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
7709         return isDataRoamingEnabled;
7710     }
7711 
7712     /**
7713      * Returns the default network type for the given {@code subId}, if the default network type is
7714      * not set, return {@link Phone#PREFERRED_NT_MODE}.
7715      */
getDefaultNetworkType(int subId)7716     private int getDefaultNetworkType(int subId) {
7717         List<Integer> list = TelephonyProperties.default_network();
7718         int phoneId = mSubscriptionController.getPhoneId(subId);
7719         if (phoneId >= 0 && phoneId < list.size() && list.get(phoneId) != null) {
7720             return list.get(phoneId);
7721         }
7722         return Phone.PREFERRED_NT_MODE;
7723     }
7724 
7725     @Override
setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn)7726     public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
7727             gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn) {
7728         enforceModifyPermission();
7729 
7730         final long identity = Binder.clearCallingIdentity();
7731         try {
7732             final Phone phone = getPhone(subId);
7733             if (phone == null) {
7734                 loge("setCarrierTestOverride fails with invalid subId: " + subId);
7735                 return;
7736             }
7737             phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn,
7738                     carrierPrivilegeRules, apn);
7739         } finally {
7740             Binder.restoreCallingIdentity(identity);
7741         }
7742     }
7743 
7744     @Override
getCarrierIdListVersion(int subId)7745     public int getCarrierIdListVersion(int subId) {
7746         enforceReadPrivilegedPermission("getCarrierIdListVersion");
7747 
7748         final long identity = Binder.clearCallingIdentity();
7749         try {
7750             final Phone phone = getPhone(subId);
7751             if (phone == null) {
7752                 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
7753                 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
7754             }
7755             return phone.getCarrierIdListVersion();
7756         } finally {
7757             Binder.restoreCallingIdentity(identity);
7758         }
7759     }
7760 
7761     @Override
getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage, String callingFeatureId)7762     public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage,
7763             String callingFeatureId) {
7764         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
7765                 mApp, subId, callingPackage, callingFeatureId,
7766                 "getNumberOfModemsWithSimultaneousDataConnections")) {
7767             return -1;
7768         }
7769 
7770         final long identity = Binder.clearCallingIdentity();
7771         try {
7772             return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
7773         } finally {
7774             Binder.restoreCallingIdentity(identity);
7775         }
7776     }
7777 
7778     @Override
getCdmaRoamingMode(int subId)7779     public int getCdmaRoamingMode(int subId) {
7780         TelephonyPermissions
7781                 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
7782                 mApp, subId, "getCdmaRoamingMode");
7783 
7784         final long identity = Binder.clearCallingIdentity();
7785         try {
7786             return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
7787         } finally {
7788             Binder.restoreCallingIdentity(identity);
7789         }
7790     }
7791 
7792     @Override
setCdmaRoamingMode(int subId, int mode)7793     public boolean setCdmaRoamingMode(int subId, int mode) {
7794         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7795                 mApp, subId, "setCdmaRoamingMode");
7796 
7797         final long identity = Binder.clearCallingIdentity();
7798         try {
7799             return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
7800         } finally {
7801             Binder.restoreCallingIdentity(identity);
7802         }
7803     }
7804 
7805     @Override
setCdmaSubscriptionMode(int subId, int mode)7806     public boolean setCdmaSubscriptionMode(int subId, int mode) {
7807         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7808                 mApp, subId, "setCdmaSubscriptionMode");
7809 
7810         final long identity = Binder.clearCallingIdentity();
7811         try {
7812             return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
7813         } finally {
7814             Binder.restoreCallingIdentity(identity);
7815         }
7816     }
7817 
7818     @Override
getEmergencyNumberList( String callingPackage, String callingFeatureId)7819     public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
7820             String callingPackage, String callingFeatureId) {
7821         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
7822                 mApp, getDefaultSubscription(), callingPackage, callingFeatureId,
7823                 "getEmergencyNumberList")) {
7824             throw new SecurityException("Requires READ_PHONE_STATE permission.");
7825         }
7826         final long identity = Binder.clearCallingIdentity();
7827         try {
7828             Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
7829             for (Phone phone: PhoneFactory.getPhones()) {
7830                 if (phone.getEmergencyNumberTracker() != null
7831                         && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
7832                     emergencyNumberListInternal.put(
7833                             phone.getSubId(),
7834                             phone.getEmergencyNumberTracker().getEmergencyNumberList());
7835                 }
7836             }
7837             return emergencyNumberListInternal;
7838         } finally {
7839             Binder.restoreCallingIdentity(identity);
7840         }
7841     }
7842 
7843     @Override
isEmergencyNumber(String number, boolean exactMatch)7844     public boolean isEmergencyNumber(String number, boolean exactMatch) {
7845         final Phone defaultPhone = getDefaultPhone();
7846         if (!exactMatch) {
7847             TelephonyPermissions
7848                     .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
7849                             mApp, defaultPhone.getSubId(), "isEmergencyNumber(Potential)");
7850         }
7851         final long identity = Binder.clearCallingIdentity();
7852         try {
7853             for (Phone phone: PhoneFactory.getPhones()) {
7854                 if (phone.getEmergencyNumberTracker() != null
7855                         && phone.getEmergencyNumberTracker() != null) {
7856                     if (phone.getEmergencyNumberTracker().isEmergencyNumber(
7857                             number, exactMatch)) {
7858                         return true;
7859                     }
7860                 }
7861             }
7862             return false;
7863         } finally {
7864             Binder.restoreCallingIdentity(identity);
7865         }
7866     }
7867 
7868     /**
7869      * Update emergency number list for test mode.
7870      */
7871     @Override
updateEmergencyNumberListTestMode(int action, EmergencyNumber num)7872     public void updateEmergencyNumberListTestMode(int action, EmergencyNumber num) {
7873         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
7874                 "updateEmergencyNumberListTestMode");
7875 
7876         final long identity = Binder.clearCallingIdentity();
7877         try {
7878             for (Phone phone: PhoneFactory.getPhones()) {
7879                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
7880                 if (tracker != null) {
7881                     tracker.executeEmergencyNumberTestModeCommand(action, num);
7882                 }
7883             }
7884         } finally {
7885             Binder.restoreCallingIdentity(identity);
7886         }
7887     }
7888 
7889     /**
7890      * Get the full emergency number list for test mode.
7891      */
7892     @Override
getEmergencyNumberListTestMode()7893     public List<String> getEmergencyNumberListTestMode() {
7894         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
7895                 "getEmergencyNumberListTestMode");
7896 
7897         final long identity = Binder.clearCallingIdentity();
7898         try {
7899             Set<String> emergencyNumbers = new HashSet<>();
7900             for (Phone phone: PhoneFactory.getPhones()) {
7901                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
7902                 if (tracker != null) {
7903                     for (EmergencyNumber num : tracker.getEmergencyNumberList()) {
7904                         emergencyNumbers.add(num.getNumber());
7905                     }
7906                 }
7907             }
7908             return new ArrayList<>(emergencyNumbers);
7909         } finally {
7910             Binder.restoreCallingIdentity(identity);
7911         }
7912     }
7913 
7914     @Override
getEmergencyNumberDbVersion(int subId)7915     public int getEmergencyNumberDbVersion(int subId) {
7916         enforceReadPrivilegedPermission("getEmergencyNumberDbVersion");
7917 
7918         final long identity = Binder.clearCallingIdentity();
7919         try {
7920             final Phone phone = getPhone(subId);
7921             if (phone == null) {
7922                 loge("getEmergencyNumberDbVersion fails with invalid subId: " + subId);
7923                 return TelephonyManager.INVALID_EMERGENCY_NUMBER_DB_VERSION;
7924             }
7925             return phone.getEmergencyNumberDbVersion();
7926         } finally {
7927             Binder.restoreCallingIdentity(identity);
7928         }
7929     }
7930 
7931     @Override
notifyOtaEmergencyNumberDbInstalled()7932     public void notifyOtaEmergencyNumberDbInstalled() {
7933         enforceModifyPermission();
7934 
7935         final long identity = Binder.clearCallingIdentity();
7936         try {
7937             for (Phone phone: PhoneFactory.getPhones()) {
7938                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
7939                 if (tracker != null) {
7940                     tracker.updateOtaEmergencyNumberDatabase();
7941                 }
7942             }
7943         } finally {
7944             Binder.restoreCallingIdentity(identity);
7945         }
7946     }
7947 
7948     @Override
updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor)7949     public void updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor) {
7950         enforceActiveEmergencySessionPermission();
7951 
7952         final long identity = Binder.clearCallingIdentity();
7953         try {
7954             for (Phone phone: PhoneFactory.getPhones()) {
7955                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
7956                 if (tracker != null) {
7957                     tracker.updateOtaEmergencyNumberDbFilePath(otaParcelFileDescriptor);
7958                 }
7959             }
7960         } finally {
7961             Binder.restoreCallingIdentity(identity);
7962         }
7963     }
7964 
7965     @Override
resetOtaEmergencyNumberDbFilePath()7966     public void resetOtaEmergencyNumberDbFilePath() {
7967         enforceActiveEmergencySessionPermission();
7968 
7969         final long identity = Binder.clearCallingIdentity();
7970         try {
7971             for (Phone phone: PhoneFactory.getPhones()) {
7972                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
7973                 if (tracker != null) {
7974                     tracker.resetOtaEmergencyNumberDbFilePath();
7975                 }
7976             }
7977         } finally {
7978             Binder.restoreCallingIdentity(identity);
7979         }
7980     }
7981 
7982     @Override
getCertsFromCarrierPrivilegeAccessRules(int subId)7983     public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
7984         enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
7985         Phone phone = getPhone(subId);
7986         if (phone == null) {
7987             return null;
7988         }
7989         final long identity = Binder.clearCallingIdentity();
7990         try {
7991             UiccProfile profile = UiccController.getInstance()
7992                     .getUiccProfileForPhone(phone.getPhoneId());
7993             if (profile != null) {
7994                 return profile.getCertsFromCarrierPrivilegeAccessRules();
7995             }
7996         } finally {
7997             Binder.restoreCallingIdentity(identity);
7998         }
7999         return null;
8000     }
8001 
8002     /**
8003      * Enable or disable a modem stack.
8004      */
8005     @Override
enableModemForSlot(int slotIndex, boolean enable)8006     public boolean enableModemForSlot(int slotIndex, boolean enable) {
8007         enforceModifyPermission();
8008 
8009         final long identity = Binder.clearCallingIdentity();
8010         try {
8011             Phone phone = PhoneFactory.getPhone(slotIndex);
8012             if (phone == null) {
8013                 return false;
8014             } else {
8015                 return (Boolean) sendRequest(CMD_REQUEST_ENABLE_MODEM, enable, phone, null);
8016             }
8017         } finally {
8018             Binder.restoreCallingIdentity(identity);
8019         }
8020     }
8021 
8022     /**
8023      * Whether a modem stack is enabled or not.
8024      */
8025     @Override
isModemEnabledForSlot(int slotIndex, String callingPackage, String callingFeatureId)8026     public boolean isModemEnabledForSlot(int slotIndex, String callingPackage,
8027             String callingFeatureId) {
8028         Phone phone = PhoneFactory.getPhone(slotIndex);
8029         if (phone == null) return false;
8030 
8031         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
8032                 mApp, phone.getSubId(), callingPackage, callingFeatureId,
8033                 "isModemEnabledForSlot")) {
8034             throw new SecurityException("Requires READ_PHONE_STATE permission.");
8035         }
8036 
8037         final long identity = Binder.clearCallingIdentity();
8038         try {
8039             try {
8040                 return mPhoneConfigurationManager.getPhoneStatusFromCache(phone.getPhoneId());
8041             } catch (NoSuchElementException ex) {
8042                 return (Boolean) sendRequest(CMD_GET_MODEM_STATUS, null, phone, null);
8043             }
8044         } finally {
8045             Binder.restoreCallingIdentity(identity);
8046         }
8047     }
8048 
8049     @Override
setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted)8050     public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
8051         enforceModifyPermission();
8052 
8053         final long identity = Binder.clearCallingIdentity();
8054         try {
8055             mTelephonySharedPreferences.edit()
8056                     .putBoolean(PREF_MULTI_SIM_RESTRICTED, isMultiSimCarrierRestricted)
8057                     .commit();
8058         } finally {
8059             Binder.restoreCallingIdentity(identity);
8060         }
8061     }
8062 
8063     @Override
8064     @TelephonyManager.IsMultiSimSupportedResult
isMultiSimSupported(String callingPackage, String callingFeatureId)8065     public int isMultiSimSupported(String callingPackage, String callingFeatureId) {
8066         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
8067                 getDefaultPhone().getSubId(), callingPackage, callingFeatureId,
8068                 "isMultiSimSupported")) {
8069             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
8070         }
8071 
8072         final long identity = Binder.clearCallingIdentity();
8073         try {
8074             return isMultiSimSupportedInternal();
8075         } finally {
8076             Binder.restoreCallingIdentity(identity);
8077         }
8078     }
8079 
8080     @TelephonyManager.IsMultiSimSupportedResult
isMultiSimSupportedInternal()8081     private int isMultiSimSupportedInternal() {
8082         // If the device has less than 2 SIM cards, indicate that multisim is restricted.
8083         int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
8084         if (numPhysicalSlots < 2) {
8085             loge("isMultiSimSupportedInternal: requires at least 2 cards");
8086             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
8087         }
8088         // Check if the hardware supports multisim functionality. If usage of multisim is not
8089         // supported by the modem, indicate that it is restricted.
8090         PhoneCapability staticCapability =
8091                 mPhoneConfigurationManager.getStaticPhoneCapability();
8092         if (staticCapability == null) {
8093             loge("isMultiSimSupportedInternal: no static configuration available");
8094             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
8095         }
8096         if (staticCapability.logicalModemList.size() < 2) {
8097             loge("isMultiSimSupportedInternal: maximum number of modem is < 2");
8098             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
8099         }
8100         // Check if support of multiple SIMs is restricted by carrier
8101         if (mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false)) {
8102             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_CARRIER;
8103         }
8104 
8105         return TelephonyManager.MULTISIM_ALLOWED;
8106     }
8107 
8108     /**
8109      * Switch configs to enable multi-sim or switch back to single-sim
8110      * Note: Switch from multi-sim to single-sim is only possible with MODIFY_PHONE_STATE
8111      * permission, but the other way around is possible with either MODIFY_PHONE_STATE
8112      * or carrier privileges
8113      * @param numOfSims number of active sims we want to switch to
8114      */
8115     @Override
switchMultiSimConfig(int numOfSims)8116     public void switchMultiSimConfig(int numOfSims) {
8117         if (numOfSims == 1) {
8118             enforceModifyPermission();
8119         } else {
8120             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8121                     mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
8122         }
8123         final long identity = Binder.clearCallingIdentity();
8124 
8125         try {
8126             //only proceed if multi-sim is not restricted
8127             if (isMultiSimSupportedInternal() != TelephonyManager.MULTISIM_ALLOWED) {
8128                 loge("switchMultiSimConfig not possible. It is restricted or not supported.");
8129                 return;
8130             }
8131             mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
8132         } finally {
8133             Binder.restoreCallingIdentity(identity);
8134         }
8135     }
8136 
8137     @Override
isApplicationOnUicc(int subId, int appType)8138     public boolean isApplicationOnUicc(int subId, int appType) {
8139         enforceReadPrivilegedPermission("isApplicationOnUicc");
8140         Phone phone = getPhone(subId);
8141         if (phone == null) {
8142             return false;
8143         }
8144         final long identity = Binder.clearCallingIdentity();
8145         try {
8146             UiccCard uiccCard = phone.getUiccCard();
8147             if (uiccCard == null) {
8148                 return false;
8149             }
8150             UiccProfile uiccProfile = uiccCard.getUiccProfile();
8151             if (uiccProfile == null) {
8152                 return false;
8153             }
8154             if (TelephonyManager.APPTYPE_SIM <= appType
8155                     && appType <= TelephonyManager.APPTYPE_ISIM) {
8156                 return uiccProfile.isApplicationOnIcc(AppType.values()[appType]);
8157             }
8158             return false;
8159         } finally {
8160             Binder.restoreCallingIdentity(identity);
8161         }
8162     }
8163 
8164     /**
8165      * Get whether making changes to modem configurations will trigger reboot.
8166      * Return value defaults to true.
8167      */
8168     @Override
doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage, String callingFeatureId)8169     public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage,
8170             String callingFeatureId) {
8171         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
8172                 mApp, subId, callingPackage, callingFeatureId,
8173                 "doesSwitchMultiSimConfigTriggerReboot")) {
8174             return false;
8175         }
8176         final long identity = Binder.clearCallingIdentity();
8177         try {
8178             return mPhoneConfigurationManager.isRebootRequiredForModemConfigChange();
8179         } finally {
8180             Binder.restoreCallingIdentity(identity);
8181         }
8182     }
8183 
updateModemStateMetrics()8184     private void updateModemStateMetrics() {
8185         TelephonyMetrics metrics = TelephonyMetrics.getInstance();
8186         // TODO: check the state for each modem if the api is ready.
8187         metrics.updateEnabledModemBitmap((1 << TelephonyManager.from(mApp).getPhoneCount()) - 1);
8188     }
8189 
8190     @Override
getSlotsMapping()8191     public int[] getSlotsMapping() {
8192         enforceReadPrivilegedPermission("getSlotsMapping");
8193 
8194         final long identity = Binder.clearCallingIdentity();
8195         try {
8196             int phoneCount = TelephonyManager.getDefault().getPhoneCount();
8197             // All logical slots should have a mapping to a physical slot.
8198             int[] logicalSlotsMapping = new int[phoneCount];
8199             UiccSlotInfo[] slotInfos = getUiccSlotsInfo();
8200             for (int i = 0; i < slotInfos.length; i++) {
8201                 if (SubscriptionManager.isValidPhoneId(slotInfos[i].getLogicalSlotIdx())) {
8202                     logicalSlotsMapping[slotInfos[i].getLogicalSlotIdx()] = i;
8203                 }
8204             }
8205             return logicalSlotsMapping;
8206         } finally {
8207             Binder.restoreCallingIdentity(identity);
8208         }
8209     }
8210 
8211     /**
8212      * Get the IRadio HAL Version
8213      */
8214     @Override
getRadioHalVersion()8215     public int getRadioHalVersion() {
8216         Phone phone = getDefaultPhone();
8217         if (phone == null) return -1;
8218         HalVersion hv = phone.getHalVersion();
8219         if (hv.equals(HalVersion.UNKNOWN)) return -1;
8220         return hv.major * 100 + hv.minor;
8221     }
8222 
8223     /**
8224      * Get the current calling package name.
8225      * @return the current calling package name
8226      */
8227     @Override
getCurrentPackageName()8228     public String getCurrentPackageName() {
8229         return mApp.getPackageManager().getPackagesForUid(Binder.getCallingUid())[0];
8230     }
8231 
8232     /**
8233      * Return whether data is enabled for certain APN type. This will tell if framework will accept
8234      * corresponding network requests on a subId.
8235      *
8236      *  Data is enabled if:
8237      *  1) user data is turned on, or
8238      *  2) APN is un-metered for this subscription, or
8239      *  3) APN type is whitelisted. E.g. MMS is whitelisted if
8240      *  {@link TelephonyManager#setAlwaysAllowMmsData} is turned on.
8241      *
8242      * @return whether data is allowed for a apn type.
8243      *
8244      * @hide
8245      */
8246     @Override
isDataEnabledForApn(int apnType, int subId, String callingPackage)8247     public boolean isDataEnabledForApn(int apnType, int subId, String callingPackage) {
8248         enforceReadPrivilegedPermission("Needs READ_PRIVILEGED_PHONE_STATE for "
8249                 + "isDataEnabledForApn");
8250 
8251         // Now that all security checks passes, perform the operation as ourselves.
8252         final long identity = Binder.clearCallingIdentity();
8253         try {
8254             Phone phone = getPhone(subId);
8255             if (phone == null) return false;
8256 
8257             boolean isMetered = ApnSettingUtils.isMeteredApnType(apnType, phone);
8258             return !isMetered || phone.getDataEnabledSettings().isDataEnabled(apnType);
8259         } finally {
8260             Binder.restoreCallingIdentity(identity);
8261         }
8262     }
8263 
8264     @Override
isApnMetered(@pnType int apnType, int subId)8265     public boolean isApnMetered(@ApnType int apnType, int subId) {
8266         enforceReadPrivilegedPermission("isApnMetered");
8267 
8268         // Now that all security checks passes, perform the operation as ourselves.
8269         final long identity = Binder.clearCallingIdentity();
8270         try {
8271             Phone phone = getPhone(subId);
8272             if (phone == null) return true; // By default return true.
8273 
8274             return ApnSettingUtils.isMeteredApnType(apnType, phone);
8275         } finally {
8276             Binder.restoreCallingIdentity(identity);
8277         }
8278     }
8279 
8280     @Override
setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers, int subscriptionId, IBooleanConsumer resultCallback)8281     public void setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers,
8282             int subscriptionId, IBooleanConsumer resultCallback) {
8283         enforceModifyPermission();
8284         long token = Binder.clearCallingIdentity();
8285         try {
8286             Phone phone = getPhone(subscriptionId);
8287             if (phone == null) {
8288                 try {
8289                     if (resultCallback != null) {
8290                         resultCallback.accept(false);
8291                     }
8292                 } catch (RemoteException e) {
8293                     // ignore
8294                 }
8295                 return;
8296             }
8297             Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> argument =
8298                     Pair.create(specifiers, (x) -> {
8299                         try {
8300                             if (resultCallback != null) {
8301                                 resultCallback.accept(x);
8302                             }
8303                         } catch (RemoteException e) {
8304                             // ignore
8305                         }
8306                     });
8307             sendRequestAsync(CMD_SET_SYSTEM_SELECTION_CHANNELS, argument, phone, null);
8308         } finally {
8309             Binder.restoreCallingIdentity(token);
8310         }
8311     }
8312 
8313     @Override
isMvnoMatched(int subId, int mvnoType, @NonNull String mvnoMatchData)8314     public boolean isMvnoMatched(int subId, int mvnoType, @NonNull String mvnoMatchData) {
8315         enforceReadPrivilegedPermission("isMvnoMatched");
8316         IccRecords iccRecords = UiccController.getInstance().getIccRecords(
8317                 SubscriptionManager.getPhoneId(subId), UiccController.APP_FAM_3GPP);
8318         if (iccRecords == null) {
8319             Log.d(LOG_TAG, "isMvnoMatched# IccRecords is null");
8320             return false;
8321         }
8322         return ApnSettingUtils.mvnoMatches(iccRecords, mvnoType, mvnoMatchData);
8323     }
8324 
8325     @Override
enqueueSmsPickResult(String callingPackage, String callingAttributionTag, IIntegerConsumer pendingSubIdResult)8326     public void enqueueSmsPickResult(String callingPackage, String callingAttributionTag,
8327             IIntegerConsumer pendingSubIdResult) {
8328         if (callingPackage == null) {
8329             callingPackage = getCurrentPackageName();
8330         }
8331         SmsPermissions permissions = new SmsPermissions(getDefaultPhone(), mApp,
8332                 (AppOpsManager) mApp.getSystemService(Context.APP_OPS_SERVICE));
8333         if (!permissions.checkCallingCanSendSms(callingPackage, callingAttributionTag,
8334                 "Sending message")) {
8335             throw new SecurityException("Requires SEND_SMS permission to perform this operation");
8336         }
8337         PickSmsSubscriptionActivity.addPendingResult(pendingSubIdResult);
8338         Intent intent = new Intent();
8339         intent.setClass(mApp, PickSmsSubscriptionActivity.class);
8340         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8341         // Bring up choose default SMS subscription dialog right now
8342         intent.putExtra(PickSmsSubscriptionActivity.DIALOG_TYPE_KEY,
8343                 PickSmsSubscriptionActivity.SMS_PICK_FOR_MESSAGE);
8344         mApp.startActivity(intent);
8345     }
8346 
8347     @Override
getMmsUAProfUrl(int subId)8348     public String getMmsUAProfUrl(int subId) {
8349         //TODO investigate if this API should require proper permission check in R b/133791609
8350         final long identity = Binder.clearCallingIdentity();
8351         try {
8352             return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
8353                     .getString(com.android.internal.R.string.config_mms_user_agent_profile_url);
8354         } finally {
8355             Binder.restoreCallingIdentity(identity);
8356         }
8357     }
8358 
8359     @Override
getMmsUserAgent(int subId)8360     public String getMmsUserAgent(int subId) {
8361         //TODO investigate if this API should require proper permission check in R b/133791609
8362         final long identity = Binder.clearCallingIdentity();
8363         try {
8364             return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
8365                     .getString(com.android.internal.R.string.config_mms_user_agent);
8366         } finally {
8367             Binder.restoreCallingIdentity(identity);
8368         }
8369     }
8370 
8371     @Override
setDataAllowedDuringVoiceCall(int subId, boolean allow)8372     public boolean setDataAllowedDuringVoiceCall(int subId, boolean allow) {
8373         enforceModifyPermission();
8374 
8375         // Now that all security checks passes, perform the operation as ourselves.
8376         final long identity = Binder.clearCallingIdentity();
8377         try {
8378             Phone phone = getPhone(subId);
8379             if (phone == null) return false;
8380 
8381             return phone.getDataEnabledSettings().setAllowDataDuringVoiceCall(allow);
8382         } finally {
8383             Binder.restoreCallingIdentity(identity);
8384         }
8385     }
8386 
8387     @Override
isDataAllowedInVoiceCall(int subId)8388     public boolean isDataAllowedInVoiceCall(int subId) {
8389         enforceReadPrivilegedPermission("isDataAllowedInVoiceCall");
8390 
8391         // Now that all security checks passes, perform the operation as ourselves.
8392         final long identity = Binder.clearCallingIdentity();
8393         try {
8394             Phone phone = getPhone(subId);
8395             if (phone == null) return false;
8396 
8397             return phone.getDataEnabledSettings().isDataAllowedInVoiceCall();
8398         } finally {
8399             Binder.restoreCallingIdentity(identity);
8400         }
8401     }
8402 
8403     @Override
setAlwaysAllowMmsData(int subId, boolean alwaysAllow)8404     public boolean setAlwaysAllowMmsData(int subId, boolean alwaysAllow) {
8405         enforceModifyPermission();
8406 
8407         // Now that all security checks passes, perform the operation as ourselves.
8408         final long identity = Binder.clearCallingIdentity();
8409         try {
8410             Phone phone = getPhone(subId);
8411             if (phone == null) return false;
8412 
8413             return phone.getDataEnabledSettings().setAlwaysAllowMmsData(alwaysAllow);
8414         } finally {
8415             Binder.restoreCallingIdentity(identity);
8416         }
8417     }
8418 
8419     /**
8420      * Updates whether conference event pacakge handling is enabled.
8421      * @param isCepEnabled {@code true} if CEP handling is enabled (default), or {@code false}
8422      *                                 otherwise.
8423      */
8424     @Override
setCepEnabled(boolean isCepEnabled)8425     public void setCepEnabled(boolean isCepEnabled) {
8426         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCepEnabled");
8427 
8428         final long identity = Binder.clearCallingIdentity();
8429         try {
8430             Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled);
8431             for (Phone phone : PhoneFactory.getPhones()) {
8432                 Phone defaultPhone = phone.getImsPhone();
8433                 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
8434                     ImsPhone imsPhone = (ImsPhone) defaultPhone;
8435                     ImsPhoneCallTracker imsPhoneCallTracker =
8436                             (ImsPhoneCallTracker) imsPhone.getCallTracker();
8437                     imsPhoneCallTracker.setConferenceEventPackageEnabled(isCepEnabled);
8438                     Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled + ", for imsPhone "
8439                             + imsPhone.getMsisdn());
8440                 }
8441             }
8442         } finally {
8443             Binder.restoreCallingIdentity(identity);
8444         }
8445     }
8446 
8447     /**
8448      * Notify that an RCS autoconfiguration XML file has been received for provisioning.
8449      *
8450      * @param config       The XML file to be read. ASCII/UTF8 encoded text if not compressed.
8451      * @param isCompressed The XML file is compressed in gzip format and must be decompressed
8452      *                     before being read.
8453      */
8454     @Override
notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean isCompressed)8455     public void notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean
8456             isCompressed) {
8457         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8458                 mApp, subId, "notifyRcsAutoConfigurationReceived");
8459         try {
8460             IImsConfig configBinder = getImsConfig(getSlotIndex(subId), ImsFeature.FEATURE_RCS);
8461             if (configBinder == null) {
8462                 Rlog.e(LOG_TAG, "null result for getImsConfig");
8463             } else {
8464                 configBinder.notifyRcsAutoConfigurationReceived(config, isCompressed);
8465             }
8466         } catch (RemoteException e) {
8467             Rlog.e(LOG_TAG, "fail to getImsConfig " + e.getMessage());
8468         }
8469     }
8470 
8471     @Override
isIccLockEnabled(int subId)8472     public boolean isIccLockEnabled(int subId) {
8473         enforceReadPrivilegedPermission("isIccLockEnabled");
8474 
8475         // Now that all security checks passes, perform the operation as ourselves.
8476         final long identity = Binder.clearCallingIdentity();
8477         try {
8478             Phone phone = getPhone(subId);
8479             if (phone != null && phone.getIccCard() != null) {
8480                 return phone.getIccCard().getIccLockEnabled();
8481             } else {
8482                 return false;
8483             }
8484         } finally {
8485             Binder.restoreCallingIdentity(identity);
8486         }
8487     }
8488 
8489     /**
8490      * Set the ICC pin lock enabled or disabled.
8491      *
8492      * @return an integer representing the status of IccLock enabled or disabled in the following
8493      * three cases:
8494      *   - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if enabled or disabled IccLock
8495      *   successfully.
8496      *   - Positive number and zero for remaining password attempts.
8497      *   - Negative number for other failure cases (such like enabling/disabling PIN failed).
8498      *
8499      */
8500     @Override
setIccLockEnabled(int subId, boolean enabled, String password)8501     public int setIccLockEnabled(int subId, boolean enabled, String password) {
8502         enforceModifyPermission();
8503 
8504         Phone phone = getPhone(subId);
8505         if (phone == null) {
8506             return 0;
8507         }
8508         // Now that all security checks passes, perform the operation as ourselves.
8509         final long identity = Binder.clearCallingIdentity();
8510         try {
8511             int attemptsRemaining = (int) sendRequest(CMD_SET_ICC_LOCK_ENABLED,
8512                     new Pair<Boolean, String>(enabled, password), phone, null);
8513             return attemptsRemaining;
8514 
8515         } catch (Exception e) {
8516             Log.e(LOG_TAG, "setIccLockEnabled. Exception e =" + e);
8517         } finally {
8518             Binder.restoreCallingIdentity(identity);
8519         }
8520         return 0;
8521     }
8522 
8523     /**
8524      * Change the ICC password used in ICC pin lock.
8525      *
8526      * @return an integer representing the status of IccLock changed in the following three cases:
8527      *   - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if changed IccLock successfully.
8528      *   - Positive number and zero for remaining password attempts.
8529      *   - Negative number for other failure cases (such like enabling/disabling PIN failed).
8530      *
8531      */
8532     @Override
changeIccLockPassword(int subId, String oldPassword, String newPassword)8533     public int changeIccLockPassword(int subId, String oldPassword, String newPassword) {
8534         enforceModifyPermission();
8535 
8536         Phone phone = getPhone(subId);
8537         if (phone == null) {
8538             return 0;
8539         }
8540         // Now that all security checks passes, perform the operation as ourselves.
8541         final long identity = Binder.clearCallingIdentity();
8542         try {
8543             int attemptsRemaining = (int) sendRequest(CMD_CHANGE_ICC_LOCK_PASSWORD,
8544                     new Pair<String, String>(oldPassword, newPassword), phone, null);
8545             return attemptsRemaining;
8546 
8547         } catch (Exception e) {
8548             Log.e(LOG_TAG, "changeIccLockPassword. Exception e =" + e);
8549         } finally {
8550             Binder.restoreCallingIdentity(identity);
8551         }
8552         return 0;
8553     }
8554 
8555     /**
8556      * Request for receiving user activity notification
8557      */
8558     @Override
requestUserActivityNotification()8559     public void requestUserActivityNotification() {
8560         if (!mNotifyUserActivity.get()
8561                 && !mMainThreadHandler.hasMessages(MSG_NOTIFY_USER_ACTIVITY)) {
8562             mNotifyUserActivity.set(true);
8563         }
8564     }
8565 
8566     /**
8567      * Called when userActivity is signalled in the power manager.
8568      * This is safe to call from any thread, with any window manager locks held or not.
8569      */
8570     @Override
userActivity()8571     public void userActivity() {
8572         // ***************************************
8573         // *  Inherited from PhoneWindowManager  *
8574         // ***************************************
8575         // THIS IS CALLED FROM DEEP IN THE POWER MANAGER
8576         // WITH ITS LOCKS HELD.
8577         //
8578         // This code must be VERY careful about the locks
8579         // it acquires.
8580         // In fact, the current code acquires way too many,
8581         // and probably has lurking deadlocks.
8582 
8583         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8584             throw new SecurityException("Only the OS may call notifyUserActivity()");
8585         }
8586 
8587         if (mNotifyUserActivity.getAndSet(false)) {
8588             mMainThreadHandler.sendEmptyMessageDelayed(MSG_NOTIFY_USER_ACTIVITY,
8589                     USER_ACTIVITY_NOTIFICATION_DELAY);
8590         }
8591     }
8592 
8593     @Override
canConnectTo5GInDsdsMode()8594     public boolean canConnectTo5GInDsdsMode() {
8595         return mApp.getResources().getBoolean(R.bool.config_5g_connection_in_dsds_mode);
8596     }
8597 }
8598