• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_CDMA;
22 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_GSM;
23 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_IMS;
24 import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
25 
26 import android.Manifest;
27 import android.Manifest.permission;
28 import android.annotation.NonNull;
29 import android.annotation.Nullable;
30 import android.app.AppOpsManager;
31 import android.app.PendingIntent;
32 import android.app.compat.CompatChanges;
33 import android.app.role.RoleManager;
34 import android.content.ComponentName;
35 import android.content.ContentResolver;
36 import android.content.Context;
37 import android.content.Intent;
38 import android.content.SharedPreferences;
39 import android.content.pm.ComponentInfo;
40 import android.content.pm.PackageInfo;
41 import android.content.pm.PackageManager;
42 import android.net.Uri;
43 import android.os.AsyncResult;
44 import android.os.Binder;
45 import android.os.Build;
46 import android.os.Bundle;
47 import android.os.Handler;
48 import android.os.IBinder;
49 import android.os.Looper;
50 import android.os.Message;
51 import android.os.Messenger;
52 import android.os.ParcelFileDescriptor;
53 import android.os.ParcelUuid;
54 import android.os.PersistableBundle;
55 import android.os.Process;
56 import android.os.RemoteException;
57 import android.os.ResultReceiver;
58 import android.os.ServiceSpecificException;
59 import android.os.SystemClock;
60 import android.os.UserHandle;
61 import android.os.UserManager;
62 import android.os.WorkSource;
63 import android.preference.PreferenceManager;
64 import android.provider.DeviceConfig;
65 import android.provider.Settings;
66 import android.provider.Telephony;
67 import android.sysprop.TelephonyProperties;
68 import android.telecom.PhoneAccount;
69 import android.telecom.PhoneAccountHandle;
70 import android.telecom.TelecomManager;
71 import android.telephony.Annotation.ApnType;
72 import android.telephony.Annotation.ThermalMitigationResult;
73 import android.telephony.CallForwardingInfo;
74 import android.telephony.CarrierConfigManager;
75 import android.telephony.CarrierRestrictionRules;
76 import android.telephony.CellIdentity;
77 import android.telephony.CellIdentityCdma;
78 import android.telephony.CellIdentityGsm;
79 import android.telephony.CellInfo;
80 import android.telephony.CellInfoGsm;
81 import android.telephony.CellInfoWcdma;
82 import android.telephony.ClientRequestStats;
83 import android.telephony.DataThrottlingRequest;
84 import android.telephony.IBootstrapAuthenticationCallback;
85 import android.telephony.ICellInfoCallback;
86 import android.telephony.IccOpenLogicalChannelResponse;
87 import android.telephony.LocationAccessPolicy;
88 import android.telephony.ModemActivityInfo;
89 import android.telephony.NeighboringCellInfo;
90 import android.telephony.NetworkScanRequest;
91 import android.telephony.PhoneCapability;
92 import android.telephony.PhoneNumberRange;
93 import android.telephony.RadioAccessFamily;
94 import android.telephony.RadioAccessSpecifier;
95 import android.telephony.ServiceState;
96 import android.telephony.SignalStrength;
97 import android.telephony.SignalStrengthUpdateRequest;
98 import android.telephony.SignalThresholdInfo;
99 import android.telephony.SubscriptionInfo;
100 import android.telephony.SubscriptionManager;
101 import android.telephony.TelephonyFrameworkInitializer;
102 import android.telephony.TelephonyHistogram;
103 import android.telephony.TelephonyManager;
104 import android.telephony.TelephonyScanManager;
105 import android.telephony.ThermalMitigationRequest;
106 import android.telephony.UiccCardInfo;
107 import android.telephony.UiccSlotInfo;
108 import android.telephony.UssdResponse;
109 import android.telephony.VisualVoicemailSmsFilterSettings;
110 import android.telephony.data.ApnSetting;
111 import android.telephony.data.NetworkSlicingConfig;
112 import android.telephony.emergency.EmergencyNumber;
113 import android.telephony.gba.GbaAuthRequest;
114 import android.telephony.gba.UaSecurityProtocolIdentifier;
115 import android.telephony.ims.ImsException;
116 import android.telephony.ims.ProvisioningManager;
117 import android.telephony.ims.RcsClientConfiguration;
118 import android.telephony.ims.RcsContactUceCapability;
119 import android.telephony.ims.RegistrationManager;
120 import android.telephony.ims.aidl.IImsCapabilityCallback;
121 import android.telephony.ims.aidl.IImsConfig;
122 import android.telephony.ims.aidl.IImsConfigCallback;
123 import android.telephony.ims.aidl.IImsRegistration;
124 import android.telephony.ims.aidl.IImsRegistrationCallback;
125 import android.telephony.ims.aidl.IRcsConfigCallback;
126 import android.telephony.ims.feature.ImsFeature;
127 import android.telephony.ims.feature.MmTelFeature;
128 import android.telephony.ims.feature.RcsFeature;
129 import android.telephony.ims.stub.ImsConfigImplBase;
130 import android.telephony.ims.stub.ImsRegistrationImplBase;
131 import android.text.TextUtils;
132 import android.util.ArraySet;
133 import android.util.EventLog;
134 import android.util.Log;
135 import android.util.Pair;
136 
137 import com.android.ims.ImsManager;
138 import com.android.ims.internal.IImsServiceFeatureCallback;
139 import com.android.ims.rcs.uce.eab.EabUtil;
140 import com.android.internal.annotations.VisibleForTesting;
141 import com.android.internal.telephony.CallForwardInfo;
142 import com.android.internal.telephony.CallManager;
143 import com.android.internal.telephony.CallStateException;
144 import com.android.internal.telephony.CallTracker;
145 import com.android.internal.telephony.CarrierResolver;
146 import com.android.internal.telephony.CellNetworkScanResult;
147 import com.android.internal.telephony.CommandException;
148 import com.android.internal.telephony.CommandsInterface;
149 import com.android.internal.telephony.DefaultPhoneNotifier;
150 import com.android.internal.telephony.GbaManager;
151 import com.android.internal.telephony.GsmCdmaPhone;
152 import com.android.internal.telephony.HalVersion;
153 import com.android.internal.telephony.IBooleanConsumer;
154 import com.android.internal.telephony.ICallForwardingInfoCallback;
155 import com.android.internal.telephony.IIntegerConsumer;
156 import com.android.internal.telephony.INumberVerificationCallback;
157 import com.android.internal.telephony.ITelephony;
158 import com.android.internal.telephony.IccCard;
159 import com.android.internal.telephony.LocaleTracker;
160 import com.android.internal.telephony.NetworkScanRequestTracker;
161 import com.android.internal.telephony.OperatorInfo;
162 import com.android.internal.telephony.Phone;
163 import com.android.internal.telephony.PhoneConfigurationManager;
164 import com.android.internal.telephony.PhoneConstantConversions;
165 import com.android.internal.telephony.PhoneConstants;
166 import com.android.internal.telephony.PhoneFactory;
167 import com.android.internal.telephony.ProxyController;
168 import com.android.internal.telephony.RIL;
169 import com.android.internal.telephony.RILConstants;
170 import com.android.internal.telephony.RadioInterfaceCapabilityController;
171 import com.android.internal.telephony.ServiceStateTracker;
172 import com.android.internal.telephony.SmsController;
173 import com.android.internal.telephony.SmsPermissions;
174 import com.android.internal.telephony.SubscriptionController;
175 import com.android.internal.telephony.TelephonyIntents;
176 import com.android.internal.telephony.TelephonyPermissions;
177 import com.android.internal.telephony.dataconnection.ApnSettingUtils;
178 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
179 import com.android.internal.telephony.euicc.EuiccConnector;
180 import com.android.internal.telephony.ims.ImsResolver;
181 import com.android.internal.telephony.imsphone.ImsPhone;
182 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
183 import com.android.internal.telephony.metrics.TelephonyMetrics;
184 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
185 import com.android.internal.telephony.uicc.IccIoResult;
186 import com.android.internal.telephony.uicc.IccRecords;
187 import com.android.internal.telephony.uicc.IccUtils;
188 import com.android.internal.telephony.uicc.SIMRecords;
189 import com.android.internal.telephony.uicc.UiccCard;
190 import com.android.internal.telephony.uicc.UiccCardApplication;
191 import com.android.internal.telephony.uicc.UiccController;
192 import com.android.internal.telephony.uicc.UiccProfile;
193 import com.android.internal.telephony.uicc.UiccSlot;
194 import com.android.internal.telephony.util.LocaleUtils;
195 import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
196 import com.android.internal.util.FunctionalUtils;
197 import com.android.internal.util.HexDump;
198 import com.android.phone.callcomposer.CallComposerPictureManager;
199 import com.android.phone.callcomposer.CallComposerPictureTransfer;
200 import com.android.phone.callcomposer.ImageData;
201 import com.android.phone.settings.PickSmsSubscriptionActivity;
202 import com.android.phone.vvm.PhoneAccountHandleConverter;
203 import com.android.phone.vvm.RemoteVvmTaskManager;
204 import com.android.phone.vvm.VisualVoicemailSettingsUtil;
205 import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
206 import com.android.services.telephony.TelecomAccountRegistry;
207 import com.android.services.telephony.TelephonyConnectionService;
208 import com.android.telephony.Rlog;
209 
210 import java.io.ByteArrayOutputStream;
211 import java.io.FileDescriptor;
212 import java.io.IOException;
213 import java.io.InputStream;
214 import java.io.PrintWriter;
215 import java.util.ArrayList;
216 import java.util.Arrays;
217 import java.util.HashMap;
218 import java.util.HashSet;
219 import java.util.List;
220 import java.util.Locale;
221 import java.util.Map;
222 import java.util.NoSuchElementException;
223 import java.util.Objects;
224 import java.util.Set;
225 import java.util.concurrent.Executors;
226 import java.util.concurrent.atomic.AtomicBoolean;
227 import java.util.function.Consumer;
228 
229 /**
230  * Implementation of the ITelephony interface.
231  */
232 public class PhoneInterfaceManager extends ITelephony.Stub {
233     private static final String LOG_TAG = "PhoneInterfaceManager";
234     private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
235     private static final boolean DBG_LOC = false;
236     private static final boolean DBG_MERGE = false;
237 
238     // Message codes used with mMainThreadHandler
239     private static final int CMD_HANDLE_PIN_MMI = 1;
240     private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
241     private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
242     private static final int CMD_OPEN_CHANNEL = 9;
243     private static final int EVENT_OPEN_CHANNEL_DONE = 10;
244     private static final int CMD_CLOSE_CHANNEL = 11;
245     private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
246     private static final int CMD_NV_READ_ITEM = 13;
247     private static final int EVENT_NV_READ_ITEM_DONE = 14;
248     private static final int CMD_NV_WRITE_ITEM = 15;
249     private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
250     private static final int CMD_NV_WRITE_CDMA_PRL = 17;
251     private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
252     private static final int CMD_RESET_MODEM_CONFIG = 19;
253     private static final int EVENT_RESET_MODEM_CONFIG_DONE = 20;
254     private static final int CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK = 21;
255     private static final int EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE = 22;
256     private static final int CMD_SEND_ENVELOPE = 25;
257     private static final int EVENT_SEND_ENVELOPE_DONE = 26;
258     private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
259     private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
260     private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
261     private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
262     private static final int CMD_EXCHANGE_SIM_IO = 31;
263     private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
264     private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
265     private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
266     private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
267     private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
268     private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
269     private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
270     private static final int CMD_PERFORM_NETWORK_SCAN = 39;
271     private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
272     private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
273     private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
274     private static final int CMD_SET_ALLOWED_CARRIERS = 43;
275     private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
276     private static final int CMD_GET_ALLOWED_CARRIERS = 45;
277     private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
278     private static final int CMD_HANDLE_USSD_REQUEST = 47;
279     private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
280     private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
281     private static final int CMD_SWITCH_SLOTS = 50;
282     private static final int EVENT_SWITCH_SLOTS_DONE = 51;
283     private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
284     private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
285     private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
286     private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
287     private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
288     private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
289     private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
290     private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
291     private static final int CMD_GET_ALL_CELL_INFO = 60;
292     private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
293     private static final int CMD_GET_CELL_LOCATION = 62;
294     private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
295     private static final int CMD_MODEM_REBOOT = 64;
296     private static final int EVENT_CMD_MODEM_REBOOT_DONE = 65;
297     private static final int CMD_REQUEST_CELL_INFO_UPDATE = 66;
298     private static final int EVENT_REQUEST_CELL_INFO_UPDATE_DONE = 67;
299     private static final int CMD_REQUEST_ENABLE_MODEM = 68;
300     private static final int EVENT_ENABLE_MODEM_DONE = 69;
301     private static final int CMD_GET_MODEM_STATUS = 70;
302     private static final int EVENT_GET_MODEM_STATUS_DONE = 71;
303     private static final int CMD_SET_FORBIDDEN_PLMNS = 72;
304     private static final int EVENT_SET_FORBIDDEN_PLMNS_DONE = 73;
305     private static final int CMD_ERASE_MODEM_CONFIG = 74;
306     private static final int EVENT_ERASE_MODEM_CONFIG_DONE = 75;
307     private static final int CMD_CHANGE_ICC_LOCK_PASSWORD = 76;
308     private static final int EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE = 77;
309     private static final int CMD_SET_ICC_LOCK_ENABLED = 78;
310     private static final int EVENT_SET_ICC_LOCK_ENABLED_DONE = 79;
311     private static final int CMD_SET_SYSTEM_SELECTION_CHANNELS = 80;
312     private static final int EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE = 81;
313     private static final int MSG_NOTIFY_USER_ACTIVITY = 82;
314     private static final int CMD_GET_CALL_FORWARDING = 83;
315     private static final int EVENT_GET_CALL_FORWARDING_DONE = 84;
316     private static final int CMD_SET_CALL_FORWARDING = 85;
317     private static final int EVENT_SET_CALL_FORWARDING_DONE = 86;
318     private static final int CMD_GET_CALL_WAITING = 87;
319     private static final int EVENT_GET_CALL_WAITING_DONE = 88;
320     private static final int CMD_SET_CALL_WAITING = 89;
321     private static final int EVENT_SET_CALL_WAITING_DONE = 90;
322     private static final int CMD_ENABLE_NR_DUAL_CONNECTIVITY = 91;
323     private static final int EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE = 92;
324     private static final int CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED = 93;
325     private static final int EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE = 94;
326     private static final int CMD_GET_CDMA_SUBSCRIPTION_MODE = 95;
327     private static final int EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE = 96;
328     private static final int CMD_GET_SYSTEM_SELECTION_CHANNELS = 97;
329     private static final int EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE = 98;
330     private static final int CMD_SET_DATA_THROTTLING = 99;
331     private static final int EVENT_SET_DATA_THROTTLING_DONE = 100;
332     private static final int CMD_SET_SIM_POWER = 101;
333     private static final int EVENT_SET_SIM_POWER_DONE = 102;
334     private static final int CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST = 103;
335     private static final int EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE = 104;
336     private static final int CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST = 105;
337     private static final int EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE = 106;
338     private static final int CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON = 107;
339     private static final int EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE = 108;
340     private static final int CMD_PREPARE_UNATTENDED_REBOOT = 109;
341     private static final int CMD_GET_SLICING_CONFIG = 110;
342     private static final int EVENT_GET_SLICING_CONFIG_DONE = 111;
343     private static final int CMD_ERASE_DATA_SHARED_PREFERENCES = 112;
344 
345     // Parameters of select command.
346     private static final int SELECT_COMMAND = 0xA4;
347     private static final int SELECT_P1 = 0x04;
348     private static final int SELECT_P2 = 0;
349     private static final int SELECT_P3 = 0x10;
350 
351     /** The singleton instance. */
352     private static PhoneInterfaceManager sInstance;
353     private static List<String> sThermalMitigationAllowlistedPackages = new ArrayList<>();
354 
355     private PhoneGlobals mApp;
356     private CallManager mCM;
357     private ImsResolver mImsResolver;
358     private UserManager mUserManager;
359     private AppOpsManager mAppOps;
360     private PackageManager mPm;
361     private MainThreadHandler mMainThreadHandler;
362     private SubscriptionController mSubscriptionController;
363     private SharedPreferences mTelephonySharedPreferences;
364     private PhoneConfigurationManager mPhoneConfigurationManager;
365     private final RadioInterfaceCapabilityController mRadioInterfaceCapabilities;
366 
367     /** User Activity */
368     private AtomicBoolean mNotifyUserActivity;
369     private static final int USER_ACTIVITY_NOTIFICATION_DELAY = 200;
370 
371     private Set<Integer> mCarrierPrivilegeTestOverrideSubIds = new ArraySet<>();
372 
373     private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
374     private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
375     private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
376     private static final String PREF_PROVISION_IMS_MMTEL_PREFIX = "provision_ims_mmtel_";
377 
378     // String to store multi SIM allowed
379     private static final String PREF_MULTI_SIM_RESTRICTED = "multisim_restricted";
380 
381     // The AID of ISD-R.
382     private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
383 
384     private NetworkScanRequestTracker mNetworkScanRequestTracker;
385 
386     private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
387     private static final int MANUFACTURER_CODE_LENGTH = 8;
388 
389     private static final int SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS = -1;
390     private static final int MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE = -2;
391 
392     /**
393      * Experiment flag to enable erase modem config on reset network, default value is false
394      */
395     public static final String RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED =
396             "reset_network_erase_modem_config_enabled";
397 
398     private static final int SET_NETWORK_SELECTION_MODE_AUTOMATIC_TIMEOUT_MS = 2000; // 2 seconds
399 
400     /**
401      * A request object to use for transmitting data to an ICC.
402      */
403     private static final class IccAPDUArgument {
404         public int channel, cla, command, p1, p2, p3;
405         public String data;
406 
IccAPDUArgument(int channel, int cla, int command, int p1, int p2, int p3, String data)407         public IccAPDUArgument(int channel, int cla, int command,
408                 int p1, int p2, int p3, String data) {
409             this.channel = channel;
410             this.cla = cla;
411             this.command = command;
412             this.p1 = p1;
413             this.p2 = p2;
414             this.p3 = p3;
415             this.data = data;
416         }
417     }
418 
419     /**
420      * A request object to use for transmitting data to an ICC.
421      */
422     private static final class ManualNetworkSelectionArgument {
423         public OperatorInfo operatorInfo;
424         public boolean persistSelection;
425 
ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection)426         public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
427             this.operatorInfo = operatorInfo;
428             this.persistSelection = persistSelection;
429         }
430     }
431 
432     /**
433      * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
434      * request after sending. The main thread will notify the request when it is complete.
435      */
436     private static final class MainThreadRequest {
437         /** The argument to use for the request */
438         public Object argument;
439         /** The result of the request that is run on the main thread */
440         public Object result;
441         // The subscriber id that this request applies to. Defaults to
442         // SubscriptionManager.INVALID_SUBSCRIPTION_ID
443         public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
444 
445         // In cases where subId is unavailable, the caller needs to specify the phone.
446         public Phone phone;
447 
448         public WorkSource workSource;
449 
MainThreadRequest(Object argument)450         public MainThreadRequest(Object argument) {
451             this.argument = argument;
452         }
453 
MainThreadRequest(Object argument, Phone phone, WorkSource workSource)454         MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
455             this.argument = argument;
456             if (phone != null) {
457                 this.phone = phone;
458             }
459             this.workSource = workSource;
460         }
461 
MainThreadRequest(Object argument, Integer subId, WorkSource workSource)462         MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
463             this.argument = argument;
464             if (subId != null) {
465                 this.subId = subId;
466             }
467             this.workSource = workSource;
468         }
469     }
470 
471     private static final class IncomingThirdPartyCallArgs {
472         public final ComponentName component;
473         public final String callId;
474         public final String callerDisplayName;
475 
IncomingThirdPartyCallArgs(ComponentName component, String callId, String callerDisplayName)476         public IncomingThirdPartyCallArgs(ComponentName component, String callId,
477                 String callerDisplayName) {
478             this.component = component;
479             this.callId = callId;
480             this.callerDisplayName = callerDisplayName;
481         }
482     }
483 
484     /**
485      * A handler that processes messages on the main thread in the phone process. Since many
486      * of the Phone calls are not thread safe this is needed to shuttle the requests from the
487      * inbound binder threads to the main thread in the phone process.  The Binder thread
488      * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
489      * on, which will be notified when the operation completes and will contain the result of the
490      * request.
491      *
492      * <p>If a MainThreadRequest object is provided in the msg.obj field,
493      * note that request.result must be set to something non-null for the calling thread to
494      * unblock.
495      */
496     private final class MainThreadHandler extends Handler {
497         @Override
handleMessage(Message msg)498         public void handleMessage(Message msg) {
499             MainThreadRequest request;
500             Message onCompleted;
501             AsyncResult ar;
502             UiccCard uiccCard;
503             IccAPDUArgument iccArgument;
504             final Phone defaultPhone = getDefaultPhone();
505 
506             switch (msg.what) {
507                 case CMD_HANDLE_USSD_REQUEST: {
508                     request = (MainThreadRequest) msg.obj;
509                     final Phone phone = getPhoneFromRequest(request);
510                     Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
511                     String ussdRequest =  ussdObject.first;
512                     ResultReceiver wrappedCallback = ussdObject.second;
513 
514                     if (!isUssdApiAllowed(request.subId)) {
515                         // Carrier does not support use of this API, return failure.
516                         Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
517                         UssdResponse response = new UssdResponse(ussdRequest, null);
518                         Bundle returnData = new Bundle();
519                         returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
520                         wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
521 
522                         request.result = true;
523                         notifyRequester(request);
524                         return;
525                     }
526 
527                     try {
528                         request.result = phone != null
529                                 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
530                     } catch (CallStateException cse) {
531                         request.result = false;
532                     }
533                     // Wake up the requesting thread
534                     notifyRequester(request);
535                     break;
536                 }
537 
538                 case CMD_HANDLE_PIN_MMI: {
539                     request = (MainThreadRequest) msg.obj;
540                     final Phone phone = getPhoneFromRequest(request);
541                     request.result = phone != null ?
542                             getPhoneFromRequest(request).handlePinMmi((String) request.argument)
543                             : false;
544                     // Wake up the requesting thread
545                     notifyRequester(request);
546                     break;
547                 }
548 
549                 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
550                     request = (MainThreadRequest) msg.obj;
551                     iccArgument = (IccAPDUArgument) request.argument;
552                     uiccCard = getUiccCardFromRequest(request);
553                     if (uiccCard == null) {
554                         loge("iccTransmitApduLogicalChannel: No UICC");
555                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
556                         notifyRequester(request);
557                     } else {
558                         onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
559                             request);
560                         uiccCard.iccTransmitApduLogicalChannel(
561                             iccArgument.channel, iccArgument.cla, iccArgument.command,
562                             iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
563                             onCompleted);
564                     }
565                     break;
566 
567                 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
568                     ar = (AsyncResult) msg.obj;
569                     request = (MainThreadRequest) ar.userObj;
570                     if (ar.exception == null && ar.result != null) {
571                         request.result = ar.result;
572                     } else {
573                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
574                         if (ar.result == null) {
575                             loge("iccTransmitApduLogicalChannel: Empty response");
576                         } else if (ar.exception instanceof CommandException) {
577                             loge("iccTransmitApduLogicalChannel: CommandException: " +
578                                     ar.exception);
579                         } else {
580                             loge("iccTransmitApduLogicalChannel: Unknown exception");
581                         }
582                     }
583                     notifyRequester(request);
584                     break;
585 
586                 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
587                     request = (MainThreadRequest) msg.obj;
588                     iccArgument = (IccAPDUArgument) request.argument;
589                     uiccCard = getUiccCardFromRequest(request);
590                     if (uiccCard == null) {
591                         loge("iccTransmitApduBasicChannel: No UICC");
592                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
593                         notifyRequester(request);
594                     } else {
595                         onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
596                             request);
597                         uiccCard.iccTransmitApduBasicChannel(
598                             iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
599                             iccArgument.p3, iccArgument.data, onCompleted);
600                     }
601                     break;
602 
603                 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
604                     ar = (AsyncResult) msg.obj;
605                     request = (MainThreadRequest) ar.userObj;
606                     if (ar.exception == null && ar.result != null) {
607                         request.result = ar.result;
608                     } else {
609                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
610                         if (ar.result == null) {
611                             loge("iccTransmitApduBasicChannel: Empty response");
612                         } else if (ar.exception instanceof CommandException) {
613                             loge("iccTransmitApduBasicChannel: CommandException: " +
614                                     ar.exception);
615                         } else {
616                             loge("iccTransmitApduBasicChannel: Unknown exception");
617                         }
618                     }
619                     notifyRequester(request);
620                     break;
621 
622                 case CMD_EXCHANGE_SIM_IO:
623                     request = (MainThreadRequest) msg.obj;
624                     iccArgument = (IccAPDUArgument) request.argument;
625                     uiccCard = getUiccCardFromRequest(request);
626                     if (uiccCard == null) {
627                         loge("iccExchangeSimIO: No UICC");
628                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
629                         notifyRequester(request);
630                     } else {
631                         onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
632                                 request);
633                         uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
634                                 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
635                                 iccArgument.data, onCompleted);
636                     }
637                     break;
638 
639                 case EVENT_EXCHANGE_SIM_IO_DONE:
640                     ar = (AsyncResult) msg.obj;
641                     request = (MainThreadRequest) ar.userObj;
642                     if (ar.exception == null && ar.result != null) {
643                         request.result = ar.result;
644                     } else {
645                         request.result = new IccIoResult(0x6f, 0, (byte[])null);
646                     }
647                     notifyRequester(request);
648                     break;
649 
650                 case CMD_SEND_ENVELOPE:
651                     request = (MainThreadRequest) msg.obj;
652                     uiccCard = getUiccCardFromRequest(request);
653                     if (uiccCard == null) {
654                         loge("sendEnvelopeWithStatus: No UICC");
655                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
656                         notifyRequester(request);
657                     } else {
658                         onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
659                         uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
660                     }
661                     break;
662 
663                 case EVENT_SEND_ENVELOPE_DONE:
664                     ar = (AsyncResult) msg.obj;
665                     request = (MainThreadRequest) ar.userObj;
666                     if (ar.exception == null && ar.result != null) {
667                         request.result = ar.result;
668                     } else {
669                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
670                         if (ar.result == null) {
671                             loge("sendEnvelopeWithStatus: Empty response");
672                         } else if (ar.exception instanceof CommandException) {
673                             loge("sendEnvelopeWithStatus: CommandException: " +
674                                     ar.exception);
675                         } else {
676                             loge("sendEnvelopeWithStatus: exception:" + ar.exception);
677                         }
678                     }
679                     notifyRequester(request);
680                     break;
681 
682                 case CMD_OPEN_CHANNEL:
683                     request = (MainThreadRequest) msg.obj;
684                     uiccCard = getUiccCardFromRequest(request);
685                     Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
686                     if (uiccCard == null) {
687                         loge("iccOpenLogicalChannel: No UICC");
688                         request.result = new IccOpenLogicalChannelResponse(-1,
689                             IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
690                         notifyRequester(request);
691                     } else {
692                         onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
693                         uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
694                                 openChannelArgs.second, onCompleted);
695                     }
696                     break;
697 
698                 case EVENT_OPEN_CHANNEL_DONE:
699                     ar = (AsyncResult) msg.obj;
700                     request = (MainThreadRequest) ar.userObj;
701                     IccOpenLogicalChannelResponse openChannelResp;
702                     if (ar.exception == null && ar.result != null) {
703                         int[] result = (int[]) ar.result;
704                         int channelId = result[0];
705                         byte[] selectResponse = null;
706                         if (result.length > 1) {
707                             selectResponse = new byte[result.length - 1];
708                             for (int i = 1; i < result.length; ++i) {
709                                 selectResponse[i - 1] = (byte) result[i];
710                             }
711                         }
712                         openChannelResp = new IccOpenLogicalChannelResponse(channelId,
713                             IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
714                     } else {
715                         if (ar.result == null) {
716                             loge("iccOpenLogicalChannel: Empty response");
717                         }
718                         if (ar.exception != null) {
719                             loge("iccOpenLogicalChannel: Exception: " + ar.exception);
720                         }
721 
722                         int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
723                         if (ar.exception instanceof CommandException) {
724                             CommandException.Error error =
725                                 ((CommandException) (ar.exception)).getCommandError();
726                             if (error == CommandException.Error.MISSING_RESOURCE) {
727                                 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
728                             } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
729                                 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
730                             }
731                         }
732                         openChannelResp = new IccOpenLogicalChannelResponse(
733                             IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
734                     }
735                     request.result = openChannelResp;
736                     notifyRequester(request);
737                     break;
738 
739                 case CMD_CLOSE_CHANNEL:
740                     request = (MainThreadRequest) msg.obj;
741                     uiccCard = getUiccCardFromRequest(request);
742                     if (uiccCard == null) {
743                         loge("iccCloseLogicalChannel: No UICC");
744                         request.result = false;
745                         notifyRequester(request);
746                     } else {
747                         onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
748                         uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
749                     }
750                     break;
751 
752                 case EVENT_CLOSE_CHANNEL_DONE:
753                     handleNullReturnEvent(msg, "iccCloseLogicalChannel");
754                     break;
755 
756                 case CMD_NV_READ_ITEM:
757                     request = (MainThreadRequest) msg.obj;
758                     onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
759                     defaultPhone.nvReadItem((Integer) request.argument, onCompleted,
760                             request.workSource);
761                     break;
762 
763                 case EVENT_NV_READ_ITEM_DONE:
764                     ar = (AsyncResult) msg.obj;
765                     request = (MainThreadRequest) ar.userObj;
766                     if (ar.exception == null && ar.result != null) {
767                         request.result = ar.result;     // String
768                     } else {
769                         request.result = "";
770                         if (ar.result == null) {
771                             loge("nvReadItem: Empty response");
772                         } else if (ar.exception instanceof CommandException) {
773                             loge("nvReadItem: CommandException: " +
774                                     ar.exception);
775                         } else {
776                             loge("nvReadItem: Unknown exception");
777                         }
778                     }
779                     notifyRequester(request);
780                     break;
781 
782                 case CMD_NV_WRITE_ITEM:
783                     request = (MainThreadRequest) msg.obj;
784                     onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
785                     Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
786                     defaultPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
787                             request.workSource);
788                     break;
789 
790                 case EVENT_NV_WRITE_ITEM_DONE:
791                     handleNullReturnEvent(msg, "nvWriteItem");
792                     break;
793 
794                 case CMD_NV_WRITE_CDMA_PRL:
795                     request = (MainThreadRequest) msg.obj;
796                     onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
797                     defaultPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
798                     break;
799 
800                 case EVENT_NV_WRITE_CDMA_PRL_DONE:
801                     handleNullReturnEvent(msg, "nvWriteCdmaPrl");
802                     break;
803 
804                 case CMD_RESET_MODEM_CONFIG:
805                     request = (MainThreadRequest) msg.obj;
806                     onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
807                     defaultPhone.resetModemConfig(onCompleted);
808                     break;
809 
810                 case EVENT_RESET_MODEM_CONFIG_DONE:
811                     handleNullReturnEvent(msg, "resetModemConfig");
812                     break;
813 
814                 case CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED: {
815                     request = (MainThreadRequest) msg.obj;
816                     onCompleted = obtainMessage(EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE,
817                             request);
818                     Phone phone = getPhoneFromRequest(request);
819                     if (phone != null) {
820                         phone.isNrDualConnectivityEnabled(onCompleted, request.workSource);
821                     } else {
822                         loge("isNRDualConnectivityEnabled: No phone object");
823                         request.result = false;
824                         notifyRequester(request);
825                     }
826                     break;
827                 }
828 
829                 case EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE:
830                     ar = (AsyncResult) msg.obj;
831                     request = (MainThreadRequest) ar.userObj;
832                     if (ar.exception == null && ar.result != null) {
833                         request.result = ar.result;
834                     } else {
835                         // request.result must be set to something non-null
836                         // for the calling thread to unblock
837                         if (request.result != null) {
838                             request.result = ar.result;
839                         } else {
840                             request.result = false;
841                         }
842                         if (ar.result == null) {
843                             loge("isNRDualConnectivityEnabled: Empty response");
844                         } else if (ar.exception instanceof CommandException) {
845                             loge("isNRDualConnectivityEnabled: CommandException: "
846                                     + ar.exception);
847                         } else {
848                             loge("isNRDualConnectivityEnabled: Unknown exception");
849                         }
850                     }
851                     notifyRequester(request);
852                     break;
853 
854                 case CMD_ENABLE_NR_DUAL_CONNECTIVITY: {
855                     request = (MainThreadRequest) msg.obj;
856                     onCompleted = obtainMessage(EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE, request);
857                     Phone phone = getPhoneFromRequest(request);
858                     if (phone != null) {
859                         phone.setNrDualConnectivityState((int) request.argument, onCompleted,
860                                 request.workSource);
861                     } else {
862                         loge("enableNrDualConnectivity: No phone object");
863                         request.result =
864                                 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
865                         notifyRequester(request);
866                     }
867                     break;
868                 }
869 
870                 case EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE: {
871                     ar = (AsyncResult) msg.obj;
872                     request = (MainThreadRequest) ar.userObj;
873                     if (ar.exception == null) {
874                         request.result =
875                                 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS;
876                     } else {
877                         request.result =
878                                 TelephonyManager
879                                         .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR;
880                         if (ar.exception instanceof CommandException) {
881                             CommandException.Error error =
882                                     ((CommandException) (ar.exception)).getCommandError();
883                             if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
884                                 request.result =
885                                         TelephonyManager
886                                                 .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
887                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
888                                 request.result =
889                                         TelephonyManager
890                                                 .ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED;
891                             }
892                             loge("enableNrDualConnectivity" + ": CommandException: "
893                                     + ar.exception);
894                         } else {
895                             loge("enableNrDualConnectivity" + ": Unknown exception");
896                         }
897                     }
898                     notifyRequester(request);
899                     break;
900                 }
901 
902                 case CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK:
903                     request = (MainThreadRequest) msg.obj;
904                     onCompleted = obtainMessage(EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE,
905                             request);
906                     getPhoneFromRequest(request).getAllowedNetworkTypesBitmask(onCompleted);
907                     break;
908 
909                 case EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE:
910                     ar = (AsyncResult) msg.obj;
911                     request = (MainThreadRequest) ar.userObj;
912                     if (ar.exception == null && ar.result != null) {
913                         request.result = ar.result;     // Integer
914                     } else {
915                         // request.result must be set to something non-null
916                         // for the calling thread to unblock
917                         request.result = new int[]{-1};
918                         if (ar.result == null) {
919                             loge("getAllowedNetworkTypesBitmask: Empty response");
920                         } else if (ar.exception instanceof CommandException) {
921                             loge("getAllowedNetworkTypesBitmask: CommandException: "
922                                     + ar.exception);
923                         } else {
924                             loge("getAllowedNetworkTypesBitmask: Unknown exception");
925                         }
926                     }
927                     notifyRequester(request);
928                     break;
929 
930                 case CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON:
931                     request = (MainThreadRequest) msg.obj;
932                     onCompleted = obtainMessage(EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE,
933                             request);
934                     Pair<Integer, Long> reasonWithNetworkTypes =
935                             (Pair<Integer, Long>) request.argument;
936                     getPhoneFromRequest(request).setAllowedNetworkTypes(
937                             reasonWithNetworkTypes.first,
938                             reasonWithNetworkTypes.second,
939                             onCompleted);
940                     break;
941 
942                 case EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE:
943                     handleNullReturnEvent(msg, "setAllowedNetworkTypesForReason");
944                     break;
945 
946                 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
947                     request = (MainThreadRequest)msg.obj;
948                     onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
949                     defaultPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
950                     break;
951 
952                 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
953                     ar = (AsyncResult)msg.obj;
954                     request = (MainThreadRequest)ar.userObj;
955                     request.result = ar;
956                     notifyRequester(request);
957                     break;
958 
959                 case CMD_SET_VOICEMAIL_NUMBER:
960                     request = (MainThreadRequest) msg.obj;
961                     onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
962                     Pair<String, String> tagNum = (Pair<String, String>) request.argument;
963                     getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
964                             onCompleted);
965                     break;
966 
967                 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
968                     handleNullReturnEvent(msg, "setVoicemailNumber");
969                     break;
970 
971                 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
972                     request = (MainThreadRequest) msg.obj;
973                     onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
974                             request);
975                     getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
976                     break;
977 
978                 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
979                     handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
980                     break;
981 
982                 case CMD_PERFORM_NETWORK_SCAN:
983                     request = (MainThreadRequest) msg.obj;
984                     onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
985                     getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
986                     break;
987 
988                 case CMD_GET_CALL_FORWARDING: {
989                     request = (MainThreadRequest) msg.obj;
990                     onCompleted = obtainMessage(EVENT_GET_CALL_FORWARDING_DONE, request);
991                     Pair<Integer, TelephonyManager.CallForwardingInfoCallback> args =
992                             (Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
993                                     request.argument;
994                     int callForwardingReason = args.first;
995                     request.phone.getCallForwardingOption(callForwardingReason, onCompleted);
996                     break;
997                 }
998                 case EVENT_GET_CALL_FORWARDING_DONE: {
999                     ar = (AsyncResult) msg.obj;
1000                     request = (MainThreadRequest) ar.userObj;
1001                     TelephonyManager.CallForwardingInfoCallback callback =
1002                             ((Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
1003                                     request.argument).second;
1004                     if (ar.exception == null && ar.result != null) {
1005                         CallForwardingInfo callForwardingInfo = null;
1006                         CallForwardInfo[] callForwardInfos = (CallForwardInfo[]) ar.result;
1007                         for (CallForwardInfo callForwardInfo : callForwardInfos) {
1008                             // Service Class is a bit mask per 3gpp 27.007. Search for
1009                             // any service for voice call.
1010                             if ((callForwardInfo.serviceClass
1011                                     & CommandsInterface.SERVICE_CLASS_VOICE) > 0) {
1012                                 callForwardingInfo = new CallForwardingInfo(true,
1013                                         callForwardInfo.reason,
1014                                         callForwardInfo.number,
1015                                         callForwardInfo.timeSeconds);
1016                                 break;
1017                             }
1018                         }
1019                         // Didn't find a call forward info for voice call.
1020                         if (callForwardingInfo == null) {
1021                             callForwardingInfo = new CallForwardingInfo(false /* enabled */,
1022                                     0 /* reason */, null /* number */, 0 /* timeout */);
1023                         }
1024                         callback.onCallForwardingInfoAvailable(callForwardingInfo);
1025                     } else {
1026                         if (ar.result == null) {
1027                             loge("EVENT_GET_CALL_FORWARDING_DONE: Empty response");
1028                         }
1029                         if (ar.exception != null) {
1030                             loge("EVENT_GET_CALL_FORWARDING_DONE: Exception: " + ar.exception);
1031                         }
1032                         int errorCode = TelephonyManager
1033                                 .CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN;
1034                         if (ar.exception instanceof CommandException) {
1035                             CommandException.Error error =
1036                                     ((CommandException) (ar.exception)).getCommandError();
1037                             if (error == CommandException.Error.FDN_CHECK_FAILURE) {
1038                                 errorCode = TelephonyManager
1039                                         .CallForwardingInfoCallback.RESULT_ERROR_FDN_CHECK_FAILURE;
1040                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1041                                 errorCode = TelephonyManager
1042                                         .CallForwardingInfoCallback.RESULT_ERROR_NOT_SUPPORTED;
1043                             }
1044                         }
1045                         callback.onError(errorCode);
1046                     }
1047                     break;
1048                 }
1049 
1050                 case CMD_SET_CALL_FORWARDING: {
1051                     request = (MainThreadRequest) msg.obj;
1052                     onCompleted = obtainMessage(EVENT_SET_CALL_FORWARDING_DONE, request);
1053                     request = (MainThreadRequest) msg.obj;
1054                     CallForwardingInfo callForwardingInfoToSet =
1055                             ((Pair<CallForwardingInfo, Consumer<Integer>>)
1056                                     request.argument).first;
1057                     request.phone.setCallForwardingOption(
1058                             callForwardingInfoToSet.isEnabled()
1059                                     ? CommandsInterface.CF_ACTION_ENABLE
1060                                     : CommandsInterface.CF_ACTION_DISABLE,
1061                             callForwardingInfoToSet.getReason(),
1062                             callForwardingInfoToSet.getNumber(),
1063                             callForwardingInfoToSet.getTimeoutSeconds(), onCompleted);
1064                     break;
1065                 }
1066 
1067                 case EVENT_SET_CALL_FORWARDING_DONE: {
1068                     ar = (AsyncResult) msg.obj;
1069                     request = (MainThreadRequest) ar.userObj;
1070                     Consumer<Integer> callback =
1071                             ((Pair<CallForwardingInfo, Consumer<Integer>>)
1072                                     request.argument).second;
1073                     if (ar.exception != null) {
1074                         loge("setCallForwarding exception: " + ar.exception);
1075                         int errorCode = TelephonyManager.CallForwardingInfoCallback
1076                                 .RESULT_ERROR_UNKNOWN;
1077                         if (ar.exception instanceof CommandException) {
1078                             CommandException.Error error =
1079                                     ((CommandException) (ar.exception)).getCommandError();
1080                             if (error == CommandException.Error.FDN_CHECK_FAILURE) {
1081                                 errorCode = TelephonyManager.CallForwardingInfoCallback
1082                                         .RESULT_ERROR_FDN_CHECK_FAILURE;
1083                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1084                                 errorCode = TelephonyManager.CallForwardingInfoCallback
1085                                         .RESULT_ERROR_NOT_SUPPORTED;
1086                             }
1087                         }
1088                         callback.accept(errorCode);
1089                     } else {
1090                         callback.accept(TelephonyManager.CallForwardingInfoCallback.RESULT_SUCCESS);
1091                     }
1092                     break;
1093                 }
1094 
1095                 case CMD_GET_CALL_WAITING: {
1096                     request = (MainThreadRequest) msg.obj;
1097                     onCompleted = obtainMessage(EVENT_GET_CALL_WAITING_DONE, request);
1098                     getPhoneFromRequest(request).getCallWaiting(onCompleted);
1099                     break;
1100                 }
1101 
1102                 case EVENT_GET_CALL_WAITING_DONE: {
1103                     ar = (AsyncResult) msg.obj;
1104                     request = (MainThreadRequest) ar.userObj;
1105                     Consumer<Integer> callback = (Consumer<Integer>) request.argument;
1106                     int callForwardingStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
1107                     if (ar.exception == null && ar.result != null) {
1108                         int[] callForwardResults = (int[]) ar.result;
1109                         // Service Class is a bit mask per 3gpp 27.007.
1110                         // Search for any service for voice call.
1111                         if (callForwardResults.length > 1
1112                                 && ((callForwardResults[1]
1113                                 & CommandsInterface.SERVICE_CLASS_VOICE) > 0)) {
1114                             callForwardingStatus = callForwardResults[0] == 0
1115                                     ? TelephonyManager.CALL_WAITING_STATUS_DISABLED
1116                                     : TelephonyManager.CALL_WAITING_STATUS_ENABLED;
1117                         } else {
1118                             callForwardingStatus = TelephonyManager.CALL_WAITING_STATUS_DISABLED;
1119                         }
1120                     } else {
1121                         if (ar.result == null) {
1122                             loge("EVENT_GET_CALL_WAITING_DONE: Empty response");
1123                         }
1124                         if (ar.exception != null) {
1125                             loge("EVENT_GET_CALL_WAITING_DONE: Exception: " + ar.exception);
1126                         }
1127                         if (ar.exception instanceof CommandException) {
1128                             CommandException.Error error =
1129                                     ((CommandException) (ar.exception)).getCommandError();
1130                             if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1131                                 callForwardingStatus =
1132                                         TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED;
1133                             }
1134                         }
1135                     }
1136                     callback.accept(callForwardingStatus);
1137                     break;
1138                 }
1139 
1140                 case CMD_SET_CALL_WAITING: {
1141                     request = (MainThreadRequest) msg.obj;
1142                     onCompleted = obtainMessage(EVENT_SET_CALL_WAITING_DONE, request);
1143                     boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1144                     getPhoneFromRequest(request).setCallWaiting(enable, onCompleted);
1145                     break;
1146                 }
1147 
1148                 case EVENT_SET_CALL_WAITING_DONE: {
1149                     ar = (AsyncResult) msg.obj;
1150                     request = (MainThreadRequest) ar.userObj;
1151                     boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1152                     Consumer<Integer> callback =
1153                             ((Pair<Boolean, Consumer<Integer>>) request.argument).second;
1154                     if (ar.exception != null) {
1155                         loge("setCallWaiting exception: " + ar.exception);
1156                         if (ar.exception instanceof CommandException) {
1157                             CommandException.Error error =
1158                                     ((CommandException) (ar.exception)).getCommandError();
1159                             if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1160                                 callback.accept(TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED);
1161                             } else {
1162                                 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1163                             }
1164                         } else {
1165                             callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1166                         }
1167                     } else {
1168                         callback.accept(enable ? TelephonyManager.CALL_WAITING_STATUS_ENABLED
1169                                 : TelephonyManager.CALL_WAITING_STATUS_DISABLED);
1170                     }
1171                     break;
1172                 }
1173                 case EVENT_PERFORM_NETWORK_SCAN_DONE:
1174                     ar = (AsyncResult) msg.obj;
1175                     request = (MainThreadRequest) ar.userObj;
1176                     CellNetworkScanResult cellScanResult;
1177                     if (ar.exception == null && ar.result != null) {
1178                         cellScanResult = new CellNetworkScanResult(
1179                                 CellNetworkScanResult.STATUS_SUCCESS,
1180                                 (List<OperatorInfo>) ar.result);
1181                     } else {
1182                         if (ar.result == null) {
1183                             loge("getCellNetworkScanResults: Empty response");
1184                         }
1185                         if (ar.exception != null) {
1186                             loge("getCellNetworkScanResults: Exception: " + ar.exception);
1187                         }
1188                         int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
1189                         if (ar.exception instanceof CommandException) {
1190                             CommandException.Error error =
1191                                 ((CommandException) (ar.exception)).getCommandError();
1192                             if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1193                                 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
1194                             } else if (error == CommandException.Error.GENERIC_FAILURE) {
1195                                 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
1196                             }
1197                         }
1198                         cellScanResult = new CellNetworkScanResult(errorCode, null);
1199                     }
1200                     request.result = cellScanResult;
1201                     notifyRequester(request);
1202                     break;
1203 
1204                 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
1205                     request = (MainThreadRequest) msg.obj;
1206                     ManualNetworkSelectionArgument selArg =
1207                             (ManualNetworkSelectionArgument) request.argument;
1208                     onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
1209                             request);
1210                     getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
1211                             selArg.persistSelection, onCompleted);
1212                     break;
1213 
1214                 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
1215                     ar = (AsyncResult) msg.obj;
1216                     request = (MainThreadRequest) ar.userObj;
1217                     if (ar.exception == null) {
1218                         request.result = true;
1219                     } else {
1220                         request.result = false;
1221                         loge("setNetworkSelectionModeManual " + ar.exception);
1222                     }
1223                     notifyRequester(request);
1224                     mApp.onNetworkSelectionChanged(request.subId);
1225                     break;
1226 
1227                 case CMD_GET_MODEM_ACTIVITY_INFO:
1228                     request = (MainThreadRequest) msg.obj;
1229                     onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
1230                     if (defaultPhone != null) {
1231                         defaultPhone.getModemActivityInfo(onCompleted, request.workSource);
1232                     } else {
1233                         ResultReceiver result = (ResultReceiver) request.argument;
1234                         Bundle bundle = new Bundle();
1235                         bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY,
1236                                 new ModemActivityInfo(0, 0, 0,
1237                                         new int[ModemActivityInfo.getNumTxPowerLevels()], 0));
1238                         result.send(0, bundle);
1239                     }
1240                     break;
1241 
1242                 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE: {
1243                     ar = (AsyncResult) msg.obj;
1244                     request = (MainThreadRequest) ar.userObj;
1245                     ResultReceiver result = (ResultReceiver) request.argument;
1246 
1247                     ModemActivityInfo ret = null;
1248                     int error = 0;
1249                     if (ar.exception == null && ar.result != null) {
1250                         // Update the last modem activity info and the result of the request.
1251                         ModemActivityInfo info = (ModemActivityInfo) ar.result;
1252                         if (isModemActivityInfoValid(info)) {
1253                             int[] mergedTxTimeMs = new int[ModemActivityInfo.getNumTxPowerLevels()];
1254                             int[] txTimeMs = info.getTransmitTimeMillis();
1255                             int[] lastModemTxTimeMs = mLastModemActivityInfo
1256                                     .getTransmitTimeMillis();
1257                             for (int i = 0; i < mergedTxTimeMs.length; i++) {
1258                                 mergedTxTimeMs[i] = txTimeMs[i] + lastModemTxTimeMs[i];
1259                             }
1260                             mLastModemActivityInfo.setTimestamp(info.getTimestampMillis());
1261                             mLastModemActivityInfo.setSleepTimeMillis(info.getSleepTimeMillis()
1262                                     + mLastModemActivityInfo.getSleepTimeMillis());
1263                             mLastModemActivityInfo.setIdleTimeMillis(info.getIdleTimeMillis()
1264                                     + mLastModemActivityInfo.getIdleTimeMillis());
1265                             mLastModemActivityInfo.setTransmitTimeMillis(mergedTxTimeMs);
1266                             mLastModemActivityInfo.setReceiveTimeMillis(
1267                                     info.getReceiveTimeMillis()
1268                                             + mLastModemActivityInfo.getReceiveTimeMillis());
1269                         }
1270                         ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestampMillis(),
1271                                 mLastModemActivityInfo.getSleepTimeMillis(),
1272                                 mLastModemActivityInfo.getIdleTimeMillis(),
1273                                 mLastModemActivityInfo.getTransmitTimeMillis(),
1274                                 mLastModemActivityInfo.getReceiveTimeMillis());
1275                     } else {
1276                         if (ar.result == null) {
1277                             loge("queryModemActivityInfo: Empty response");
1278                             error = TelephonyManager.ModemActivityInfoException
1279                                     .ERROR_INVALID_INFO_RECEIVED;
1280                         } else if (ar.exception instanceof CommandException) {
1281                             loge("queryModemActivityInfo: CommandException: " +
1282                                     ar.exception);
1283                             error = TelephonyManager.ModemActivityInfoException
1284                                     .ERROR_MODEM_RESPONSE_ERROR;
1285                         } else {
1286                             loge("queryModemActivityInfo: Unknown exception");
1287                             error = TelephonyManager.ModemActivityInfoException
1288                                     .ERROR_UNKNOWN;
1289                         }
1290                     }
1291                     Bundle bundle = new Bundle();
1292                     if (ret != null) {
1293                         bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
1294                     } else {
1295                         bundle.putInt(TelephonyManager.EXCEPTION_RESULT_KEY, error);
1296                     }
1297                     result.send(0, bundle);
1298                     notifyRequester(request);
1299                     break;
1300                 }
1301 
1302                 case CMD_SET_ALLOWED_CARRIERS:
1303                     request = (MainThreadRequest) msg.obj;
1304                     CarrierRestrictionRules argument =
1305                             (CarrierRestrictionRules) request.argument;
1306                     onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
1307                     defaultPhone.setAllowedCarriers(argument, onCompleted, request.workSource);
1308                     break;
1309 
1310                 case EVENT_SET_ALLOWED_CARRIERS_DONE:
1311                     ar = (AsyncResult) msg.obj;
1312                     request = (MainThreadRequest) ar.userObj;
1313                     if (ar.exception == null && ar.result != null) {
1314                         request.result = ar.result;
1315                     } else {
1316                         request.result = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
1317                         if (ar.exception instanceof CommandException) {
1318                             loge("setAllowedCarriers: CommandException: " + ar.exception);
1319                             CommandException.Error error =
1320                                     ((CommandException) (ar.exception)).getCommandError();
1321                             if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1322                                 request.result =
1323                                         TelephonyManager.SET_CARRIER_RESTRICTION_NOT_SUPPORTED;
1324                             }
1325                         } else {
1326                             loge("setAllowedCarriers: Unknown exception");
1327                         }
1328                     }
1329                     notifyRequester(request);
1330                     break;
1331 
1332                 case CMD_GET_ALLOWED_CARRIERS:
1333                     request = (MainThreadRequest) msg.obj;
1334                     onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
1335                     defaultPhone.getAllowedCarriers(onCompleted, request.workSource);
1336                     break;
1337 
1338                 case EVENT_GET_ALLOWED_CARRIERS_DONE:
1339                     ar = (AsyncResult) msg.obj;
1340                     request = (MainThreadRequest) ar.userObj;
1341                     if (ar.exception == null && ar.result != null) {
1342                         request.result = ar.result;
1343                     } else {
1344                         request.result = new IllegalStateException(
1345                             "Failed to get carrier restrictions");
1346                         if (ar.result == null) {
1347                             loge("getAllowedCarriers: Empty response");
1348                         } else if (ar.exception instanceof CommandException) {
1349                             loge("getAllowedCarriers: CommandException: " +
1350                                     ar.exception);
1351                         } else {
1352                             loge("getAllowedCarriers: Unknown exception");
1353                         }
1354                     }
1355                     notifyRequester(request);
1356                     break;
1357 
1358                 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
1359                     ar = (AsyncResult) msg.obj;
1360                     request = (MainThreadRequest) ar.userObj;
1361                     if (ar.exception == null && ar.result != null) {
1362                         request.result = ar.result;
1363                     } else {
1364                         request.result = new IllegalArgumentException(
1365                                 "Failed to retrieve Forbidden Plmns");
1366                         if (ar.result == null) {
1367                             loge("getForbiddenPlmns: Empty response");
1368                         } else {
1369                             loge("getForbiddenPlmns: Unknown exception");
1370                         }
1371                     }
1372                     notifyRequester(request);
1373                     break;
1374 
1375                 case CMD_GET_FORBIDDEN_PLMNS:
1376                     request = (MainThreadRequest) msg.obj;
1377                     uiccCard = getUiccCardFromRequest(request);
1378                     if (uiccCard == null) {
1379                         loge("getForbiddenPlmns() UiccCard is null");
1380                         request.result = new IllegalArgumentException(
1381                                 "getForbiddenPlmns() UiccCard is null");
1382                         notifyRequester(request);
1383                         break;
1384                     }
1385                     Integer appType = (Integer) request.argument;
1386                     UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
1387                     if (uiccApp == null) {
1388                         loge("getForbiddenPlmns() no app with specified type -- "
1389                                 + appType);
1390                         request.result = new IllegalArgumentException("Failed to get UICC App");
1391                         notifyRequester(request);
1392                         break;
1393                     } else {
1394                         if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
1395                                 + " specified type -- " + appType);
1396                     }
1397                     onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
1398                     ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
1399                               onCompleted);
1400                     break;
1401 
1402                 case CMD_SWITCH_SLOTS:
1403                     request = (MainThreadRequest) msg.obj;
1404                     int[] physicalSlots = (int[]) request.argument;
1405                     onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
1406                     UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
1407                     break;
1408 
1409                 case EVENT_SWITCH_SLOTS_DONE:
1410                     ar = (AsyncResult) msg.obj;
1411                     request = (MainThreadRequest) ar.userObj;
1412                     request.result = (ar.exception == null);
1413                     notifyRequester(request);
1414                     break;
1415                 case CMD_GET_NETWORK_SELECTION_MODE:
1416                     request = (MainThreadRequest) msg.obj;
1417                     onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
1418                     getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
1419                     break;
1420 
1421                 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
1422                     ar = (AsyncResult) msg.obj;
1423                     request = (MainThreadRequest) ar.userObj;
1424                     if (ar.exception != null) {
1425                         request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
1426                     } else {
1427                         int mode = ((int[]) ar.result)[0];
1428                         if (mode == 0) {
1429                             request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
1430                         } else {
1431                             request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
1432                         }
1433                     }
1434                     notifyRequester(request);
1435                     break;
1436                 case CMD_GET_CDMA_ROAMING_MODE:
1437                     request = (MainThreadRequest) msg.obj;
1438                     onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
1439                     getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
1440                     break;
1441                 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
1442                     ar = (AsyncResult) msg.obj;
1443                     request = (MainThreadRequest) ar.userObj;
1444                     if (ar.exception != null) {
1445                         request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
1446                     } else {
1447                         request.result = ((int[]) ar.result)[0];
1448                     }
1449                     notifyRequester(request);
1450                     break;
1451                 case CMD_SET_CDMA_ROAMING_MODE:
1452                     request = (MainThreadRequest) msg.obj;
1453                     onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
1454                     int mode = (int) request.argument;
1455                     getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
1456                     break;
1457                 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
1458                     ar = (AsyncResult) msg.obj;
1459                     request = (MainThreadRequest) ar.userObj;
1460                     request.result = ar.exception == null;
1461                     notifyRequester(request);
1462                     break;
1463                 case CMD_GET_CDMA_SUBSCRIPTION_MODE:
1464                     request = (MainThreadRequest) msg.obj;
1465                     onCompleted = obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1466                     getPhoneFromRequest(request).queryCdmaSubscriptionMode(onCompleted);
1467                     break;
1468                 case EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE:
1469                     ar = (AsyncResult) msg.obj;
1470                     request = (MainThreadRequest) ar.userObj;
1471                     if (ar.exception != null) {
1472                         request.result = TelephonyManager.CDMA_SUBSCRIPTION_RUIM_SIM;
1473                     } else {
1474                         request.result = ((int[]) ar.result)[0];
1475                     }
1476                     notifyRequester(request);
1477                     break;
1478                 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
1479                     request = (MainThreadRequest) msg.obj;
1480                     onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1481                     int subscriptionMode = (int) request.argument;
1482                     getPhoneFromRequest(request).setCdmaSubscriptionMode(
1483                             subscriptionMode, onCompleted);
1484                     break;
1485                 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
1486                     ar = (AsyncResult) msg.obj;
1487                     request = (MainThreadRequest) ar.userObj;
1488                     request.result = ar.exception == null;
1489                     notifyRequester(request);
1490                     break;
1491                 case CMD_GET_ALL_CELL_INFO:
1492                     request = (MainThreadRequest) msg.obj;
1493                     onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
1494                     request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
1495                     break;
1496                 case EVENT_GET_ALL_CELL_INFO_DONE:
1497                     ar = (AsyncResult) msg.obj;
1498                     request = (MainThreadRequest) ar.userObj;
1499                     // If a timeout occurs, the response will be null
1500                     request.result = (ar.exception == null && ar.result != null)
1501                             ? ar.result : new ArrayList<CellInfo>();
1502                     synchronized (request) {
1503                         request.notifyAll();
1504                     }
1505                     break;
1506                 case CMD_REQUEST_CELL_INFO_UPDATE:
1507                     request = (MainThreadRequest) msg.obj;
1508                     request.phone.requestCellInfoUpdate(request.workSource,
1509                             obtainMessage(EVENT_REQUEST_CELL_INFO_UPDATE_DONE, request));
1510                     break;
1511                 case EVENT_REQUEST_CELL_INFO_UPDATE_DONE:
1512                     ar = (AsyncResult) msg.obj;
1513                     request = (MainThreadRequest) ar.userObj;
1514                     ICellInfoCallback cb = (ICellInfoCallback) request.argument;
1515                     try {
1516                         if (ar.exception != null) {
1517                             Log.e(LOG_TAG, "Exception retrieving CellInfo=" + ar.exception);
1518                             cb.onError(
1519                                     TelephonyManager.CellInfoCallback.ERROR_MODEM_ERROR,
1520                                     ar.exception.getClass().getName(),
1521                                     ar.exception.toString());
1522                         } else if (ar.result == null) {
1523                             Log.w(LOG_TAG, "Timeout Waiting for CellInfo!");
1524                             cb.onError(TelephonyManager.CellInfoCallback.ERROR_TIMEOUT, null, null);
1525                         } else {
1526                             // use the result as returned
1527                             cb.onCellInfo((List<CellInfo>) ar.result);
1528                         }
1529                     } catch (RemoteException re) {
1530                         Log.w(LOG_TAG, "Discarded CellInfo due to Callback RemoteException");
1531                     }
1532                     break;
1533                 case CMD_GET_CELL_LOCATION: {
1534                     request = (MainThreadRequest) msg.obj;
1535                     WorkSource ws = (WorkSource) request.argument;
1536                     Phone phone = getPhoneFromRequest(request);
1537                     phone.getCellIdentity(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
1538                     break;
1539                 }
1540                 case EVENT_GET_CELL_LOCATION_DONE: {
1541                     ar = (AsyncResult) msg.obj;
1542                     request = (MainThreadRequest) ar.userObj;
1543                     if (ar.exception == null) {
1544                         request.result = ar.result;
1545                     } else {
1546                         Phone phone = getPhoneFromRequest(request);
1547                         request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
1548                                 ? new CellIdentityCdma() : new CellIdentityGsm();
1549                     }
1550 
1551                     synchronized (request) {
1552                         request.notifyAll();
1553                     }
1554                     break;
1555                 }
1556                 case CMD_MODEM_REBOOT:
1557                     request = (MainThreadRequest) msg.obj;
1558                     onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
1559                     defaultPhone.rebootModem(onCompleted);
1560                     break;
1561                 case EVENT_CMD_MODEM_REBOOT_DONE:
1562                     handleNullReturnEvent(msg, "rebootModem");
1563                     break;
1564                 case CMD_REQUEST_ENABLE_MODEM:
1565                     request = (MainThreadRequest) msg.obj;
1566                     boolean enable = (boolean) request.argument;
1567                     onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
1568                     onCompleted.arg1 = enable ? 1 : 0;
1569                     PhoneConfigurationManager.getInstance()
1570                             .enablePhone(request.phone, enable, onCompleted);
1571                     break;
1572                 case EVENT_ENABLE_MODEM_DONE: {
1573                     ar = (AsyncResult) msg.obj;
1574                     request = (MainThreadRequest) ar.userObj;
1575                     request.result = (ar.exception == null);
1576                     int phoneId = request.phone.getPhoneId();
1577                     //update the cache as modem status has changed
1578                     if ((boolean) request.result) {
1579                         mPhoneConfigurationManager.addToPhoneStatusCache(phoneId, msg.arg1 == 1);
1580                         updateModemStateMetrics();
1581                     } else {
1582                         Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1583                                 + ar.exception);
1584                     }
1585                     notifyRequester(request);
1586                     break;
1587                 }
1588                 case CMD_GET_MODEM_STATUS:
1589                     request = (MainThreadRequest) msg.obj;
1590                     onCompleted = obtainMessage(EVENT_GET_MODEM_STATUS_DONE, request);
1591                     PhoneConfigurationManager.getInstance()
1592                             .getPhoneStatusFromModem(request.phone, onCompleted);
1593                     break;
1594                 case EVENT_GET_MODEM_STATUS_DONE:
1595                     ar = (AsyncResult) msg.obj;
1596                     request = (MainThreadRequest) ar.userObj;
1597                     int id = request.phone.getPhoneId();
1598                     if (ar.exception == null && ar.result != null) {
1599                         request.result = ar.result;
1600                         //update the cache as modem status has changed
1601                         mPhoneConfigurationManager.addToPhoneStatusCache(id,
1602                                 (boolean) request.result);
1603                     } else {
1604                         // Return true if modem status cannot be retrieved. For most cases,
1605                         // modem status is on. And for older version modems, GET_MODEM_STATUS
1606                         // and disable modem are not supported. Modem is always on.
1607                         // TODO: this should be fixed in R to support a third
1608                         // status UNKNOWN b/131631629
1609                         request.result = true;
1610                         Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1611                                 + ar.exception);
1612                     }
1613                     notifyRequester(request);
1614                     break;
1615                 case CMD_SET_SYSTEM_SELECTION_CHANNELS: {
1616                     request = (MainThreadRequest) msg.obj;
1617                     onCompleted = obtainMessage(EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1618                     Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1619                             (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1620                     request.phone.setSystemSelectionChannels(args.first, onCompleted);
1621                     break;
1622                 }
1623                 case EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE: {
1624                     ar = (AsyncResult) msg.obj;
1625                     request = (MainThreadRequest) ar.userObj;
1626                     Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1627                             (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1628                     args.second.accept(ar.exception == null);
1629                     notifyRequester(request);
1630                     break;
1631                 }
1632                 case CMD_GET_SYSTEM_SELECTION_CHANNELS: {
1633                     request = (MainThreadRequest) msg.obj;
1634                     onCompleted = obtainMessage(EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1635                     Phone phone = getPhoneFromRequest(request);
1636                     if (phone != null) {
1637                         phone.getSystemSelectionChannels(onCompleted);
1638                     } else {
1639                         loge("getSystemSelectionChannels: No phone object");
1640                         request.result = new ArrayList<RadioAccessSpecifier>();
1641                         notifyRequester(request);
1642                     }
1643                     break;
1644                 }
1645                 case EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE:
1646                     ar = (AsyncResult) msg.obj;
1647                     request = (MainThreadRequest) ar.userObj;
1648                     if (ar.exception == null && ar.result != null) {
1649                         request.result = ar.result;
1650                     } else {
1651                         request.result = new IllegalStateException(
1652                                 "Failed to retrieve system selecton channels");
1653                         if (ar.result == null) {
1654                             loge("getSystemSelectionChannels: Empty response");
1655                         } else {
1656                             loge("getSystemSelectionChannels: Unknown exception");
1657                         }
1658                     }
1659                     notifyRequester(request);
1660                     break;
1661                 case EVENT_SET_FORBIDDEN_PLMNS_DONE:
1662                     ar = (AsyncResult) msg.obj;
1663                     request = (MainThreadRequest) ar.userObj;
1664                     if (ar.exception == null && ar.result != null) {
1665                         request.result = ar.result;
1666                     } else {
1667                         request.result = -1;
1668                         loge("Failed to set Forbidden Plmns");
1669                         if (ar.result == null) {
1670                             loge("setForbidenPlmns: Empty response");
1671                         } else if (ar.exception != null) {
1672                             loge("setForbiddenPlmns: Exception: " + ar.exception);
1673                             request.result = -1;
1674                         } else {
1675                             loge("setForbiddenPlmns: Unknown exception");
1676                         }
1677                     }
1678                     notifyRequester(request);
1679                     break;
1680                 case CMD_SET_FORBIDDEN_PLMNS:
1681                     request = (MainThreadRequest) msg.obj;
1682                     uiccCard = getUiccCardFromRequest(request);
1683                     if (uiccCard == null) {
1684                         loge("setForbiddenPlmns: UiccCard is null");
1685                         request.result = -1;
1686                         notifyRequester(request);
1687                         break;
1688                     }
1689                     Pair<Integer, List<String>> setFplmnsArgs =
1690                             (Pair<Integer, List<String>>) request.argument;
1691                     appType = setFplmnsArgs.first;
1692                     List<String> fplmns = setFplmnsArgs.second;
1693                     uiccApp = uiccCard.getApplicationByType(appType);
1694                     if (uiccApp == null) {
1695                         loge("setForbiddenPlmns: no app with specified type -- " + appType);
1696                         request.result = -1;
1697                         loge("Failed to get UICC App");
1698                         notifyRequester(request);
1699                     } else {
1700                         onCompleted = obtainMessage(EVENT_SET_FORBIDDEN_PLMNS_DONE, request);
1701                         ((SIMRecords) uiccApp.getIccRecords())
1702                                 .setForbiddenPlmns(onCompleted, fplmns);
1703                     }
1704                     break;
1705                 case CMD_ERASE_MODEM_CONFIG:
1706                     request = (MainThreadRequest) msg.obj;
1707                     onCompleted = obtainMessage(EVENT_ERASE_MODEM_CONFIG_DONE, request);
1708                     defaultPhone.eraseModemConfig(onCompleted);
1709                     break;
1710                 case EVENT_ERASE_MODEM_CONFIG_DONE:
1711                     handleNullReturnEvent(msg, "eraseModemConfig");
1712                     break;
1713 
1714                 case CMD_ERASE_DATA_SHARED_PREFERENCES:
1715                     request = (MainThreadRequest) msg.obj;
1716                     request.result = defaultPhone.eraseDataInSharedPreferences();
1717                     notifyRequester(request);
1718                     break;
1719 
1720                 case CMD_CHANGE_ICC_LOCK_PASSWORD:
1721                     request = (MainThreadRequest) msg.obj;
1722                     onCompleted = obtainMessage(EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE, request);
1723                     Pair<String, String> changed = (Pair<String, String>) request.argument;
1724                     getPhoneFromRequest(request).getIccCard().changeIccLockPassword(
1725                             changed.first, changed.second, onCompleted);
1726                     break;
1727                 case EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE:
1728                     ar = (AsyncResult) msg.obj;
1729                     request = (MainThreadRequest) ar.userObj;
1730                     if (ar.exception == null) {
1731                         request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
1732                         // If the operation is successful, update the PIN storage
1733                         Pair<String, String> passwords = (Pair<String, String>) request.argument;
1734                         int phoneId = getPhoneFromRequest(request).getPhoneId();
1735                         UiccController.getInstance().getPinStorage()
1736                                 .storePin(passwords.second, phoneId);
1737                     } else {
1738                         request.result = msg.arg1;
1739                     }
1740                     notifyRequester(request);
1741                     break;
1742 
1743                 case CMD_SET_ICC_LOCK_ENABLED: {
1744                     request = (MainThreadRequest) msg.obj;
1745                     onCompleted = obtainMessage(EVENT_SET_ICC_LOCK_ENABLED_DONE, request);
1746                     Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
1747                     getPhoneFromRequest(request).getIccCard().setIccLockEnabled(
1748                             enabled.first, enabled.second, onCompleted);
1749                     break;
1750                 }
1751                 case EVENT_SET_ICC_LOCK_ENABLED_DONE:
1752                     ar = (AsyncResult) msg.obj;
1753                     request = (MainThreadRequest) ar.userObj;
1754                     if (ar.exception == null) {
1755                         request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
1756                         // If the operation is successful, update the PIN storage
1757                         Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
1758                         int phoneId = getPhoneFromRequest(request).getPhoneId();
1759                         if (enabled.first) {
1760                             UiccController.getInstance().getPinStorage()
1761                                     .storePin(enabled.second, phoneId);
1762                         } else {
1763                             UiccController.getInstance().getPinStorage().clearPin(phoneId);
1764                         }
1765                     } else {
1766                         request.result = msg.arg1;
1767                     }
1768 
1769 
1770                     notifyRequester(request);
1771                     break;
1772 
1773                 case MSG_NOTIFY_USER_ACTIVITY:
1774                     removeMessages(MSG_NOTIFY_USER_ACTIVITY);
1775                     Intent intent = new Intent(TelephonyIntents.ACTION_USER_ACTIVITY_NOTIFICATION);
1776                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1777                     getDefaultPhone().getContext().sendBroadcastAsUser(
1778                             intent, UserHandle.ALL, permission.USER_ACTIVITY);
1779                     break;
1780 
1781                 case CMD_SET_DATA_THROTTLING: {
1782                     request = (MainThreadRequest) msg.obj;
1783                     onCompleted = obtainMessage(EVENT_SET_DATA_THROTTLING_DONE, request);
1784                     DataThrottlingRequest dataThrottlingRequest =
1785                             (DataThrottlingRequest) request.argument;
1786                     Phone phone = getPhoneFromRequest(request);
1787                     if (phone != null) {
1788                         phone.setDataThrottling(onCompleted,
1789                                 request.workSource, dataThrottlingRequest.getDataThrottlingAction(),
1790                                 dataThrottlingRequest.getCompletionDurationMillis());
1791                     } else {
1792                         loge("setDataThrottling: No phone object");
1793                         request.result =
1794                                 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
1795                         notifyRequester(request);
1796                     }
1797 
1798                     break;
1799                 }
1800                 case EVENT_SET_DATA_THROTTLING_DONE:
1801                     ar = (AsyncResult) msg.obj;
1802                     request = (MainThreadRequest) ar.userObj;
1803 
1804                     if (ar.exception == null) {
1805                         request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
1806                     } else if (ar.exception instanceof CommandException) {
1807                         loge("setDataThrottling: CommandException: " + ar.exception);
1808                         CommandException.Error error =
1809                                 ((CommandException) (ar.exception)).getCommandError();
1810 
1811                         if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1812                             request.result = TelephonyManager
1813                                 .THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
1814                         } else if (error == CommandException.Error.INVALID_ARGUMENTS) {
1815                             request.result = SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS;
1816                         } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1817                             request.result = MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE;
1818                         } else {
1819                             request.result =
1820                                     TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
1821                         }
1822                     } else {
1823                         request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
1824                     }
1825                     Log.w(LOG_TAG, "DataThrottlingResult = " + request.result);
1826                     notifyRequester(request);
1827                     break;
1828 
1829                 case CMD_SET_SIM_POWER: {
1830                     request = (MainThreadRequest) msg.obj;
1831                     onCompleted = obtainMessage(EVENT_SET_SIM_POWER_DONE, request);
1832                     request = (MainThreadRequest) msg.obj;
1833                     int stateToSet =
1834                             ((Pair<Integer, IIntegerConsumer>)
1835                                     request.argument).first;
1836                     request.phone.setSimPowerState(stateToSet, onCompleted, request.workSource);
1837                     break;
1838                 }
1839                 case EVENT_SET_SIM_POWER_DONE: {
1840                     ar = (AsyncResult) msg.obj;
1841                     request = (MainThreadRequest) ar.userObj;
1842                     IIntegerConsumer callback =
1843                             ((Pair<Integer, IIntegerConsumer>) request.argument).second;
1844                     if (ar.exception != null) {
1845                         loge("setSimPower exception: " + ar.exception);
1846                         int errorCode = TelephonyManager.CallForwardingInfoCallback
1847                                 .RESULT_ERROR_UNKNOWN;
1848                         if (ar.exception instanceof CommandException) {
1849                             CommandException.Error error =
1850                                     ((CommandException) (ar.exception)).getCommandError();
1851                             if (error == CommandException.Error.SIM_ERR) {
1852                                 errorCode = TelephonyManager.SET_SIM_POWER_STATE_SIM_ERROR;
1853                             } else if (error == CommandException.Error.INVALID_ARGUMENTS) {
1854                                 errorCode = TelephonyManager.SET_SIM_POWER_STATE_ALREADY_IN_STATE;
1855                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1856                                 errorCode = TelephonyManager.SET_SIM_POWER_STATE_NOT_SUPPORTED;
1857                             } else {
1858                                 errorCode = TelephonyManager.SET_SIM_POWER_STATE_MODEM_ERROR;
1859                             }
1860                         }
1861                         try {
1862                             callback.accept(errorCode);
1863                         } catch (RemoteException e) {
1864                             // Ignore if the remote process is no longer available to call back.
1865                             Log.w(LOG_TAG, "setSimPower: callback not available.");
1866                         }
1867                     } else {
1868                         try {
1869                             callback.accept(TelephonyManager.SET_SIM_POWER_STATE_SUCCESS);
1870                         } catch (RemoteException e) {
1871                             // Ignore if the remote process is no longer available to call back.
1872                             Log.w(LOG_TAG, "setSimPower: callback not available.");
1873                         }
1874                     }
1875                     break;
1876                 }
1877                 case CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST: {
1878                     request = (MainThreadRequest) msg.obj;
1879 
1880                     final Phone phone = getPhoneFromRequest(request);
1881                     if (phone == null || phone.getServiceStateTracker() == null) {
1882                         request.result = new IllegalStateException("Phone or SST is null");
1883                         notifyRequester(request);
1884                         break;
1885                     }
1886 
1887                     Pair<Integer, SignalStrengthUpdateRequest> pair =
1888                             (Pair<Integer, SignalStrengthUpdateRequest>) request.argument;
1889                     onCompleted = obtainMessage(EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE,
1890                             request);
1891                     phone.getServiceStateTracker().setSignalStrengthUpdateRequest(
1892                                     request.subId, pair.first /*callingUid*/,
1893                                     pair.second /*request*/, onCompleted);
1894                     break;
1895                 }
1896                 case EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE: {
1897                     ar = (AsyncResult) msg.obj;
1898                     request = (MainThreadRequest) ar.userObj;
1899                     // request.result will be the exception of ar if present, true otherwise.
1900                     // Be cautious not to leave result null which will wait() forever
1901                     request.result = ar.exception != null ? ar.exception : true;
1902                     notifyRequester(request);
1903                     break;
1904                 }
1905                 case CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST: {
1906                     request = (MainThreadRequest) msg.obj;
1907 
1908                     Phone phone = getPhoneFromRequest(request);
1909                     if (phone == null || phone.getServiceStateTracker() == null) {
1910                         request.result = new IllegalStateException("Phone or SST is null");
1911                         notifyRequester(request);
1912                         break;
1913                     }
1914 
1915                     Pair<Integer, SignalStrengthUpdateRequest> pair =
1916                             (Pair<Integer, SignalStrengthUpdateRequest>) request.argument;
1917                     onCompleted = obtainMessage(EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE,
1918                             request);
1919                     phone.getServiceStateTracker().clearSignalStrengthUpdateRequest(
1920                                     request.subId, pair.first /*callingUid*/,
1921                                     pair.second /*request*/, onCompleted);
1922                     break;
1923                 }
1924                 case EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE: {
1925                     ar = (AsyncResult) msg.obj;
1926                     request = (MainThreadRequest) ar.userObj;
1927                     request.result = ar.exception != null ? ar.exception : true;
1928                     notifyRequester(request);
1929                     break;
1930                 }
1931 
1932                 case CMD_GET_SLICING_CONFIG: {
1933                     request = (MainThreadRequest) msg.obj;
1934                     onCompleted = obtainMessage(EVENT_GET_SLICING_CONFIG_DONE, request);
1935                     request.phone.getSlicingConfig(onCompleted);
1936                     break;
1937                 }
1938                 case EVENT_GET_SLICING_CONFIG_DONE: {
1939                     ar = (AsyncResult) msg.obj;
1940                     request = (MainThreadRequest) ar.userObj;
1941                     ResultReceiver result = (ResultReceiver) request.argument;
1942 
1943                     NetworkSlicingConfig slicingConfig = null;
1944                     Bundle bundle = new Bundle();
1945                     int resultCode = 0;
1946                     if (ar.exception != null) {
1947                         Log.e(LOG_TAG, "Exception retrieving slicing configuration="
1948                                 + ar.exception);
1949                         resultCode = TelephonyManager.NetworkSlicingException.ERROR_MODEM_ERROR;
1950                     } else if (ar.result == null) {
1951                         Log.w(LOG_TAG, "Timeout Waiting for slicing configuration!");
1952                         resultCode = TelephonyManager.NetworkSlicingException.ERROR_TIMEOUT;
1953                     } else {
1954                         // use the result as returned
1955                         resultCode = TelephonyManager.NetworkSlicingException.SUCCESS;
1956                         slicingConfig = (NetworkSlicingConfig) ar.result;
1957                     }
1958 
1959                     if (slicingConfig == null) {
1960                         slicingConfig = new NetworkSlicingConfig();
1961                     }
1962                     bundle.putParcelable(TelephonyManager.KEY_SLICING_CONFIG_HANDLE, slicingConfig);
1963                     result.send(resultCode, bundle);
1964                     notifyRequester(request);
1965                     break;
1966                 }
1967 
1968                 case CMD_PREPARE_UNATTENDED_REBOOT:
1969                     request = (MainThreadRequest) msg.obj;
1970                     request.result =
1971                             UiccController.getInstance().getPinStorage().prepareUnattendedReboot();
1972                     notifyRequester(request);
1973                     break;
1974 
1975                 default:
1976                     Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
1977                     break;
1978             }
1979         }
1980 
notifyRequester(MainThreadRequest request)1981         private void notifyRequester(MainThreadRequest request) {
1982             synchronized (request) {
1983                 request.notifyAll();
1984             }
1985         }
1986 
handleNullReturnEvent(Message msg, String command)1987         private void handleNullReturnEvent(Message msg, String command) {
1988             AsyncResult ar = (AsyncResult) msg.obj;
1989             MainThreadRequest request = (MainThreadRequest) ar.userObj;
1990             if (ar.exception == null) {
1991                 request.result = true;
1992             } else {
1993                 request.result = false;
1994                 if (ar.exception instanceof CommandException) {
1995                     loge(command + ": CommandException: " + ar.exception);
1996                 } else {
1997                     loge(command + ": Unknown exception");
1998                 }
1999             }
2000             notifyRequester(request);
2001         }
2002     }
2003 
2004     /**
2005      * Posts the specified command to be executed on the main thread,
2006      * waits for the request to complete, and returns the result.
2007      * @see #sendRequestAsync
2008      */
sendRequest(int command, Object argument)2009     private Object sendRequest(int command, Object argument) {
2010         return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null,
2011                 null, -1 /*timeoutInMs*/);
2012     }
2013 
2014     /**
2015      * Posts the specified command to be executed on the main thread,
2016      * waits for the request to complete, and returns the result.
2017      * @see #sendRequestAsync
2018      */
sendRequest(int command, Object argument, WorkSource workSource)2019     private Object sendRequest(int command, Object argument, WorkSource workSource) {
2020         return sendRequest(command, argument,  SubscriptionManager.INVALID_SUBSCRIPTION_ID,
2021                 null, workSource, -1 /*timeoutInMs*/);
2022     }
2023 
2024     /**
2025      * Posts the specified command to be executed on the main thread,
2026      * waits for the request to complete, and returns the result.
2027      * @see #sendRequestAsync
2028      */
sendRequest(int command, Object argument, Integer subId)2029     private Object sendRequest(int command, Object argument, Integer subId) {
2030         return sendRequest(command, argument, subId, null, null, -1 /*timeoutInMs*/);
2031     }
2032 
2033     /**
2034      * Posts the specified command to be executed on the main thread,
2035      * waits for the request to complete for at most {@code timeoutInMs}, and returns the result
2036      * if not timeout or null otherwise.
2037      * @see #sendRequestAsync
2038      */
sendRequest(int command, Object argument, Integer subId, long timeoutInMs)2039     private @Nullable Object sendRequest(int command, Object argument, Integer subId,
2040             long timeoutInMs) {
2041         return sendRequest(command, argument, subId, null, null, timeoutInMs);
2042     }
2043 
2044     /**
2045      * Posts the specified command to be executed on the main thread,
2046      * waits for the request to complete, and returns the result.
2047      * @see #sendRequestAsync
2048      */
sendRequest(int command, Object argument, int subId, WorkSource workSource)2049     private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
2050         return sendRequest(command, argument, subId, null, workSource, -1 /*timeoutInMs*/);
2051     }
2052 
2053     /**
2054      * Posts the specified command to be executed on the main thread,
2055      * waits for the request to complete, and returns the result.
2056      * @see #sendRequestAsync
2057      */
sendRequest(int command, Object argument, Phone phone, WorkSource workSource)2058     private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
2059         return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone,
2060                 workSource, -1 /*timeoutInMs*/);
2061     }
2062 
2063     /**
2064      * Posts the specified command to be executed on the main thread. If {@code timeoutInMs} is
2065      * negative, waits for the request to complete, and returns the result. Otherwise, wait for
2066      * maximum of {@code timeoutInMs} milliseconds, interrupt and return null.
2067      * @see #sendRequestAsync
2068      */
sendRequest(int command, Object argument, Integer subId, Phone phone, WorkSource workSource, long timeoutInMs)2069     private @Nullable Object sendRequest(int command, Object argument, Integer subId, Phone phone,
2070             WorkSource workSource, long timeoutInMs) {
2071         if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
2072             throw new RuntimeException("This method will deadlock if called from the main thread.");
2073         }
2074 
2075         MainThreadRequest request = null;
2076         if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
2077             throw new IllegalArgumentException("subId and phone cannot both be specified!");
2078         } else if (phone != null) {
2079             request = new MainThreadRequest(argument, phone, workSource);
2080         } else {
2081             request = new MainThreadRequest(argument, subId, workSource);
2082         }
2083 
2084         Message msg = mMainThreadHandler.obtainMessage(command, request);
2085         msg.sendToTarget();
2086 
2087 
2088         synchronized (request) {
2089             if (timeoutInMs >= 0) {
2090                 // Wait for at least timeoutInMs before returning null request result
2091                 long now = SystemClock.elapsedRealtime();
2092                 long deadline = now + timeoutInMs;
2093                 while (request.result == null && now < deadline) {
2094                     try {
2095                         request.wait(deadline - now);
2096                     } catch (InterruptedException e) {
2097                         // Do nothing, go back and check if request is completed or timeout
2098                     } finally {
2099                         now = SystemClock.elapsedRealtime();
2100                     }
2101                 }
2102             } else {
2103                 // Wait for the request to complete
2104                 while (request.result == null) {
2105                     try {
2106                         request.wait();
2107                     } catch (InterruptedException e) {
2108                         // Do nothing, go back and wait until the request is complete
2109                     }
2110                 }
2111             }
2112         }
2113         if (request.result == null) {
2114             Log.wtf(LOG_TAG,
2115                     "sendRequest: Blocking command timed out. Something has gone terribly wrong.");
2116         }
2117         return request.result;
2118     }
2119 
2120     /**
2121      * Asynchronous ("fire and forget") version of sendRequest():
2122      * Posts the specified command to be executed on the main thread, and
2123      * returns immediately.
2124      * @see #sendRequest
2125      */
sendRequestAsync(int command)2126     private void sendRequestAsync(int command) {
2127         mMainThreadHandler.sendEmptyMessage(command);
2128     }
2129 
2130     /**
2131      * Same as {@link #sendRequestAsync(int)} except it takes an argument.
2132      * @see {@link #sendRequest(int)}
2133      */
sendRequestAsync(int command, Object argument)2134     private void sendRequestAsync(int command, Object argument) {
2135         sendRequestAsync(command, argument, null, null);
2136     }
2137 
2138     /**
2139      * Same as {@link #sendRequestAsync(int,Object)} except it takes a Phone and WorkSource.
2140      * @see {@link #sendRequest(int,Object)}
2141      */
sendRequestAsync( int command, Object argument, Phone phone, WorkSource workSource)2142     private void sendRequestAsync(
2143             int command, Object argument, Phone phone, WorkSource workSource) {
2144         MainThreadRequest request = new MainThreadRequest(argument, phone, workSource);
2145         Message msg = mMainThreadHandler.obtainMessage(command, request);
2146         msg.sendToTarget();
2147     }
2148 
2149     /**
2150      * Initialize the singleton PhoneInterfaceManager instance.
2151      * This is only done once, at startup, from PhoneApp.onCreate().
2152      */
init(PhoneGlobals app)2153     /* package */ static PhoneInterfaceManager init(PhoneGlobals app) {
2154         synchronized (PhoneInterfaceManager.class) {
2155             if (sInstance == null) {
2156                 sInstance = new PhoneInterfaceManager(app);
2157             } else {
2158                 Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
2159             }
2160             return sInstance;
2161         }
2162     }
2163 
2164     /** Private constructor; @see init() */
PhoneInterfaceManager(PhoneGlobals app)2165     private PhoneInterfaceManager(PhoneGlobals app) {
2166         mApp = app;
2167         mCM = PhoneGlobals.getInstance().mCM;
2168         mImsResolver = ImsResolver.getInstance();
2169         mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
2170         mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
2171         mPm = app.getSystemService(PackageManager.class);
2172         mMainThreadHandler = new MainThreadHandler();
2173         mSubscriptionController = SubscriptionController.getInstance();
2174         mTelephonySharedPreferences =
2175                 PreferenceManager.getDefaultSharedPreferences(mApp);
2176         mNetworkScanRequestTracker = new NetworkScanRequestTracker();
2177         mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
2178         mRadioInterfaceCapabilities = RadioInterfaceCapabilityController.getInstance();
2179         mNotifyUserActivity = new AtomicBoolean(false);
2180 
2181         publish();
2182     }
2183 
getDefaultPhone()2184     private Phone getDefaultPhone() {
2185         Phone thePhone = getPhone(getDefaultSubscription());
2186         return (thePhone != null) ? thePhone : PhoneFactory.getDefaultPhone();
2187     }
2188 
publish()2189     private void publish() {
2190         if (DBG) log("publish: " + this);
2191 
2192         TelephonyFrameworkInitializer
2193                 .getTelephonyServiceManager()
2194                 .getTelephonyServiceRegisterer()
2195                 .register(this);
2196     }
2197 
getPhoneFromRequest(MainThreadRequest request)2198     private Phone getPhoneFromRequest(MainThreadRequest request) {
2199         if (request.phone != null) {
2200             return request.phone;
2201         } else {
2202             return getPhoneFromSubId(request.subId);
2203         }
2204     }
2205 
getPhoneFromSubId(int subId)2206     private Phone getPhoneFromSubId(int subId) {
2207         return (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
2208                 ? getDefaultPhone() : getPhone(subId);
2209     }
2210 
getUiccCardFromRequest(MainThreadRequest request)2211     private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
2212         Phone phone = getPhoneFromRequest(request);
2213         return phone == null ? null :
2214                 UiccController.getInstance().getUiccCard(phone.getPhoneId());
2215     }
2216 
2217     // returns phone associated with the subId.
getPhone(int subId)2218     private Phone getPhone(int subId) {
2219         return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
2220     }
2221 
sendEraseModemConfig(@onNull Phone phone)2222     private void sendEraseModemConfig(@NonNull Phone phone) {
2223         Boolean success = (Boolean) sendRequest(CMD_ERASE_MODEM_CONFIG, null);
2224         if (DBG) log("eraseModemConfig:" + ' ' + (success ? "ok" : "fail"));
2225     }
2226 
sendEraseDataInSharedPreferences(@onNull Phone phone)2227     private void sendEraseDataInSharedPreferences(@NonNull Phone phone) {
2228         Boolean success = (Boolean) sendRequest(CMD_ERASE_DATA_SHARED_PREFERENCES, null);
2229         if (DBG) log("eraseDataInSharedPreferences:" + ' ' + (success ? "ok" : "fail"));
2230     }
2231 
isImsAvailableOnDevice()2232     private boolean isImsAvailableOnDevice() {
2233         PackageManager pm = getDefaultPhone().getContext().getPackageManager();
2234         if (pm == null) {
2235             // For some reason package manger is not available.. This will fail internally anyway,
2236             // so do not throw error and allow.
2237             return true;
2238         }
2239         return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS, 0);
2240     }
2241 
dial(String number)2242     public void dial(String number) {
2243         dialForSubscriber(getPreferredVoiceSubscription(), number);
2244     }
2245 
dialForSubscriber(int subId, String number)2246     public void dialForSubscriber(int subId, String number) {
2247         if (DBG) log("dial: " + number);
2248         // No permission check needed here: This is just a wrapper around the
2249         // ACTION_DIAL intent, which is available to any app since it puts up
2250         // the UI before it does anything.
2251 
2252         final long identity = Binder.clearCallingIdentity();
2253         try {
2254             String url = createTelUrl(number);
2255             if (url == null) {
2256                 return;
2257             }
2258 
2259             // PENDING: should we just silently fail if phone is offhook or ringing?
2260             PhoneConstants.State state = mCM.getState(subId);
2261             if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
2262                 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
2263                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2264                 mApp.startActivity(intent);
2265             }
2266         } finally {
2267             Binder.restoreCallingIdentity(identity);
2268         }
2269     }
2270 
call(String callingPackage, String number)2271     public void call(String callingPackage, String number) {
2272         callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
2273     }
2274 
callForSubscriber(int subId, String callingPackage, String number)2275     public void callForSubscriber(int subId, String callingPackage, String number) {
2276         if (DBG) log("call: " + number);
2277 
2278         // This is just a wrapper around the ACTION_CALL intent, but we still
2279         // need to do a permission check since we're calling startActivity()
2280         // from the context of the phone app.
2281         enforceCallPermission();
2282 
2283         if (mAppOps.noteOp(AppOpsManager.OPSTR_CALL_PHONE, Binder.getCallingUid(), callingPackage)
2284                 != AppOpsManager.MODE_ALLOWED) {
2285             return;
2286         }
2287 
2288         final long identity = Binder.clearCallingIdentity();
2289         try {
2290             String url = createTelUrl(number);
2291             if (url == null) {
2292                 return;
2293             }
2294 
2295             boolean isValid = false;
2296             final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
2297             if (slist != null) {
2298                 for (SubscriptionInfo subInfoRecord : slist) {
2299                     if (subInfoRecord.getSubscriptionId() == subId) {
2300                         isValid = true;
2301                         break;
2302                     }
2303                 }
2304             }
2305             if (!isValid) {
2306                 return;
2307             }
2308 
2309             Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
2310             intent.putExtra(SUBSCRIPTION_KEY, subId);
2311             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2312             mApp.startActivity(intent);
2313         } finally {
2314             Binder.restoreCallingIdentity(identity);
2315         }
2316     }
2317 
supplyPinForSubscriber(int subId, String pin)2318     public boolean supplyPinForSubscriber(int subId, String pin) {
2319         int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
2320         return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
2321     }
2322 
supplyPukForSubscriber(int subId, String puk, String pin)2323     public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
2324         int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
2325         return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
2326     }
2327 
supplyPinReportResultForSubscriber(int subId, String pin)2328     public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
2329         enforceModifyPermission();
2330 
2331         final long identity = Binder.clearCallingIdentity();
2332         try {
2333             Phone phone = getPhone(subId);
2334             final UnlockSim checkSimPin = new UnlockSim(phone.getPhoneId(), phone.getIccCard());
2335             checkSimPin.start();
2336             return checkSimPin.unlockSim(null, pin);
2337         } finally {
2338             Binder.restoreCallingIdentity(identity);
2339         }
2340     }
2341 
supplyPukReportResultForSubscriber(int subId, String puk, String pin)2342     public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
2343         enforceModifyPermission();
2344 
2345         final long identity = Binder.clearCallingIdentity();
2346         try {
2347             Phone phone = getPhone(subId);
2348             final UnlockSim checkSimPuk = new UnlockSim(phone.getPhoneId(), phone.getIccCard());
2349             checkSimPuk.start();
2350             return checkSimPuk.unlockSim(puk, pin);
2351         } finally {
2352             Binder.restoreCallingIdentity(identity);
2353         }
2354     }
2355 
2356     /**
2357      * Helper thread to turn async call to SimCard#supplyPin into
2358      * a synchronous one.
2359      */
2360     private static class UnlockSim extends Thread {
2361 
2362         private final IccCard mSimCard;
2363         private final int mPhoneId;
2364 
2365         private boolean mDone = false;
2366         private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
2367         private int mRetryCount = -1;
2368 
2369         // For replies from SimCard interface
2370         private Handler mHandler;
2371 
2372         // For async handler to identify request type
2373         private static final int SUPPLY_PIN_COMPLETE = 100;
2374 
UnlockSim(int phoneId, IccCard simCard)2375         UnlockSim(int phoneId, IccCard simCard) {
2376             mPhoneId = phoneId;
2377             mSimCard = simCard;
2378         }
2379 
2380         @Override
run()2381         public void run() {
2382             Looper.prepare();
2383             synchronized (UnlockSim.this) {
2384                 mHandler = new Handler() {
2385                     @Override
2386                     public void handleMessage(Message msg) {
2387                         AsyncResult ar = (AsyncResult) msg.obj;
2388                         switch (msg.what) {
2389                             case SUPPLY_PIN_COMPLETE:
2390                                 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
2391                                 synchronized (UnlockSim.this) {
2392                                     mRetryCount = msg.arg1;
2393                                     if (ar.exception != null) {
2394                                         if (ar.exception instanceof CommandException &&
2395                                                 ((CommandException)(ar.exception)).getCommandError()
2396                                                 == CommandException.Error.PASSWORD_INCORRECT) {
2397                                             mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
2398                                         } //When UiccCardApp dispose,handle message and return exception
2399                                           else if (ar.exception instanceof CommandException &&
2400                                                 ((CommandException) (ar.exception)).getCommandError()
2401                                                         == CommandException.Error.ABORTED) {
2402                                             mResult = PhoneConstants.PIN_OPERATION_ABORTED;
2403                                         } else {
2404                                             mResult = PhoneConstants.PIN_GENERAL_FAILURE;
2405                                         }
2406                                     } else {
2407                                         mResult = PhoneConstants.PIN_RESULT_SUCCESS;
2408                                     }
2409                                     mDone = true;
2410                                     UnlockSim.this.notifyAll();
2411                                 }
2412                                 break;
2413                         }
2414                     }
2415                 };
2416                 UnlockSim.this.notifyAll();
2417             }
2418             Looper.loop();
2419         }
2420 
2421         /*
2422          * Use PIN or PUK to unlock SIM card
2423          *
2424          * If PUK is null, unlock SIM card with PIN
2425          *
2426          * If PUK is not null, unlock SIM card with PUK and set PIN code
2427          */
unlockSim(String puk, String pin)2428         synchronized int[] unlockSim(String puk, String pin) {
2429 
2430             while (mHandler == null) {
2431                 try {
2432                     wait();
2433                 } catch (InterruptedException e) {
2434                     Thread.currentThread().interrupt();
2435                 }
2436             }
2437             Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
2438 
2439             if (puk == null) {
2440                 mSimCard.supplyPin(pin, callback);
2441             } else {
2442                 mSimCard.supplyPuk(puk, pin, callback);
2443             }
2444 
2445             while (!mDone) {
2446                 try {
2447                     Log.d(LOG_TAG, "wait for done");
2448                     wait();
2449                 } catch (InterruptedException e) {
2450                     // Restore the interrupted status
2451                     Thread.currentThread().interrupt();
2452                 }
2453             }
2454             Log.d(LOG_TAG, "done");
2455             int[] resultArray = new int[2];
2456             resultArray[0] = mResult;
2457             resultArray[1] = mRetryCount;
2458 
2459             if (mResult == PhoneConstants.PIN_RESULT_SUCCESS && pin.length() > 0) {
2460                 UiccController.getInstance().getPinStorage().storePin(pin, mPhoneId);
2461             }
2462 
2463             return resultArray;
2464         }
2465     }
2466 
2467     /**
2468      * This method has been removed due to privacy and stability concerns.
2469      */
2470     @Override
updateServiceLocation()2471     public void updateServiceLocation() {
2472         Log.e(LOG_TAG, "Call to unsupported method updateServiceLocation()");
2473         return;
2474     }
2475 
2476     @Override
updateServiceLocationWithPackageName(String callingPackage)2477     public void updateServiceLocationWithPackageName(String callingPackage) {
2478         mApp.getSystemService(AppOpsManager.class)
2479                 .checkPackage(Binder.getCallingUid(), callingPackage);
2480 
2481         final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
2482         if (targetSdk > android.os.Build.VERSION_CODES.R) {
2483             // Callers targeting S have no business invoking this method.
2484             return;
2485         }
2486 
2487         LocationAccessPolicy.LocationPermissionResult locationResult =
2488                 LocationAccessPolicy.checkLocationPermission(mApp,
2489                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
2490                                 .setCallingPackage(callingPackage)
2491                                 .setCallingFeatureId(null)
2492                                 .setCallingPid(Binder.getCallingPid())
2493                                 .setCallingUid(Binder.getCallingUid())
2494                                 .setMethod("updateServiceLocation")
2495                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2496                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2497                                 .build());
2498         // Apps that lack location permission have no business calling this method;
2499         // however, because no permission was declared in the public API, denials must
2500         // all be "soft".
2501         switch (locationResult) {
2502             case DENIED_HARD: /* fall through */
2503             case DENIED_SOFT:
2504                 return;
2505         }
2506 
2507         WorkSource workSource = getWorkSource(Binder.getCallingUid());
2508         final long identity = Binder.clearCallingIdentity();
2509         try {
2510             final Phone phone = getPhone(getDefaultSubscription());
2511             if (phone != null) {
2512                 phone.updateServiceLocation(workSource);
2513             }
2514         } finally {
2515             Binder.restoreCallingIdentity(identity);
2516         }
2517     }
2518 
2519     @Deprecated
2520     @Override
isRadioOn(String callingPackage)2521     public boolean isRadioOn(String callingPackage) {
2522         return isRadioOnWithFeature(callingPackage, null);
2523     }
2524 
2525 
2526     @Override
isRadioOnWithFeature(String callingPackage, String callingFeatureId)2527     public boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId) {
2528         return isRadioOnForSubscriberWithFeature(getDefaultSubscription(), callingPackage,
2529                 callingFeatureId);
2530     }
2531 
2532     @Deprecated
2533     @Override
isRadioOnForSubscriber(int subId, String callingPackage)2534     public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
2535         return isRadioOnForSubscriberWithFeature(subId, callingPackage, null);
2536     }
2537 
2538     @Override
isRadioOnForSubscriberWithFeature(int subId, String callingPackage, String callingFeatureId)2539     public boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage,
2540             String callingFeatureId) {
2541         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2542                 mApp, subId, callingPackage, callingFeatureId, "isRadioOnForSubscriber")) {
2543             return false;
2544         }
2545 
2546         final long identity = Binder.clearCallingIdentity();
2547         try {
2548             return isRadioOnForSubscriber(subId);
2549         } finally {
2550             Binder.restoreCallingIdentity(identity);
2551         }
2552     }
2553 
isRadioOnForSubscriber(int subId)2554     private boolean isRadioOnForSubscriber(int subId) {
2555         final long identity = Binder.clearCallingIdentity();
2556         try {
2557             final Phone phone = getPhone(subId);
2558             if (phone != null) {
2559                 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
2560             } else {
2561                 return false;
2562             }
2563         } finally {
2564             Binder.restoreCallingIdentity(identity);
2565         }
2566     }
2567 
toggleRadioOnOff()2568     public void toggleRadioOnOff() {
2569         toggleRadioOnOffForSubscriber(getDefaultSubscription());
2570     }
2571 
toggleRadioOnOffForSubscriber(int subId)2572     public void toggleRadioOnOffForSubscriber(int subId) {
2573         enforceModifyPermission();
2574 
2575         final long identity = Binder.clearCallingIdentity();
2576         try {
2577             final Phone phone = getPhone(subId);
2578             if (phone != null) {
2579                 phone.setRadioPower(!isRadioOnForSubscriber(subId));
2580             }
2581         } finally {
2582             Binder.restoreCallingIdentity(identity);
2583         }
2584     }
2585 
setRadio(boolean turnOn)2586     public boolean setRadio(boolean turnOn) {
2587         return setRadioForSubscriber(getDefaultSubscription(), turnOn);
2588     }
2589 
setRadioForSubscriber(int subId, boolean turnOn)2590     public boolean setRadioForSubscriber(int subId, boolean turnOn) {
2591         enforceModifyPermission();
2592 
2593         final long identity = Binder.clearCallingIdentity();
2594         try {
2595             final Phone phone = getPhone(subId);
2596             if (phone == null) {
2597                 return false;
2598             }
2599             if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
2600                 toggleRadioOnOffForSubscriber(subId);
2601             }
2602             return true;
2603         } finally {
2604             Binder.restoreCallingIdentity(identity);
2605         }
2606     }
2607 
needMobileRadioShutdown()2608     public boolean needMobileRadioShutdown() {
2609         enforceReadPrivilegedPermission("needMobileRadioShutdown");
2610         /*
2611          * If any of the Radios are available, it will need to be
2612          * shutdown. So return true if any Radio is available.
2613          */
2614         final long identity = Binder.clearCallingIdentity();
2615         try {
2616             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
2617                 Phone phone = PhoneFactory.getPhone(i);
2618                 if (phone != null && phone.isRadioAvailable()) return true;
2619             }
2620             logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
2621             return false;
2622         } finally {
2623             Binder.restoreCallingIdentity(identity);
2624         }
2625     }
2626 
2627     @Override
shutdownMobileRadios()2628     public void shutdownMobileRadios() {
2629         enforceModifyPermission();
2630 
2631         final long identity = Binder.clearCallingIdentity();
2632         try {
2633             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
2634                 logv("Shutting down Phone " + i);
2635                 shutdownRadioUsingPhoneId(i);
2636             }
2637         } finally {
2638             Binder.restoreCallingIdentity(identity);
2639         }
2640     }
2641 
shutdownRadioUsingPhoneId(int phoneId)2642     private void shutdownRadioUsingPhoneId(int phoneId) {
2643         Phone phone = PhoneFactory.getPhone(phoneId);
2644         if (phone != null && phone.isRadioAvailable()) {
2645             phone.shutdownRadio();
2646         }
2647     }
2648 
setRadioPower(boolean turnOn)2649     public boolean setRadioPower(boolean turnOn) {
2650         enforceModifyPermission();
2651 
2652         final long identity = Binder.clearCallingIdentity();
2653         try {
2654             final Phone defaultPhone = PhoneFactory.getDefaultPhone();
2655             if (defaultPhone != null) {
2656                 defaultPhone.setRadioPower(turnOn);
2657                 return true;
2658             } else {
2659                 loge("There's no default phone.");
2660                 return false;
2661             }
2662         } finally {
2663             Binder.restoreCallingIdentity(identity);
2664         }
2665     }
2666 
setRadioPowerForSubscriber(int subId, boolean turnOn)2667     public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
2668         enforceModifyPermission();
2669 
2670         final long identity = Binder.clearCallingIdentity();
2671         try {
2672             final Phone phone = getPhone(subId);
2673             if (phone != null) {
2674                 phone.setRadioPower(turnOn);
2675                 return true;
2676             } else {
2677                 return false;
2678             }
2679         } finally {
2680             Binder.restoreCallingIdentity(identity);
2681         }
2682     }
2683 
2684     // FIXME: subId version needed
2685     @Override
enableDataConnectivity()2686     public boolean enableDataConnectivity() {
2687         enforceModifyPermission();
2688 
2689         final long identity = Binder.clearCallingIdentity();
2690         try {
2691             int subId = mSubscriptionController.getDefaultDataSubId();
2692             final Phone phone = getPhone(subId);
2693             if (phone != null) {
2694                 phone.getDataEnabledSettings().setDataEnabled(
2695                         TelephonyManager.DATA_ENABLED_REASON_USER, true);
2696                 return true;
2697             } else {
2698                 return false;
2699             }
2700         } finally {
2701             Binder.restoreCallingIdentity(identity);
2702         }
2703     }
2704 
2705     // FIXME: subId version needed
2706     @Override
disableDataConnectivity()2707     public boolean disableDataConnectivity() {
2708         enforceModifyPermission();
2709 
2710         final long identity = Binder.clearCallingIdentity();
2711         try {
2712             int subId = mSubscriptionController.getDefaultDataSubId();
2713             final Phone phone = getPhone(subId);
2714             if (phone != null) {
2715                 phone.getDataEnabledSettings().setDataEnabled(
2716                         TelephonyManager.DATA_ENABLED_REASON_USER, false);
2717                 return true;
2718             } else {
2719                 return false;
2720             }
2721         } finally {
2722             Binder.restoreCallingIdentity(identity);
2723         }
2724     }
2725 
2726     @Override
isDataConnectivityPossible(int subId)2727     public boolean isDataConnectivityPossible(int subId) {
2728         final long identity = Binder.clearCallingIdentity();
2729         try {
2730             final Phone phone = getPhone(subId);
2731             if (phone != null) {
2732                 return phone.isDataAllowed(ApnSetting.TYPE_DEFAULT);
2733             } else {
2734                 return false;
2735             }
2736         } finally {
2737             Binder.restoreCallingIdentity(identity);
2738         }
2739     }
2740 
handlePinMmi(String dialString)2741     public boolean handlePinMmi(String dialString) {
2742         return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
2743     }
2744 
handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback)2745     public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
2746         enforceCallPermission();
2747 
2748         final long identity = Binder.clearCallingIdentity();
2749         try {
2750             if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2751                 return;
2752             }
2753             Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
2754             sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
2755         } finally {
2756             Binder.restoreCallingIdentity(identity);
2757         }
2758     };
2759 
handlePinMmiForSubscriber(int subId, String dialString)2760     public boolean handlePinMmiForSubscriber(int subId, String dialString) {
2761         enforceModifyPermission();
2762 
2763         final long identity = Binder.clearCallingIdentity();
2764         try {
2765             if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2766                 return false;
2767             }
2768             return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
2769         } finally {
2770             Binder.restoreCallingIdentity(identity);
2771         }
2772     }
2773 
2774     /**
2775      * @deprecated  This method is deprecated and is only being kept due to an UnsupportedAppUsage
2776      * tag on getCallState Binder call.
2777      */
2778     @Deprecated
2779     @Override
getCallState()2780     public int getCallState() {
2781         if (CompatChanges.isChangeEnabled(
2782                 TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION,
2783                 Binder.getCallingUid())) {
2784             // Do not allow this API to be called on API version 31+, it should only be
2785             // called on old apps using this Binder call directly.
2786             throw new SecurityException("This method can only be used for applications "
2787                     + "targeting API version 30 or less.");
2788         }
2789         final long identity = Binder.clearCallingIdentity();
2790         try {
2791             Phone phone = getPhone(getDefaultSubscription());
2792             return phone == null ? TelephonyManager.CALL_STATE_IDLE :
2793                     PhoneConstantConversions.convertCallState(phone.getState());
2794         } finally {
2795             Binder.restoreCallingIdentity(identity);
2796         }
2797     }
2798 
2799     @Override
getCallStateForSubscription(int subId, String callingPackage, String featureId)2800     public int getCallStateForSubscription(int subId, String callingPackage, String featureId) {
2801         if (CompatChanges.isChangeEnabled(
2802                 TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION,
2803                 Binder.getCallingUid())) {
2804             // Check READ_PHONE_STATE for API version 31+
2805             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
2806                     featureId, "getCallStateForSubscription")) {
2807                 throw new SecurityException("getCallState requires READ_PHONE_STATE for apps "
2808                         + "targeting API level 31+.");
2809             }
2810         }
2811         final long identity = Binder.clearCallingIdentity();
2812         try {
2813             Phone phone = getPhone(subId);
2814             return phone == null ? TelephonyManager.CALL_STATE_IDLE :
2815                     PhoneConstantConversions.convertCallState(phone.getState());
2816         } finally {
2817             Binder.restoreCallingIdentity(identity);
2818         }
2819     }
2820 
2821     @Override
getDataState()2822     public int getDataState() {
2823         return getDataStateForSubId(mSubscriptionController.getDefaultDataSubId());
2824     }
2825 
2826     @Override
getDataStateForSubId(int subId)2827     public int getDataStateForSubId(int subId) {
2828         final long identity = Binder.clearCallingIdentity();
2829         try {
2830             final Phone phone = getPhone(subId);
2831             if (phone != null) {
2832                 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
2833             } else {
2834                 return PhoneConstantConversions.convertDataState(
2835                         PhoneConstants.DataState.DISCONNECTED);
2836             }
2837         } finally {
2838             Binder.restoreCallingIdentity(identity);
2839         }
2840     }
2841 
2842     @Override
getDataActivity()2843     public int getDataActivity() {
2844         return getDataActivityForSubId(mSubscriptionController.getDefaultDataSubId());
2845     }
2846 
2847     @Override
getDataActivityForSubId(int subId)2848     public int getDataActivityForSubId(int subId) {
2849         final long identity = Binder.clearCallingIdentity();
2850         try {
2851             final Phone phone = getPhone(subId);
2852             if (phone != null) {
2853                 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
2854             } else {
2855                 return TelephonyManager.DATA_ACTIVITY_NONE;
2856             }
2857         } finally {
2858             Binder.restoreCallingIdentity(identity);
2859         }
2860     }
2861 
2862     @Override
getCellLocation(String callingPackage, String callingFeatureId)2863     public CellIdentity getCellLocation(String callingPackage, String callingFeatureId) {
2864         mApp.getSystemService(AppOpsManager.class)
2865                 .checkPackage(Binder.getCallingUid(), callingPackage);
2866 
2867         LocationAccessPolicy.LocationPermissionResult locationResult =
2868                 LocationAccessPolicy.checkLocationPermission(mApp,
2869                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
2870                                 .setCallingPackage(callingPackage)
2871                                 .setCallingFeatureId(callingFeatureId)
2872                                 .setCallingPid(Binder.getCallingPid())
2873                                 .setCallingUid(Binder.getCallingUid())
2874                                 .setMethod("getCellLocation")
2875                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2876                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2877                                 .build());
2878         switch (locationResult) {
2879             case DENIED_HARD:
2880                 throw new SecurityException("Not allowed to access cell location");
2881             case DENIED_SOFT:
2882                 return (getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
2883                         ? new CellIdentityCdma() : new CellIdentityGsm();
2884         }
2885 
2886         WorkSource workSource = getWorkSource(Binder.getCallingUid());
2887         final long identity = Binder.clearCallingIdentity();
2888         try {
2889             if (DBG_LOC) log("getCellLocation: is active user");
2890             int subId = mSubscriptionController.getDefaultDataSubId();
2891             return (CellIdentity) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
2892         } finally {
2893             Binder.restoreCallingIdentity(identity);
2894         }
2895     }
2896 
2897     @Override
getNetworkCountryIsoForPhone(int phoneId)2898     public String getNetworkCountryIsoForPhone(int phoneId) {
2899         // Reporting the correct network country is ambiguous when IWLAN could conflict with
2900         // registered cell info, so return a NULL country instead.
2901         final long identity = Binder.clearCallingIdentity();
2902         try {
2903             if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
2904                 // Get default phone in this case.
2905                 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
2906             }
2907             final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
2908             Phone phone = PhoneFactory.getPhone(phoneId);
2909             if (phone == null) return "";
2910             ServiceStateTracker sst = phone.getServiceStateTracker();
2911             if (sst == null) return "";
2912             LocaleTracker lt = sst.getLocaleTracker();
2913             if (lt == null) return "";
2914             return lt.getCurrentCountry();
2915         } finally {
2916             Binder.restoreCallingIdentity(identity);
2917         }
2918     }
2919 
2920     /**
2921      * This method was removed due to potential issues caused by performing partial
2922      * updates of service state, and lack of a credible use case.
2923      *
2924      * This has the ability to break the telephony implementation by disabling notification of
2925      * changes in device connectivity. DO NOT USE THIS!
2926      */
2927     @Override
enableLocationUpdates()2928     public void enableLocationUpdates() {
2929         mApp.enforceCallingOrSelfPermission(
2930                 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
2931     }
2932 
2933     /**
2934      * This method was removed due to potential issues caused by performing partial
2935      * updates of service state, and lack of a credible use case.
2936      *
2937      * This has the ability to break the telephony implementation by disabling notification of
2938      * changes in device connectivity. DO NOT USE THIS!
2939      */
2940     @Override
disableLocationUpdates()2941     public void disableLocationUpdates() {
2942         mApp.enforceCallingOrSelfPermission(
2943                 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
2944     }
2945 
2946     @Override
2947     @SuppressWarnings("unchecked")
getNeighboringCellInfo(String callingPackage, String callingFeatureId)2948     public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage,
2949             String callingFeatureId) {
2950         final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
2951         if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
2952             throw new SecurityException(
2953                     "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
2954         }
2955 
2956         if (mAppOps.noteOp(AppOpsManager.OPSTR_NEIGHBORING_CELLS, Binder.getCallingUid(),
2957                 callingPackage) != AppOpsManager.MODE_ALLOWED) {
2958             return null;
2959         }
2960 
2961         if (DBG_LOC) log("getNeighboringCellInfo: is active user");
2962 
2963         List<CellInfo> info = getAllCellInfo(callingPackage, callingFeatureId);
2964         if (info == null) return null;
2965 
2966         List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
2967         for (CellInfo ci : info) {
2968             if (ci instanceof CellInfoGsm) {
2969                 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
2970             } else if (ci instanceof CellInfoWcdma) {
2971                 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
2972             }
2973         }
2974         return (neighbors.size()) > 0 ? neighbors : null;
2975     }
2976 
getCachedCellInfo()2977     private List<CellInfo> getCachedCellInfo() {
2978         List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2979         for (Phone phone : PhoneFactory.getPhones()) {
2980             List<CellInfo> info = phone.getAllCellInfo();
2981             if (info != null) cellInfos.addAll(info);
2982         }
2983         return cellInfos;
2984     }
2985 
2986     @Override
getAllCellInfo(String callingPackage, String callingFeatureId)2987     public List<CellInfo> getAllCellInfo(String callingPackage, String callingFeatureId) {
2988         mApp.getSystemService(AppOpsManager.class)
2989                 .checkPackage(Binder.getCallingUid(), callingPackage);
2990 
2991         LocationAccessPolicy.LocationPermissionResult locationResult =
2992                 LocationAccessPolicy.checkLocationPermission(mApp,
2993                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
2994                                 .setCallingPackage(callingPackage)
2995                                 .setCallingFeatureId(callingFeatureId)
2996                                 .setCallingPid(Binder.getCallingPid())
2997                                 .setCallingUid(Binder.getCallingUid())
2998                                 .setMethod("getAllCellInfo")
2999                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
3000                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
3001                                 .build());
3002         switch (locationResult) {
3003             case DENIED_HARD:
3004                 throw new SecurityException("Not allowed to access cell info");
3005             case DENIED_SOFT:
3006                 return new ArrayList<>();
3007         }
3008 
3009         final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
3010         if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
3011             return getCachedCellInfo();
3012         }
3013 
3014         if (DBG_LOC) log("getAllCellInfo: is active user");
3015         WorkSource workSource = getWorkSource(Binder.getCallingUid());
3016         final long identity = Binder.clearCallingIdentity();
3017         try {
3018             List<CellInfo> cellInfos = new ArrayList<CellInfo>();
3019             for (Phone phone : PhoneFactory.getPhones()) {
3020                 final List<CellInfo> info = (List<CellInfo>) sendRequest(
3021                         CMD_GET_ALL_CELL_INFO, null, phone, workSource);
3022                 if (info != null) cellInfos.addAll(info);
3023             }
3024             return cellInfos;
3025         } finally {
3026             Binder.restoreCallingIdentity(identity);
3027         }
3028     }
3029 
3030     @Override
requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage, String callingFeatureId)3031     public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage,
3032             String callingFeatureId) {
3033         requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId,
3034                 getWorkSource(Binder.getCallingUid()));
3035     }
3036 
3037     @Override
requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb, String callingPackage, String callingFeatureId, WorkSource workSource)3038     public void requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb,
3039             String callingPackage, String callingFeatureId, WorkSource workSource) {
3040         enforceModifyPermission();
3041         requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId, workSource);
3042     }
3043 
requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb, String callingPackage, String callingFeatureId, WorkSource workSource)3044     private void requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb,
3045             String callingPackage, String callingFeatureId, WorkSource workSource) {
3046         mApp.getSystemService(AppOpsManager.class)
3047                 .checkPackage(Binder.getCallingUid(), callingPackage);
3048 
3049         LocationAccessPolicy.LocationPermissionResult locationResult =
3050                 LocationAccessPolicy.checkLocationPermission(mApp,
3051                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
3052                                 .setCallingPackage(callingPackage)
3053                                 .setCallingFeatureId(callingFeatureId)
3054                                 .setCallingPid(Binder.getCallingPid())
3055                                 .setCallingUid(Binder.getCallingUid())
3056                                 .setMethod("requestCellInfoUpdate")
3057                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
3058                                 .setMinSdkVersionForFine(Build.VERSION_CODES.BASE)
3059                                 .build());
3060         switch (locationResult) {
3061             case DENIED_HARD:
3062                 if (TelephonyPermissions
3063                         .getTargetSdk(mApp, callingPackage) < Build.VERSION_CODES.Q) {
3064                     // Safetynet logging for b/154934934
3065                     EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
3066                 }
3067                 throw new SecurityException("Not allowed to access cell info");
3068             case DENIED_SOFT:
3069                 if (TelephonyPermissions
3070                         .getTargetSdk(mApp, callingPackage) < Build.VERSION_CODES.Q) {
3071                     // Safetynet logging for b/154934934
3072                     EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
3073                 }
3074                 try {
3075                     cb.onCellInfo(new ArrayList<CellInfo>());
3076                 } catch (RemoteException re) {
3077                     // Drop without consequences
3078                 }
3079                 return;
3080         }
3081 
3082 
3083         final Phone phone = getPhoneFromSubId(subId);
3084         if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
3085 
3086         sendRequestAsync(CMD_REQUEST_CELL_INFO_UPDATE, cb, phone, workSource);
3087     }
3088 
3089     @Override
setCellInfoListRate(int rateInMillis)3090     public void setCellInfoListRate(int rateInMillis) {
3091         enforceModifyPermission();
3092         WorkSource workSource = getWorkSource(Binder.getCallingUid());
3093 
3094         final long identity = Binder.clearCallingIdentity();
3095         try {
3096             getDefaultPhone().setCellInfoListRate(rateInMillis, workSource);
3097         } finally {
3098             Binder.restoreCallingIdentity(identity);
3099         }
3100     }
3101 
3102     @Override
getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId)3103     public String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
3104         Phone phone = PhoneFactory.getPhone(slotIndex);
3105         if (phone == null) {
3106             return null;
3107         }
3108         int subId = phone.getSubId();
3109         enforceCallingPackage(callingPackage, Binder.getCallingUid(), "getImeiForSlot");
3110         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
3111                 callingPackage, callingFeatureId, "getImeiForSlot")) {
3112             return null;
3113         }
3114 
3115         final long identity = Binder.clearCallingIdentity();
3116         try {
3117             return phone.getImei();
3118         } finally {
3119             Binder.restoreCallingIdentity(identity);
3120         }
3121     }
3122 
3123     @Override
getTypeAllocationCodeForSlot(int slotIndex)3124     public String getTypeAllocationCodeForSlot(int slotIndex) {
3125         Phone phone = PhoneFactory.getPhone(slotIndex);
3126         String tac = null;
3127         if (phone != null) {
3128             String imei = phone.getImei();
3129             tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
3130         }
3131         return tac;
3132     }
3133 
3134     @Override
getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId)3135     public String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
3136         Phone phone = PhoneFactory.getPhone(slotIndex);
3137         if (phone == null) {
3138             return null;
3139         }
3140 
3141         int subId = phone.getSubId();
3142         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
3143                 callingPackage, callingFeatureId, "getMeidForSlot")) {
3144             return null;
3145         }
3146 
3147         final long identity = Binder.clearCallingIdentity();
3148         try {
3149             return phone.getMeid();
3150         } finally {
3151             Binder.restoreCallingIdentity(identity);
3152         }
3153     }
3154 
3155     @Override
getManufacturerCodeForSlot(int slotIndex)3156     public String getManufacturerCodeForSlot(int slotIndex) {
3157         Phone phone = PhoneFactory.getPhone(slotIndex);
3158         String manufacturerCode = null;
3159         if (phone != null) {
3160             String meid = phone.getMeid();
3161             manufacturerCode = meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
3162         }
3163         return manufacturerCode;
3164     }
3165 
3166     @Override
getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage, String callingFeatureId)3167     public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage,
3168             String callingFeatureId) {
3169         Phone phone = PhoneFactory.getPhone(slotIndex);
3170         if (phone == null) {
3171             return null;
3172         }
3173         int subId = phone.getSubId();
3174         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3175                 mApp, subId, callingPackage, callingFeatureId,
3176                 "getDeviceSoftwareVersionForSlot")) {
3177             return null;
3178         }
3179 
3180         final long identity = Binder.clearCallingIdentity();
3181         try {
3182             return phone.getDeviceSvn();
3183         } finally {
3184             Binder.restoreCallingIdentity(identity);
3185         }
3186     }
3187 
3188     @Override
getSubscriptionCarrierId(int subId)3189     public int getSubscriptionCarrierId(int subId) {
3190         final long identity = Binder.clearCallingIdentity();
3191         try {
3192             final Phone phone = getPhone(subId);
3193             return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
3194         } finally {
3195             Binder.restoreCallingIdentity(identity);
3196         }
3197     }
3198 
3199     @Override
getSubscriptionCarrierName(int subId)3200     public String getSubscriptionCarrierName(int subId) {
3201         final long identity = Binder.clearCallingIdentity();
3202         try {
3203             final Phone phone = getPhone(subId);
3204             return phone == null ? null : phone.getCarrierName();
3205         } finally {
3206             Binder.restoreCallingIdentity(identity);
3207         }
3208     }
3209 
3210     @Override
getSubscriptionSpecificCarrierId(int subId)3211     public int getSubscriptionSpecificCarrierId(int subId) {
3212         final long identity = Binder.clearCallingIdentity();
3213         try {
3214             final Phone phone = getPhone(subId);
3215             return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
3216                     : phone.getSpecificCarrierId();
3217         } finally {
3218             Binder.restoreCallingIdentity(identity);
3219         }
3220     }
3221 
3222     @Override
getSubscriptionSpecificCarrierName(int subId)3223     public String getSubscriptionSpecificCarrierName(int subId) {
3224         final long identity = Binder.clearCallingIdentity();
3225         try {
3226             final Phone phone = getPhone(subId);
3227             return phone == null ? null : phone.getSpecificCarrierName();
3228         } finally {
3229             Binder.restoreCallingIdentity(identity);
3230         }
3231     }
3232 
3233     @Override
getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc)3234     public int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc) {
3235         if (!isSubscriptionMccMnc) {
3236             enforceReadPrivilegedPermission("getCarrierIdFromMccMnc");
3237         }
3238         final Phone phone = PhoneFactory.getPhone(slotIndex);
3239         if (phone == null) {
3240             return TelephonyManager.UNKNOWN_CARRIER_ID;
3241         }
3242         final long identity = Binder.clearCallingIdentity();
3243         try {
3244             return CarrierResolver.getCarrierIdFromMccMnc(phone.getContext(), mccmnc);
3245         } finally {
3246             Binder.restoreCallingIdentity(identity);
3247         }
3248     }
3249 
3250     //
3251     // Internal helper methods.
3252     //
3253 
3254     /**
3255      * Make sure the caller is the calling package itself
3256      *
3257      * @throws SecurityException if the caller is not the calling package
3258      */
enforceCallingPackage(String callingPackage, int callingUid, String message)3259     private void enforceCallingPackage(String callingPackage, int callingUid, String message) {
3260         int packageUid = -1;
3261         PackageManager pm = mApp.getBaseContext().createContextAsUser(
3262                 UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager();
3263         try {
3264             packageUid = pm.getPackageUid(callingPackage, 0);
3265         } catch (PackageManager.NameNotFoundException e) {
3266             // packageUid is -1
3267         }
3268         if (packageUid != callingUid) {
3269             throw new SecurityException(message + ": Package " + callingPackage
3270                     + " does not belong to " + callingUid);
3271         }
3272     }
3273 
3274     /**
3275      * Make sure the caller has the MODIFY_PHONE_STATE permission.
3276      *
3277      * @throws SecurityException if the caller does not have the required permission
3278      */
enforceModifyPermission()3279     private void enforceModifyPermission() {
3280         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
3281     }
3282 
3283     /**
3284      * Make sure the caller is system.
3285      *
3286      * @throws SecurityException if the caller is not system.
3287      */
enforceSystemCaller()3288     private static void enforceSystemCaller() {
3289         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
3290             throw new SecurityException("Caller must be system");
3291         }
3292     }
3293 
enforceActiveEmergencySessionPermission()3294     private void enforceActiveEmergencySessionPermission() {
3295         mApp.enforceCallingOrSelfPermission(
3296                 android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
3297     }
3298 
3299     /**
3300      * Make sure the caller has the CALL_PHONE permission.
3301      *
3302      * @throws SecurityException if the caller does not have the required permission
3303      */
enforceCallPermission()3304     private void enforceCallPermission() {
3305         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
3306     }
3307 
enforceSettingsPermission()3308     private void enforceSettingsPermission() {
3309         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS, null);
3310     }
3311 
enforceRebootPermission()3312     private void enforceRebootPermission() {
3313         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
3314     }
3315 
createTelUrl(String number)3316     private String createTelUrl(String number) {
3317         if (TextUtils.isEmpty(number)) {
3318             return null;
3319         }
3320 
3321         return "tel:" + number;
3322     }
3323 
log(String msg)3324     private static void log(String msg) {
3325         Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
3326     }
3327 
logv(String msg)3328     private static void logv(String msg) {
3329         Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
3330     }
3331 
loge(String msg)3332     private static void loge(String msg) {
3333         Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
3334     }
3335 
3336     @Override
getActivePhoneType()3337     public int getActivePhoneType() {
3338         return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
3339     }
3340 
3341     @Override
getActivePhoneTypeForSlot(int slotIndex)3342     public int getActivePhoneTypeForSlot(int slotIndex) {
3343         final long identity = Binder.clearCallingIdentity();
3344         try {
3345             final Phone phone = PhoneFactory.getPhone(slotIndex);
3346             if (phone == null) {
3347                 return PhoneConstants.PHONE_TYPE_NONE;
3348             } else {
3349                 return phone.getPhoneType();
3350             }
3351         } finally {
3352             Binder.restoreCallingIdentity(identity);
3353         }
3354     }
3355 
3356     /**
3357      * Returns the CDMA ERI icon index to display
3358      */
3359     @Override
getCdmaEriIconIndex(String callingPackage, String callingFeatureId)3360     public int getCdmaEriIconIndex(String callingPackage, String callingFeatureId) {
3361         return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage,
3362                 callingFeatureId);
3363     }
3364 
3365     @Override
getCdmaEriIconIndexForSubscriber(int subId, String callingPackage, String callingFeatureId)3366     public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
3367             String callingFeatureId) {
3368         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3369                 mApp, subId, callingPackage, callingFeatureId,
3370                 "getCdmaEriIconIndexForSubscriber")) {
3371             return -1;
3372         }
3373 
3374         final long identity = Binder.clearCallingIdentity();
3375         try {
3376             final Phone phone = getPhone(subId);
3377             if (phone != null) {
3378                 return phone.getCdmaEriIconIndex();
3379             } else {
3380                 return -1;
3381             }
3382         } finally {
3383             Binder.restoreCallingIdentity(identity);
3384         }
3385     }
3386 
3387     /**
3388      * Returns the CDMA ERI icon mode,
3389      * 0 - ON
3390      * 1 - FLASHING
3391      */
3392     @Override
getCdmaEriIconMode(String callingPackage, String callingFeatureId)3393     public int getCdmaEriIconMode(String callingPackage, String callingFeatureId) {
3394         return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage,
3395                 callingFeatureId);
3396     }
3397 
3398     @Override
getCdmaEriIconModeForSubscriber(int subId, String callingPackage, String callingFeatureId)3399     public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
3400             String callingFeatureId) {
3401         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3402                 mApp, subId, callingPackage, callingFeatureId,
3403                 "getCdmaEriIconModeForSubscriber")) {
3404             return -1;
3405         }
3406 
3407         final long identity = Binder.clearCallingIdentity();
3408         try {
3409             final Phone phone = getPhone(subId);
3410             if (phone != null) {
3411                 return phone.getCdmaEriIconMode();
3412             } else {
3413                 return -1;
3414             }
3415         } finally {
3416             Binder.restoreCallingIdentity(identity);
3417         }
3418     }
3419 
3420     /**
3421      * Returns the CDMA ERI text,
3422      */
3423     @Override
getCdmaEriText(String callingPackage, String callingFeatureId)3424     public String getCdmaEriText(String callingPackage, String callingFeatureId) {
3425         return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage,
3426                 callingFeatureId);
3427     }
3428 
3429     @Override
getCdmaEriTextForSubscriber(int subId, String callingPackage, String callingFeatureId)3430     public String getCdmaEriTextForSubscriber(int subId, String callingPackage,
3431             String callingFeatureId) {
3432         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3433                 mApp, subId, callingPackage, callingFeatureId,
3434                 "getCdmaEriIconTextForSubscriber")) {
3435             return null;
3436         }
3437 
3438         final long identity = Binder.clearCallingIdentity();
3439         try {
3440             final Phone phone = getPhone(subId);
3441             if (phone != null) {
3442                 return phone.getCdmaEriText();
3443             } else {
3444                 return null;
3445             }
3446         } finally {
3447             Binder.restoreCallingIdentity(identity);
3448         }
3449     }
3450 
3451     /**
3452      * Returns the CDMA MDN.
3453      */
3454     @Override
getCdmaMdn(int subId)3455     public String getCdmaMdn(int subId) {
3456         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3457                 mApp, subId, "getCdmaMdn");
3458 
3459         final long identity = Binder.clearCallingIdentity();
3460         try {
3461             final Phone phone = getPhone(subId);
3462             if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
3463                 return phone.getLine1Number();
3464             } else {
3465                 loge("getCdmaMdn: no phone found. Invalid subId: " + subId);
3466                 return null;
3467             }
3468         } finally {
3469             Binder.restoreCallingIdentity(identity);
3470         }
3471     }
3472 
3473     /**
3474      * Returns the CDMA MIN.
3475      */
3476     @Override
getCdmaMin(int subId)3477     public String getCdmaMin(int subId) {
3478         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3479                 mApp, subId, "getCdmaMin");
3480 
3481         final long identity = Binder.clearCallingIdentity();
3482         try {
3483             final Phone phone = getPhone(subId);
3484             if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
3485                 return phone.getCdmaMin();
3486             } else {
3487                 return null;
3488             }
3489         } finally {
3490             Binder.restoreCallingIdentity(identity);
3491         }
3492     }
3493 
3494     @Override
requestNumberVerification(PhoneNumberRange range, long timeoutMillis, INumberVerificationCallback callback, String callingPackage)3495     public void requestNumberVerification(PhoneNumberRange range, long timeoutMillis,
3496             INumberVerificationCallback callback, String callingPackage) {
3497         if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
3498                 != PERMISSION_GRANTED) {
3499             throw new SecurityException("Caller must hold the MODIFY_PHONE_STATE permission");
3500         }
3501         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3502 
3503         String authorizedPackage = NumberVerificationManager.getAuthorizedPackage(mApp);
3504         if (!TextUtils.equals(callingPackage, authorizedPackage)) {
3505             throw new SecurityException("Calling package must be configured in the device config: "
3506                     + "calling package: " + callingPackage
3507                     + ", configured package: " + authorizedPackage);
3508         }
3509 
3510         if (range == null) {
3511             throw new NullPointerException("Range must be non-null");
3512         }
3513 
3514         timeoutMillis = Math.min(timeoutMillis,
3515                 TelephonyManager.getMaxNumberVerificationTimeoutMillis());
3516 
3517         NumberVerificationManager.getInstance().requestVerification(range, callback, timeoutMillis);
3518     }
3519 
3520     /**
3521      * Returns true if CDMA provisioning needs to run.
3522      */
needsOtaServiceProvisioning()3523     public boolean needsOtaServiceProvisioning() {
3524         final long identity = Binder.clearCallingIdentity();
3525         try {
3526             return getDefaultPhone().needsOtaServiceProvisioning();
3527         } finally {
3528             Binder.restoreCallingIdentity(identity);
3529         }
3530     }
3531 
3532     /**
3533      * Sets the voice mail number of a given subId.
3534      */
3535     @Override
setVoiceMailNumber(int subId, String alphaTag, String number)3536     public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
3537         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
3538                 mApp, subId, "setVoiceMailNumber");
3539 
3540         final long identity = Binder.clearCallingIdentity();
3541         try {
3542             Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
3543                     new Pair<String, String>(alphaTag, number), new Integer(subId));
3544             return success;
3545         } finally {
3546             Binder.restoreCallingIdentity(identity);
3547         }
3548     }
3549 
3550     @Override
getVisualVoicemailSettings(String callingPackage, int subId)3551     public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
3552         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3553         TelecomManager tm = mApp.getSystemService(TelecomManager.class);
3554         String systemDialer = tm.getSystemDialerPackage();
3555         if (!TextUtils.equals(callingPackage, systemDialer)) {
3556             throw new SecurityException("caller must be system dialer");
3557         }
3558 
3559         final long identity = Binder.clearCallingIdentity();
3560         try {
3561             PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
3562             if (phoneAccountHandle == null) {
3563                 return null;
3564             }
3565             return VisualVoicemailSettingsUtil.dump(mApp, phoneAccountHandle);
3566         } finally {
3567             Binder.restoreCallingIdentity(identity);
3568         }
3569     }
3570 
3571     @Override
getVisualVoicemailPackageName(String callingPackage, String callingFeatureId, int subId)3572     public String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId,
3573             int subId) {
3574         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3575         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3576                 mApp, subId, callingPackage, callingFeatureId,
3577                 "getVisualVoicemailPackageName")) {
3578             return null;
3579         }
3580 
3581         final long identity = Binder.clearCallingIdentity();
3582         try {
3583             return RemoteVvmTaskManager.getRemotePackage(mApp, subId).getPackageName();
3584         } finally {
3585             Binder.restoreCallingIdentity(identity);
3586         }
3587     }
3588 
3589     @Override
enableVisualVoicemailSmsFilter(String callingPackage, int subId, VisualVoicemailSmsFilterSettings settings)3590     public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
3591             VisualVoicemailSmsFilterSettings settings) {
3592         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3593 
3594         final long identity = Binder.clearCallingIdentity();
3595         try {
3596             VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
3597                     mApp, callingPackage, subId, settings);
3598         } finally {
3599             Binder.restoreCallingIdentity(identity);
3600         }
3601     }
3602 
3603     @Override
disableVisualVoicemailSmsFilter(String callingPackage, int subId)3604     public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
3605         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3606 
3607         final long identity = Binder.clearCallingIdentity();
3608         try {
3609             VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
3610                     mApp, callingPackage, subId);
3611         } finally {
3612             Binder.restoreCallingIdentity(identity);
3613         }
3614     }
3615 
3616     @Override
getVisualVoicemailSmsFilterSettings( String callingPackage, int subId)3617     public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
3618             String callingPackage, int subId) {
3619         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3620 
3621         final long identity = Binder.clearCallingIdentity();
3622         try {
3623             return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
3624                     mApp, callingPackage, subId);
3625         } finally {
3626             Binder.restoreCallingIdentity(identity);
3627         }
3628     }
3629 
3630     @Override
getActiveVisualVoicemailSmsFilterSettings(int subId)3631     public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
3632         enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
3633 
3634         final long identity = Binder.clearCallingIdentity();
3635         try {
3636             return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
3637                     mApp, subId);
3638         } finally {
3639             Binder.restoreCallingIdentity(identity);
3640         }
3641     }
3642 
3643     @Override
sendVisualVoicemailSmsForSubscriber(String callingPackage, String callingAttributionTag, int subId, String number, int port, String text, PendingIntent sentIntent)3644     public void sendVisualVoicemailSmsForSubscriber(String callingPackage,
3645             String callingAttributionTag, int subId, String number, int port, String text,
3646             PendingIntent sentIntent) {
3647         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3648         enforceVisualVoicemailPackage(callingPackage, subId);
3649         enforceSendSmsPermission();
3650         SmsController smsController = PhoneFactory.getSmsController();
3651         smsController.sendVisualVoicemailSmsForSubscriber(callingPackage, callingAttributionTag,
3652                 subId, number, port, text, sentIntent);
3653     }
3654 
3655     /**
3656      * Sets the voice activation state of a given subId.
3657      */
3658     @Override
setVoiceActivationState(int subId, int activationState)3659     public void setVoiceActivationState(int subId, int activationState) {
3660         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3661                 mApp, subId, "setVoiceActivationState");
3662 
3663         final long identity = Binder.clearCallingIdentity();
3664         try {
3665             final Phone phone = getPhone(subId);
3666             if (phone != null) {
3667                 phone.setVoiceActivationState(activationState);
3668             } else {
3669                 loge("setVoiceActivationState fails with invalid subId: " + subId);
3670             }
3671         } finally {
3672             Binder.restoreCallingIdentity(identity);
3673         }
3674     }
3675 
3676     /**
3677      * Sets the data activation state of a given subId.
3678      */
3679     @Override
setDataActivationState(int subId, int activationState)3680     public void setDataActivationState(int subId, int activationState) {
3681         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3682                 mApp, subId, "setDataActivationState");
3683 
3684         final long identity = Binder.clearCallingIdentity();
3685         try {
3686             final Phone phone = getPhone(subId);
3687             if (phone != null) {
3688                 phone.setDataActivationState(activationState);
3689             } else {
3690                 loge("setDataActivationState fails with invalid subId: " + subId);
3691             }
3692         } finally {
3693             Binder.restoreCallingIdentity(identity);
3694         }
3695     }
3696 
3697     /**
3698      * Returns the voice activation state of a given subId.
3699      */
3700     @Override
getVoiceActivationState(int subId, String callingPackage)3701     public int getVoiceActivationState(int subId, String callingPackage) {
3702         enforceReadPrivilegedPermission("getVoiceActivationState");
3703 
3704         final Phone phone = getPhone(subId);
3705         final long identity = Binder.clearCallingIdentity();
3706         try {
3707             if (phone != null) {
3708                 return phone.getVoiceActivationState();
3709             } else {
3710                 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
3711             }
3712         } finally {
3713             Binder.restoreCallingIdentity(identity);
3714         }
3715     }
3716 
3717     /**
3718      * Returns the data activation state of a given subId.
3719      */
3720     @Override
getDataActivationState(int subId, String callingPackage)3721     public int getDataActivationState(int subId, String callingPackage) {
3722         enforceReadPrivilegedPermission("getDataActivationState");
3723 
3724         final Phone phone = getPhone(subId);
3725         final long identity = Binder.clearCallingIdentity();
3726         try {
3727             if (phone != null) {
3728                 return phone.getDataActivationState();
3729             } else {
3730                 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
3731             }
3732         } finally {
3733             Binder.restoreCallingIdentity(identity);
3734         }
3735     }
3736 
3737     /**
3738      * Returns the unread count of voicemails for a subId
3739      */
3740     @Override
getVoiceMessageCountForSubscriber(int subId, String callingPackage, String callingFeatureId)3741     public int getVoiceMessageCountForSubscriber(int subId, String callingPackage,
3742             String callingFeatureId) {
3743         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3744                 mApp, subId, callingPackage, callingFeatureId,
3745                 "getVoiceMessageCountForSubscriber")) {
3746             return 0;
3747         }
3748         final long identity = Binder.clearCallingIdentity();
3749         try {
3750             final Phone phone = getPhone(subId);
3751             if (phone != null) {
3752                 return phone.getVoiceMessageCount();
3753             } else {
3754                 return 0;
3755             }
3756         } finally {
3757             Binder.restoreCallingIdentity(identity);
3758         }
3759     }
3760 
3761     /**
3762       * returns true, if the device is in a state where both voice and data
3763       * are supported simultaneously. This can change based on location or network condition.
3764      */
3765     @Override
isConcurrentVoiceAndDataAllowed(int subId)3766     public boolean isConcurrentVoiceAndDataAllowed(int subId) {
3767         final long identity = Binder.clearCallingIdentity();
3768         try {
3769             final Phone phone = getPhone(subId);
3770             return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
3771         } finally {
3772             Binder.restoreCallingIdentity(identity);
3773         }
3774     }
3775 
3776     /**
3777      * Send the dialer code if called from the current default dialer or the caller has
3778      * carrier privilege.
3779      * @param inputCode The dialer code to send
3780      */
3781     @Override
sendDialerSpecialCode(String callingPackage, String inputCode)3782     public void sendDialerSpecialCode(String callingPackage, String inputCode) {
3783         final Phone defaultPhone = getDefaultPhone();
3784         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3785         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
3786         String defaultDialer = tm.getDefaultDialerPackage();
3787         if (!TextUtils.equals(callingPackage, defaultDialer)) {
3788             TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
3789                     getDefaultSubscription(), "sendDialerSpecialCode");
3790         }
3791 
3792         final long identity = Binder.clearCallingIdentity();
3793         try {
3794             defaultPhone.sendDialerSpecialCode(inputCode);
3795         } finally {
3796             Binder.restoreCallingIdentity(identity);
3797         }
3798     }
3799 
3800     @Override
getNetworkSelectionMode(int subId)3801     public int getNetworkSelectionMode(int subId) {
3802         TelephonyPermissions
3803                     .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3804                     mApp, subId, "getNetworkSelectionMode");
3805         final long identity = Binder.clearCallingIdentity();
3806         try {
3807             if (!isActiveSubscription(subId)) {
3808                 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
3809             }
3810             return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
3811         } finally {
3812             Binder.restoreCallingIdentity(identity);
3813         }
3814     }
3815 
3816     @Override
isInEmergencySmsMode()3817     public boolean isInEmergencySmsMode() {
3818         enforceReadPrivilegedPermission("isInEmergencySmsMode");
3819         final long identity = Binder.clearCallingIdentity();
3820         try {
3821             for (Phone phone : PhoneFactory.getPhones()) {
3822                 if (phone.isInEmergencySmsMode()) {
3823                     return true;
3824                 }
3825             }
3826         } finally {
3827             Binder.restoreCallingIdentity(identity);
3828         }
3829         return false;
3830     }
3831 
3832     /**
3833      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3834      * @param subId The subscription to use to check the configuration.
3835      * @param c The callback that will be used to send the result.
3836      */
3837     @Override
registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)3838     public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)
3839             throws RemoteException {
3840         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3841                 mApp, subId, "registerImsRegistrationCallback");
3842 
3843         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3844             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3845                     "IMS not available on device.");
3846         }
3847         final long token = Binder.clearCallingIdentity();
3848         try {
3849             int slotId = getSlotIndexOrException(subId);
3850             verifyImsMmTelConfiguredOrThrow(slotId);
3851             ImsManager.getInstance(mApp, slotId).addRegistrationCallbackForSubscription(c, subId);
3852         } catch (ImsException e) {
3853             throw new ServiceSpecificException(e.getCode());
3854         } finally {
3855             Binder.restoreCallingIdentity(token);
3856         }
3857     }
3858 
3859     /**
3860      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3861      * @param subId The subscription to use to check the configuration.
3862      * @param c The callback that will be used to send the result.
3863      */
3864     @Override
unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c)3865     public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c) {
3866         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3867                 mApp, subId, "unregisterImsRegistrationCallback");
3868         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3869             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3870         }
3871         final long token = Binder.clearCallingIdentity();
3872         try {
3873             ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3874                     .removeRegistrationCallbackForSubscription(c, subId);
3875         } catch (ImsException e) {
3876             Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
3877                     + "is inactive, ignoring unregister.");
3878             // If the subscription is no longer active, just return, since the callback
3879             // will already have been removed internally.
3880         } finally {
3881             Binder.restoreCallingIdentity(token);
3882         }
3883     }
3884 
3885     /**
3886      * Get the IMS service registration state for the MmTelFeature associated with this sub id.
3887      */
3888     @Override
getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer)3889     public void getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer) {
3890         enforceReadPrivilegedPermission("getImsMmTelRegistrationState");
3891         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3892             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3893                     "IMS not available on device.");
3894         }
3895         final long token = Binder.clearCallingIdentity();
3896         try {
3897             Phone phone = getPhone(subId);
3898             if (phone == null) {
3899                 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
3900                         + subId + "'");
3901                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3902             }
3903             phone.getImsRegistrationState(regState -> {
3904                 try {
3905                     consumer.accept((regState == null)
3906                             ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
3907                 } catch (RemoteException e) {
3908                     // Ignore if the remote process is no longer available to call back.
3909                     Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
3910                 }
3911             });
3912         } finally {
3913             Binder.restoreCallingIdentity(token);
3914         }
3915     }
3916 
3917     /**
3918      * Get the transport type for the IMS service registration state.
3919      */
3920     @Override
getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer)3921     public void getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer) {
3922         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3923                 mApp, subId, "getImsMmTelRegistrationTransportType");
3924         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3925             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3926                     "IMS not available on device.");
3927         }
3928         final long token = Binder.clearCallingIdentity();
3929         try {
3930             Phone phone = getPhone(subId);
3931             if (phone == null) {
3932                 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
3933                         + subId + "'");
3934                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3935             }
3936             phone.getImsRegistrationTech(regTech -> {
3937                 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
3938                 int regTechConverted = (regTech == null)
3939                         ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
3940                 regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
3941                         regTechConverted);
3942                 try {
3943                     consumer.accept(regTechConverted);
3944                 } catch (RemoteException e) {
3945                     // Ignore if the remote process is no longer available to call back.
3946                     Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
3947                 }
3948             });
3949         } finally {
3950             Binder.restoreCallingIdentity(token);
3951         }
3952     }
3953 
3954     /**
3955      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3956      * @param subId The subscription to use to check the configuration.
3957      * @param c The callback that will be used to send the result.
3958      */
3959     @Override
registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)3960     public void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)
3961             throws RemoteException {
3962         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3963                 mApp, subId, "registerMmTelCapabilityCallback");
3964         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3965             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3966                     "IMS not available on device.");
3967         }
3968         final long token = Binder.clearCallingIdentity();
3969         try {
3970             int slotId = getSlotIndexOrException(subId);
3971             verifyImsMmTelConfiguredOrThrow(slotId);
3972             ImsManager.getInstance(mApp, slotId).addCapabilitiesCallbackForSubscription(c, subId);
3973         } catch (ImsException e) {
3974             throw new ServiceSpecificException(e.getCode());
3975         } finally {
3976             Binder.restoreCallingIdentity(token);
3977         }
3978     }
3979 
3980     /**
3981      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3982      * @param subId The subscription to use to check the configuration.
3983      * @param c The callback that will be used to send the result.
3984      */
3985     @Override
unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)3986     public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
3987         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3988                 mApp, subId, "unregisterMmTelCapabilityCallback");
3989         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3990             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3991         }
3992 
3993         final long token = Binder.clearCallingIdentity();
3994         try {
3995             ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3996                         .removeCapabilitiesCallbackForSubscription(c, subId);
3997         } catch (ImsException e) {
3998             Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
3999                      + "is inactive, ignoring unregister.");
4000              // If the subscription is no longer active, just return, since the callback
4001              // will already have been removed internally.
4002         } finally {
4003             Binder.restoreCallingIdentity(token);
4004         }
4005     }
4006 
4007     @Override
isCapable(int subId, int capability, int regTech)4008     public boolean isCapable(int subId, int capability, int regTech) {
4009         enforceReadPrivilegedPermission("isCapable");
4010         final long token = Binder.clearCallingIdentity();
4011         try {
4012             int slotId = getSlotIndexOrException(subId);
4013             verifyImsMmTelConfiguredOrThrow(slotId);
4014             return ImsManager.getInstance(mApp, slotId).queryMmTelCapability(capability, regTech);
4015         } catch (com.android.ims.ImsException e) {
4016             Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
4017             return false;
4018         } catch (ImsException e) {
4019             Log.i(LOG_TAG, "isCapable: " + subId + " is inactive, returning false.");
4020             return false;
4021         } finally {
4022             Binder.restoreCallingIdentity(token);
4023         }
4024     }
4025 
4026     @Override
isAvailable(int subId, int capability, int regTech)4027     public boolean isAvailable(int subId, int capability, int regTech) {
4028         enforceReadPrivilegedPermission("isAvailable");
4029         final long token = Binder.clearCallingIdentity();
4030         try {
4031             Phone phone = getPhone(subId);
4032             if (phone == null) return false;
4033             return phone.isImsCapabilityAvailable(capability, regTech);
4034         } catch (com.android.ims.ImsException e) {
4035             Log.w(LOG_TAG, "IMS isAvailable - service unavailable: " + e.getMessage());
4036             return false;
4037         } finally {
4038             Binder.restoreCallingIdentity(token);
4039         }
4040     }
4041 
4042     /**
4043      * Determines if the MmTel feature capability is supported by the carrier configuration for this
4044      * subscription.
4045      * @param subId The subscription to use to check the configuration.
4046      * @param callback The callback that will be used to send the result.
4047      * @param capability The MmTelFeature capability that will be used to send the result.
4048      * @param transportType The transport type of the MmTelFeature capability.
4049      */
4050     @Override
isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability, int transportType)4051     public void isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability,
4052             int transportType) {
4053         enforceReadPrivilegedPermission("isMmTelCapabilitySupported");
4054         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4055             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4056                     "IMS not available on device.");
4057         }
4058         final long token = Binder.clearCallingIdentity();
4059         try {
4060             int slotId = getSlotIndex(subId);
4061             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4062                 Log.w(LOG_TAG, "isMmTelCapabilitySupported: called with an inactive subscription '"
4063                         + subId + "'");
4064                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4065             }
4066             verifyImsMmTelConfiguredOrThrow(slotId);
4067             ImsManager.getInstance(mApp, slotId).isSupported(capability,
4068                     transportType, aBoolean -> {
4069                         try {
4070                             callback.accept((aBoolean == null) ? 0 : (aBoolean ? 1 : 0));
4071                         } catch (RemoteException e) {
4072                             Log.w(LOG_TAG, "isMmTelCapabilitySupported: remote caller is not "
4073                                     + "running. Ignore");
4074                         }
4075                     });
4076         } catch (ImsException e) {
4077             throw new ServiceSpecificException(e.getCode());
4078         } finally {
4079             Binder.restoreCallingIdentity(token);
4080         }
4081     }
4082 
4083     /**
4084      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4085      * @param subId The subscription to use to check the configuration.
4086      */
4087     @Override
isAdvancedCallingSettingEnabled(int subId)4088     public boolean isAdvancedCallingSettingEnabled(int subId) {
4089         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4090                 mApp, subId, "isAdvancedCallingSettingEnabled");
4091 
4092         final long token = Binder.clearCallingIdentity();
4093         try {
4094             int slotId = getSlotIndexOrException(subId);
4095             // This setting doesn't require an active ImsService connection, so do not verify.
4096             return ImsManager.getInstance(mApp, slotId).isEnhanced4gLteModeSettingEnabledByUser();
4097         } catch (ImsException e) {
4098             throw new ServiceSpecificException(e.getCode());
4099         } finally {
4100             Binder.restoreCallingIdentity(token);
4101         }
4102     }
4103 
4104     @Override
setAdvancedCallingSettingEnabled(int subId, boolean isEnabled)4105     public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
4106         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4107                 "setAdvancedCallingSettingEnabled");
4108         final long identity = Binder.clearCallingIdentity();
4109         try {
4110             int slotId = getSlotIndexOrException(subId);
4111             // This setting doesn't require an active ImsService connection, so do not verify. The
4112             // new setting will be picked up when the ImsService comes up next if it isn't up.
4113             ImsManager.getInstance(mApp, slotId).setEnhanced4gLteModeSetting(isEnabled);
4114         } catch (ImsException e) {
4115             throw new ServiceSpecificException(e.getCode());
4116         } finally {
4117             Binder.restoreCallingIdentity(identity);
4118         }
4119     }
4120 
4121     /**
4122      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4123      * @param subId The subscription to use to check the configuration.
4124      */
4125     @Override
isVtSettingEnabled(int subId)4126     public boolean isVtSettingEnabled(int subId) {
4127         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4128                 mApp, subId, "isVtSettingEnabled");
4129         final long identity = Binder.clearCallingIdentity();
4130         try {
4131             int slotId = getSlotIndexOrException(subId);
4132             // This setting doesn't require an active ImsService connection, so do not verify.
4133             return ImsManager.getInstance(mApp, slotId).isVtEnabledByUser();
4134         } catch (ImsException e) {
4135             throw new ServiceSpecificException(e.getCode());
4136         } finally {
4137             Binder.restoreCallingIdentity(identity);
4138         }
4139     }
4140 
4141     @Override
setVtSettingEnabled(int subId, boolean isEnabled)4142     public void setVtSettingEnabled(int subId, boolean isEnabled) {
4143         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4144                 "setVtSettingEnabled");
4145         final long identity = Binder.clearCallingIdentity();
4146         try {
4147             int slotId = getSlotIndexOrException(subId);
4148             // This setting doesn't require an active ImsService connection, so do not verify. The
4149             // new setting will be picked up when the ImsService comes up next if it isn't up.
4150             ImsManager.getInstance(mApp, slotId).setVtSetting(isEnabled);
4151         } catch (ImsException e) {
4152             throw new ServiceSpecificException(e.getCode());
4153         } finally {
4154             Binder.restoreCallingIdentity(identity);
4155         }
4156     }
4157 
4158     /**
4159      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4160      * @param subId The subscription to use to check the configuration.
4161      */
4162     @Override
isVoWiFiSettingEnabled(int subId)4163     public boolean isVoWiFiSettingEnabled(int subId) {
4164         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4165                 mApp, subId, "isVoWiFiSettingEnabled");
4166         final long identity = Binder.clearCallingIdentity();
4167         try {
4168             int slotId = getSlotIndexOrException(subId);
4169             // This setting doesn't require an active ImsService connection, so do not verify.
4170             return ImsManager.getInstance(mApp, slotId).isWfcEnabledByUser();
4171         } catch (ImsException e) {
4172             throw new ServiceSpecificException(e.getCode());
4173         } finally {
4174             Binder.restoreCallingIdentity(identity);
4175         }
4176     }
4177 
4178     @Override
setVoWiFiSettingEnabled(int subId, boolean isEnabled)4179     public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
4180         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4181                 "setVoWiFiSettingEnabled");
4182         final long identity = Binder.clearCallingIdentity();
4183         try {
4184             int slotId = getSlotIndexOrException(subId);
4185             // This setting doesn't require an active ImsService connection, so do not verify. The
4186             // new setting will be picked up when the ImsService comes up next if it isn't up.
4187             ImsManager.getInstance(mApp, slotId).setWfcSetting(isEnabled);
4188         } catch (ImsException e) {
4189             throw new ServiceSpecificException(e.getCode());
4190         } finally {
4191             Binder.restoreCallingIdentity(identity);
4192         }
4193     }
4194 
4195     /**
4196      * @return true if the user's setting for Voice over Cross SIM is enabled and false if it is not
4197      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4198      * @param subId The subscription to use to check the configuration.
4199      */
4200     @Override
isCrossSimCallingEnabledByUser(int subId)4201     public boolean isCrossSimCallingEnabledByUser(int subId) {
4202         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4203                 mApp, subId, "isCrossSimCallingEnabledByUser");
4204         final long identity = Binder.clearCallingIdentity();
4205         try {
4206             int slotId = getSlotIndexOrException(subId);
4207             // This setting doesn't require an active ImsService connection, so do not verify.
4208             return ImsManager.getInstance(mApp, slotId).isCrossSimCallingEnabledByUser();
4209         } catch (ImsException e) {
4210             throw new ServiceSpecificException(e.getCode());
4211         } finally {
4212             Binder.restoreCallingIdentity(identity);
4213         }
4214     }
4215 
4216     /**
4217      * Sets the user's setting for whether or not Voice over Cross SIM is enabled.
4218      * Requires MODIFY_PHONE_STATE permission.
4219      * @param subId The subscription to use to check the configuration.
4220      * @param isEnabled true if the user's setting for Voice over Cross SIM is enabled,
4221      *                 false otherwise
4222      */
4223     @Override
setCrossSimCallingEnabled(int subId, boolean isEnabled)4224     public void setCrossSimCallingEnabled(int subId, boolean isEnabled) {
4225         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4226                 "setCrossSimCallingEnabled");
4227         final long identity = Binder.clearCallingIdentity();
4228         try {
4229             int slotId = getSlotIndexOrException(subId);
4230             // This setting doesn't require an active ImsService connection, so do not verify. The
4231             // new setting will be picked up when the ImsService comes up next if it isn't up.
4232             ImsManager.getInstance(mApp, slotId).setCrossSimCallingEnabled(isEnabled);
4233         } catch (ImsException e) {
4234             throw new ServiceSpecificException(e.getCode());
4235         } finally {
4236             Binder.restoreCallingIdentity(identity);
4237         }
4238     }
4239 
4240     /**
4241      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4242      * @param subId The subscription to use to check the configuration.
4243      */
4244     @Override
4245 
isVoWiFiRoamingSettingEnabled(int subId)4246     public boolean isVoWiFiRoamingSettingEnabled(int subId) {
4247         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4248                 mApp, subId, "isVoWiFiRoamingSettingEnabled");
4249         final long identity = Binder.clearCallingIdentity();
4250         try {
4251             int slotId = getSlotIndexOrException(subId);
4252             // This setting doesn't require an active ImsService connection, so do not verify.
4253             return ImsManager.getInstance(mApp, slotId).isWfcRoamingEnabledByUser();
4254         } catch (ImsException e) {
4255             throw new ServiceSpecificException(e.getCode());
4256         } finally {
4257             Binder.restoreCallingIdentity(identity);
4258         }
4259     }
4260 
4261     @Override
setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled)4262     public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
4263         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4264                 "setVoWiFiRoamingSettingEnabled");
4265         final long identity = Binder.clearCallingIdentity();
4266         try {
4267             int slotId = getSlotIndexOrException(subId);
4268             // This setting doesn't require an active ImsService connection, so do not verify. The
4269             // new setting will be picked up when the ImsService comes up next if it isn't up.
4270             ImsManager.getInstance(mApp, slotId).setWfcRoamingSetting(isEnabled);
4271         } catch (ImsException e) {
4272             throw new ServiceSpecificException(e.getCode());
4273         } finally {
4274             Binder.restoreCallingIdentity(identity);
4275         }
4276     }
4277 
4278     @Override
setVoWiFiNonPersistent(int subId, boolean isCapable, int mode)4279     public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
4280         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4281                 "setVoWiFiNonPersistent");
4282         final long identity = Binder.clearCallingIdentity();
4283         try {
4284             int slotId = getSlotIndexOrException(subId);
4285             // This setting will be ignored if the ImsService isn't up.
4286             ImsManager.getInstance(mApp, slotId).setWfcNonPersistent(isCapable, mode);
4287         } catch (ImsException e) {
4288             throw new ServiceSpecificException(e.getCode());
4289         } finally {
4290             Binder.restoreCallingIdentity(identity);
4291         }
4292     }
4293 
4294     /**
4295      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4296      * @param subId The subscription to use to check the configuration.
4297      */
4298     @Override
getVoWiFiModeSetting(int subId)4299     public int getVoWiFiModeSetting(int subId) {
4300         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4301                 mApp, subId, "getVoWiFiModeSetting");
4302         final long identity = Binder.clearCallingIdentity();
4303         try {
4304             int slotId = getSlotIndexOrException(subId);
4305             // This setting doesn't require an active ImsService connection, so do not verify.
4306             return ImsManager.getInstance(mApp, slotId).getWfcMode(false /*isRoaming*/);
4307         } catch (ImsException e) {
4308             throw new ServiceSpecificException(e.getCode());
4309         } finally {
4310             Binder.restoreCallingIdentity(identity);
4311         }
4312     }
4313 
4314     @Override
setVoWiFiModeSetting(int subId, int mode)4315     public void setVoWiFiModeSetting(int subId, int mode) {
4316         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4317                 "setVoWiFiModeSetting");
4318         final long identity = Binder.clearCallingIdentity();
4319         try {
4320             int slotId = getSlotIndexOrException(subId);
4321             // This setting doesn't require an active ImsService connection, so do not verify. The
4322             // new setting will be picked up when the ImsService comes up next if it isn't up.
4323             ImsManager.getInstance(mApp, slotId).setWfcMode(mode, false /*isRoaming*/);
4324         } catch (ImsException e) {
4325             throw new ServiceSpecificException(e.getCode());
4326         } finally {
4327             Binder.restoreCallingIdentity(identity);
4328         }
4329     }
4330 
4331     @Override
getVoWiFiRoamingModeSetting(int subId)4332     public int getVoWiFiRoamingModeSetting(int subId) {
4333         enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
4334         final long identity = Binder.clearCallingIdentity();
4335         try {
4336             int slotId = getSlotIndexOrException(subId);
4337             // This setting doesn't require an active ImsService connection, so do not verify.
4338             return ImsManager.getInstance(mApp, slotId).getWfcMode(true /*isRoaming*/);
4339         } catch (ImsException e) {
4340             throw new ServiceSpecificException(e.getCode());
4341         } finally {
4342             Binder.restoreCallingIdentity(identity);
4343         }
4344     }
4345 
4346     @Override
setVoWiFiRoamingModeSetting(int subId, int mode)4347     public void setVoWiFiRoamingModeSetting(int subId, int mode) {
4348         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4349                 "setVoWiFiRoamingModeSetting");
4350         final long identity = Binder.clearCallingIdentity();
4351         try {
4352             int slotId = getSlotIndexOrException(subId);
4353             // This setting doesn't require an active ImsService connection, so do not verify. The
4354             // new setting will be picked up when the ImsService comes up next if it isn't up.
4355             ImsManager.getInstance(mApp, slotId).setWfcMode(mode, true /*isRoaming*/);
4356         } catch (ImsException e) {
4357             throw new ServiceSpecificException(e.getCode());
4358         } finally {
4359             Binder.restoreCallingIdentity(identity);
4360         }
4361     }
4362 
4363     @Override
setRttCapabilitySetting(int subId, boolean isEnabled)4364     public void setRttCapabilitySetting(int subId, boolean isEnabled) {
4365         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4366                 "setRttCapabilityEnabled");
4367         final long identity = Binder.clearCallingIdentity();
4368         try {
4369             int slotId = getSlotIndexOrException(subId);
4370             // This setting doesn't require an active ImsService connection, so do not verify. The
4371             // new setting will be picked up when the ImsService comes up next if it isn't up.
4372             ImsManager.getInstance(mApp, slotId).setRttEnabled(isEnabled);
4373         } catch (ImsException e) {
4374             throw new ServiceSpecificException(e.getCode());
4375         } finally {
4376             Binder.restoreCallingIdentity(identity);
4377         }
4378     }
4379 
4380     /**
4381      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4382      * @param subId The subscription to use to check the configuration.
4383      */
4384     @Override
isTtyOverVolteEnabled(int subId)4385     public boolean isTtyOverVolteEnabled(int subId) {
4386         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4387                 mApp, subId, "isTtyOverVolteEnabled");
4388         final long identity = Binder.clearCallingIdentity();
4389         try {
4390             int slotId = getSlotIndexOrException(subId);
4391             // This setting doesn't require an active ImsService connection, so do not verify.
4392             return ImsManager.getInstance(mApp, slotId).isTtyOnVoLteCapable();
4393         } catch (ImsException e) {
4394             throw new ServiceSpecificException(e.getCode());
4395         } finally {
4396             Binder.restoreCallingIdentity(identity);
4397         }
4398     }
4399 
4400     @Override
registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback)4401     public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
4402         enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
4403         final long identity = Binder.clearCallingIdentity();
4404         try {
4405             if (!isImsAvailableOnDevice()) {
4406                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4407                         "IMS not available on device.");
4408             }
4409             int slotId = getSlotIndexOrException(subId);
4410             verifyImsMmTelConfiguredOrThrow(slotId);
4411             ImsManager.getInstance(mApp, slotId)
4412                     .addProvisioningCallbackForSubscription(callback, subId);
4413         } catch (ImsException e) {
4414             throw new ServiceSpecificException(e.getCode());
4415         } finally {
4416             Binder.restoreCallingIdentity(identity);
4417         }
4418     }
4419 
4420     @Override
unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback)4421     public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
4422         enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
4423         final long identity = Binder.clearCallingIdentity();
4424         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4425             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
4426         }
4427         try {
4428             ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
4429                     .removeProvisioningCallbackForSubscription(callback, subId);
4430         } catch (ImsException e) {
4431             Log.i(LOG_TAG, "unregisterImsProvisioningChangedCallback: " + subId
4432                     + "is inactive, ignoring unregister.");
4433             // If the subscription is no longer active, just return, since the callback will already
4434             // have been removed internally.
4435         } finally {
4436             Binder.restoreCallingIdentity(identity);
4437         }
4438     }
4439 
4440 
checkModifyPhoneStatePermission(int subId, String message)4441     private void checkModifyPhoneStatePermission(int subId, String message) {
4442         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4443                 message);
4444     }
4445 
isImsProvisioningRequired(int subId, int capability, boolean isMmtelCapability)4446     private boolean isImsProvisioningRequired(int subId, int capability,
4447             boolean isMmtelCapability) {
4448         Phone phone = getPhone(subId);
4449         if (phone == null) {
4450             loge("phone instance null for subid " + subId);
4451             return false;
4452         }
4453         if (isMmtelCapability) {
4454             if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
4455                 return false;
4456             }
4457         } else {
4458             if (!doesRcsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
4459                 return false;
4460             }
4461         }
4462         return true;
4463     }
4464 
4465     @Override
setRcsProvisioningStatusForCapability(int subId, int capability, boolean isProvisioned)4466     public void setRcsProvisioningStatusForCapability(int subId, int capability,
4467             boolean isProvisioned) {
4468         checkModifyPhoneStatePermission(subId, "setRcsProvisioningStatusForCapability");
4469 
4470         final long identity = Binder.clearCallingIdentity();
4471         try {
4472             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4473             if (!isImsProvisioningRequired(subId, capability, false)) {
4474                 return;
4475             }
4476 
4477             // this capability requires provisioning, route to the correct API.
4478             ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4479             switch (capability) {
4480                 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
4481                 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
4482                     ims.setEabProvisioned(isProvisioned);
4483                     break;
4484                 default: {
4485                     throw new IllegalArgumentException("Tried to set provisioning for "
4486                             + "rcs capability '" + capability + "', which does not require "
4487                             + "provisioning.");
4488                 }
4489             }
4490         } finally {
4491             Binder.restoreCallingIdentity(identity);
4492         }
4493 
4494     }
4495 
4496 
4497     @Override
getRcsProvisioningStatusForCapability(int subId, int capability)4498     public boolean getRcsProvisioningStatusForCapability(int subId, int capability) {
4499         enforceReadPrivilegedPermission("getRcsProvisioningStatusForCapability");
4500         final long identity = Binder.clearCallingIdentity();
4501         try {
4502             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4503             if (!isImsProvisioningRequired(subId, capability, false)) {
4504                 return true;
4505             }
4506 
4507             ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4508             switch (capability) {
4509                 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
4510                 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
4511                     return ims.isEabProvisionedOnDevice();
4512 
4513                 default: {
4514                     throw new IllegalArgumentException("Tried to get rcs provisioning for "
4515                             + "capability '" + capability + "', which does not require "
4516                             + "provisioning.");
4517                 }
4518             }
4519 
4520         } finally {
4521             Binder.restoreCallingIdentity(identity);
4522         }
4523     }
4524 
4525     @Override
setImsProvisioningStatusForCapability(int subId, int capability, int tech, boolean isProvisioned)4526     public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
4527             boolean isProvisioned) {
4528         if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4529                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE
4530                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_NR
4531                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM) {
4532             throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4533         }
4534         checkModifyPhoneStatePermission(subId, "setImsProvisioningStatusForCapability");
4535         final long identity = Binder.clearCallingIdentity();
4536         try {
4537             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4538             if (!isImsProvisioningRequired(subId, capability, true)) {
4539                 return;
4540             }
4541             if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_NR
4542                     || tech == ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM) {
4543                 loge("setImsProvisioningStatusForCapability: called for technology that does "
4544                         + "not support provisioning - " + tech);
4545                 return;
4546             }
4547 
4548             // this capability requires provisioning, route to the correct API.
4549             ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4550             switch (capability) {
4551                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
4552                     if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4553                         ims.setVolteProvisioned(isProvisioned);
4554                     } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
4555                         ims.setWfcProvisioned(isProvisioned);
4556                     }
4557                     break;
4558                 }
4559                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
4560                     // There is currently no difference in VT provisioning type.
4561                     ims.setVtProvisioned(isProvisioned);
4562                     break;
4563                 }
4564                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
4565                     // There is no "deprecated" UT provisioning mechanism through ImsConfig, so
4566                     // change the capability of the feature instead if needed.
4567                     if (isMmTelCapabilityProvisionedInCache(subId, capability, tech)
4568                             == isProvisioned) {
4569                         // No change in provisioning.
4570                         return;
4571                     }
4572                     cacheMmTelCapabilityProvisioning(subId, capability, tech, isProvisioned);
4573                     try {
4574                         ims.changeMmTelCapability(isProvisioned, capability, tech);
4575                     } catch (com.android.ims.ImsException e) {
4576                         loge("setImsProvisioningStatusForCapability: couldn't change UT capability"
4577                                 + ", Exception" + e.getMessage());
4578                     }
4579                     break;
4580                 }
4581                 default: {
4582                     throw new IllegalArgumentException("Tried to set provisioning for "
4583                             + "MmTel capability '" + capability + "', which does not require "
4584                             + "provisioning. ");
4585                 }
4586             }
4587 
4588         } finally {
4589             Binder.restoreCallingIdentity(identity);
4590         }
4591     }
4592 
4593     @Override
getImsProvisioningStatusForCapability(int subId, int capability, int tech)4594     public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
4595         if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4596                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE
4597                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_NR
4598                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM) {
4599             throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4600         }
4601         enforceReadPrivilegedPermission("getProvisioningStatusForCapability");
4602         final long identity = Binder.clearCallingIdentity();
4603         try {
4604             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4605             if (!isImsProvisioningRequired(subId, capability, true)) {
4606                 return true;
4607             }
4608 
4609             if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_NR
4610                     || tech == ImsRegistrationImplBase.REGISTRATION_TECH_CROSS_SIM) {
4611                 loge("getImsProvisioningStatusForCapability: called for technology that does "
4612                         + "not support provisioning - " + tech);
4613                 return true;
4614             }
4615 
4616             ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
4617             switch (capability) {
4618                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
4619                     if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4620                         return ims.isVolteProvisionedOnDevice();
4621                     } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
4622                         return ims.isWfcProvisionedOnDevice();
4623                     }
4624                     // This should never happen, since we are checking tech above to make sure it
4625                     // is either LTE or IWLAN.
4626                     throw new IllegalArgumentException("Invalid radio technology for voice "
4627                             + "capability.");
4628                 }
4629                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
4630                     // There is currently no difference in VT provisioning type.
4631                     return ims.isVtProvisionedOnDevice();
4632                 }
4633                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
4634                     // There is no "deprecated" UT provisioning mechanism, so get from shared prefs.
4635                     return isMmTelCapabilityProvisionedInCache(subId, capability, tech);
4636                 }
4637                 default: {
4638                     throw new IllegalArgumentException(
4639                             "Tried to get provisioning for MmTel capability '" + capability
4640                                     + "', which does not require provisioning.");
4641                 }
4642             }
4643 
4644         } finally {
4645             Binder.restoreCallingIdentity(identity);
4646         }
4647     }
4648 
4649     @Override
isMmTelCapabilityProvisionedInCache(int subId, int capability, int tech)4650     public boolean isMmTelCapabilityProvisionedInCache(int subId, int capability, int tech) {
4651         if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4652                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4653             throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4654         }
4655         enforceReadPrivilegedPermission("isMmTelCapabilityProvisionedInCache");
4656         int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
4657         return (provisionedBits & capability) > 0;
4658     }
4659 
4660     @Override
cacheMmTelCapabilityProvisioning(int subId, int capability, int tech, boolean isProvisioned)4661     public void cacheMmTelCapabilityProvisioning(int subId, int capability, int tech,
4662             boolean isProvisioned) {
4663         if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4664                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4665             throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4666         }
4667         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4668                 "setProvisioningStatusForCapability");
4669         int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
4670         // If the current provisioning status for capability already matches isProvisioned,
4671         // do nothing.
4672         if (((provisionedBits & capability) > 0) == isProvisioned) {
4673             return;
4674         }
4675         if (isProvisioned) {
4676             setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits | capability));
4677         } else {
4678             setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits & ~capability));
4679         }
4680     }
4681 
4682     /**
4683      * @return the bitfield containing the MmTel provisioning for the provided subscription and
4684      * technology. The bitfield should mirror the bitfield defined by
4685      * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}.
4686      */
getMmTelCapabilityProvisioningBitfield(int subId, int tech)4687     private int getMmTelCapabilityProvisioningBitfield(int subId, int tech) {
4688         String key = getMmTelProvisioningKey(subId, tech);
4689         // Default is no capabilities are provisioned.
4690         return mTelephonySharedPreferences.getInt(key, 0 /*default*/);
4691     }
4692 
4693     /**
4694      * Sets the MmTel capability provisioning bitfield (defined by
4695      *     {@link MmTelFeature.MmTelCapabilities.MmTelCapability}) for the subscription and
4696      *     technology specified.
4697      *
4698      * Note: This is a synchronous command and should not be called on UI thread.
4699      */
setMmTelCapabilityProvisioningBitfield(int subId, int tech, int newField)4700     private void setMmTelCapabilityProvisioningBitfield(int subId, int tech, int newField) {
4701         final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
4702         String key = getMmTelProvisioningKey(subId, tech);
4703         editor.putInt(key, newField);
4704         editor.commit();
4705     }
4706 
getMmTelProvisioningKey(int subId, int tech)4707     private static String getMmTelProvisioningKey(int subId, int tech) {
4708         // resulting key is provision_ims_mmtel_{subId}_{tech}
4709         return PREF_PROVISION_IMS_MMTEL_PREFIX + subId + "_" + tech;
4710     }
4711 
4712     /**
4713      * Query CarrierConfig to see if the specified capability requires provisioning for the
4714      * carrier associated with the subscription id.
4715      */
doesImsCapabilityRequireProvisioning(Context context, int subId, int capability)4716     private boolean doesImsCapabilityRequireProvisioning(Context context, int subId,
4717             int capability) {
4718         CarrierConfigManager configManager = new CarrierConfigManager(context);
4719         PersistableBundle c = configManager.getConfigForSubId(subId);
4720         boolean requireUtProvisioning = c.getBoolean(
4721                 CarrierConfigManager.KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, false)
4722                 && c.getBoolean(CarrierConfigManager.KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL,
4723                 false);
4724         boolean requireVoiceVtProvisioning = c.getBoolean(
4725                 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
4726 
4727         // First check to make sure that the capability requires provisioning.
4728         switch (capability) {
4729             case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE:
4730                 // intentional fallthrough
4731             case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
4732                 if (requireVoiceVtProvisioning) {
4733                     // Voice and Video requires provisioning
4734                     return true;
4735                 }
4736                 break;
4737             }
4738             case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
4739                 if (requireUtProvisioning) {
4740                     // UT requires provisioning
4741                     return true;
4742                 }
4743                 break;
4744             }
4745         }
4746         return false;
4747     }
4748 
doesRcsCapabilityRequireProvisioning(Context context, int subId, int capability)4749     private boolean doesRcsCapabilityRequireProvisioning(Context context, int subId,
4750             int capability) {
4751         CarrierConfigManager configManager = new CarrierConfigManager(context);
4752         PersistableBundle c = configManager.getConfigForSubId(subId);
4753 
4754         boolean requireRcsProvisioning = c.getBoolean(
4755                 CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, false);
4756 
4757         // First check to make sure that the capability requires provisioning.
4758         switch (capability) {
4759             case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
4760                 // intentional fallthrough
4761             case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE: {
4762                 if (requireRcsProvisioning) {
4763                     // OPTION or PRESENCE requires provisioning
4764                     return true;
4765                 }
4766                 break;
4767             }
4768         }
4769         return false;
4770     }
4771 
4772     @Override
getImsProvisioningInt(int subId, int key)4773     public int getImsProvisioningInt(int subId, int key) {
4774         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4775             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4776         }
4777         enforceReadPrivilegedPermission("getImsProvisioningInt");
4778         final long identity = Binder.clearCallingIdentity();
4779         try {
4780             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4781             int slotId = getSlotIndex(subId);
4782             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4783                 Log.w(LOG_TAG, "getImsProvisioningInt: called with an inactive subscription '"
4784                         + subId + "' for key:" + key);
4785                 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
4786             }
4787             return ImsManager.getInstance(mApp, slotId).getConfigInt(key);
4788         } catch (com.android.ims.ImsException e) {
4789             Log.w(LOG_TAG, "getImsProvisioningInt: ImsService is not available for subscription '"
4790                     + subId + "' for key:" + key);
4791             return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
4792         } finally {
4793             Binder.restoreCallingIdentity(identity);
4794         }
4795     }
4796 
4797     @Override
getImsProvisioningString(int subId, int key)4798     public String getImsProvisioningString(int subId, int key) {
4799         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4800             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4801         }
4802         enforceReadPrivilegedPermission("getImsProvisioningString");
4803         final long identity = Binder.clearCallingIdentity();
4804         try {
4805             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4806             int slotId = getSlotIndex(subId);
4807             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4808                 Log.w(LOG_TAG, "getImsProvisioningString: called for an inactive subscription id '"
4809                         + subId + "' for key:" + key);
4810                 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_GENERIC;
4811             }
4812             return ImsManager.getInstance(mApp, slotId).getConfigString(key);
4813         } catch (com.android.ims.ImsException e) {
4814             Log.w(LOG_TAG, "getImsProvisioningString: ImsService is not available for sub '"
4815                     + subId + "' for key:" + key);
4816             return ProvisioningManager.STRING_QUERY_RESULT_ERROR_NOT_READY;
4817         } finally {
4818             Binder.restoreCallingIdentity(identity);
4819         }
4820     }
4821 
4822     @Override
setImsProvisioningInt(int subId, int key, int value)4823     public int setImsProvisioningInt(int subId, int key, int value) {
4824         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4825             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4826         }
4827         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4828                 "setImsProvisioningInt");
4829         final long identity = Binder.clearCallingIdentity();
4830         try {
4831             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4832             int slotId = getSlotIndex(subId);
4833             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4834                 Log.w(LOG_TAG, "setImsProvisioningInt: called with an inactive subscription id '"
4835                         + subId + "' for key:" + key);
4836                 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4837             }
4838             return ImsManager.getInstance(mApp, slotId).setConfig(key, value);
4839         } catch (com.android.ims.ImsException | RemoteException e) {
4840             Log.w(LOG_TAG, "setImsProvisioningInt: ImsService unavailable for sub '" + subId
4841                     + "' for key:" + key, e);
4842             return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4843         } finally {
4844             Binder.restoreCallingIdentity(identity);
4845         }
4846     }
4847 
4848     @Override
setImsProvisioningString(int subId, int key, String value)4849     public int setImsProvisioningString(int subId, int key, String value) {
4850         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4851             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4852         }
4853         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4854                 "setImsProvisioningString");
4855         final long identity = Binder.clearCallingIdentity();
4856         try {
4857             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4858             int slotId = getSlotIndex(subId);
4859             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4860                 Log.w(LOG_TAG, "setImsProvisioningString: called with an inactive subscription id '"
4861                         + subId + "' for key:" + key);
4862                 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4863             }
4864             return ImsManager.getInstance(mApp, slotId).setConfig(key, value);
4865         } catch (com.android.ims.ImsException | RemoteException e) {
4866             Log.w(LOG_TAG, "setImsProvisioningString: ImsService unavailable for sub '" + subId
4867                     + "' for key:" + key, e);
4868             return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4869         } finally {
4870             Binder.restoreCallingIdentity(identity);
4871         }
4872     }
4873 
4874     /**
4875      * Throw an ImsException if the IMS resolver does not have an ImsService configured for MMTEL
4876      * for the given slot ID or no ImsResolver instance has been created.
4877      * @param slotId The slot ID that the IMS service is created for.
4878      * @throws ImsException If there is no ImsService configured for this slot.
4879      */
verifyImsMmTelConfiguredOrThrow(int slotId)4880     private void verifyImsMmTelConfiguredOrThrow(int slotId) throws ImsException {
4881         if (mImsResolver == null || !mImsResolver.isImsServiceConfiguredForFeature(slotId,
4882                 ImsFeature.FEATURE_MMTEL)) {
4883             throw new ImsException("This subscription does not support MMTEL over IMS",
4884                     ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
4885         }
4886     }
4887 
getSlotIndexOrException(int subId)4888     private int getSlotIndexOrException(int subId) throws ImsException {
4889         int slotId = SubscriptionManager.getSlotIndex(subId);
4890         if (!SubscriptionManager.isValidSlotIndex(slotId)) {
4891             throw new ImsException("Invalid Subscription Id, subId=" + subId,
4892                     ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4893         }
4894         return slotId;
4895     }
4896 
getSlotIndex(int subId)4897     private int getSlotIndex(int subId) {
4898         int slotId = SubscriptionManager.getSlotIndex(subId);
4899         if (!SubscriptionManager.isValidSlotIndex(slotId)) {
4900             return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
4901         }
4902         return slotId;
4903     }
4904 
4905     /**
4906      * Returns the data network type for a subId; does not throw SecurityException.
4907      */
4908     @Override
getNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId)4909     public int getNetworkTypeForSubscriber(int subId, String callingPackage,
4910             String callingFeatureId) {
4911         final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
4912         if (targetSdk > android.os.Build.VERSION_CODES.Q) {
4913             return getDataNetworkTypeForSubscriber(subId, callingPackage, callingFeatureId);
4914         } else if (targetSdk == android.os.Build.VERSION_CODES.Q
4915                 && !TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
4916                         mApp, subId, callingPackage, callingFeatureId,
4917                 "getNetworkTypeForSubscriber")) {
4918             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4919         }
4920 
4921         final long identity = Binder.clearCallingIdentity();
4922         try {
4923             final Phone phone = getPhone(subId);
4924             if (phone != null) {
4925                 return phone.getServiceState().getDataNetworkType();
4926             } else {
4927                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4928             }
4929         } finally {
4930             Binder.restoreCallingIdentity(identity);
4931         }
4932     }
4933 
4934     /**
4935      * Returns the data network type
4936      */
4937     @Override
getDataNetworkType(String callingPackage, String callingFeatureId)4938     public int getDataNetworkType(String callingPackage, String callingFeatureId) {
4939         return getDataNetworkTypeForSubscriber(mSubscriptionController.getDefaultDataSubId(),
4940                 callingPackage, callingFeatureId);
4941     }
4942 
4943     /**
4944      * Returns the data network type for a subId
4945      */
4946     @Override
getDataNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId)4947     public int getDataNetworkTypeForSubscriber(int subId, String callingPackage,
4948             String callingFeatureId) {
4949         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4950                 mApp, subId, callingPackage, callingFeatureId,
4951                 "getDataNetworkTypeForSubscriber")) {
4952             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4953         }
4954 
4955         final long identity = Binder.clearCallingIdentity();
4956         try {
4957             final Phone phone = getPhone(subId);
4958             if (phone != null) {
4959                 return phone.getServiceState().getDataNetworkType();
4960             } else {
4961                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4962             }
4963         } finally {
4964             Binder.restoreCallingIdentity(identity);
4965         }
4966     }
4967 
4968     /**
4969      * Returns the Voice network type for a subId
4970      */
4971     @Override
getVoiceNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId)4972     public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage,
4973             String callingFeatureId) {
4974         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4975                 mApp, subId, callingPackage, callingFeatureId,
4976                 "getDataNetworkTypeForSubscriber")) {
4977             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4978         }
4979 
4980         final long identity = Binder.clearCallingIdentity();
4981         try {
4982             final Phone phone = getPhone(subId);
4983             if (phone != null) {
4984                 return phone.getServiceState().getVoiceNetworkType();
4985             } else {
4986                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4987             }
4988         } finally {
4989             Binder.restoreCallingIdentity(identity);
4990         }
4991     }
4992 
4993     /**
4994      * @return true if a ICC card is present
4995      */
hasIccCard()4996     public boolean hasIccCard() {
4997         // FIXME Make changes to pass defaultSimId of type int
4998         return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
4999                 getDefaultSubscription()));
5000     }
5001 
5002     /**
5003      * @return true if a ICC card is present for a slotIndex
5004      */
5005     @Override
hasIccCardUsingSlotIndex(int slotIndex)5006     public boolean hasIccCardUsingSlotIndex(int slotIndex) {
5007         final long identity = Binder.clearCallingIdentity();
5008         try {
5009             final Phone phone = PhoneFactory.getPhone(slotIndex);
5010             if (phone != null) {
5011                 return phone.getIccCard().hasIccCard();
5012             } else {
5013                 return false;
5014             }
5015         } finally {
5016             Binder.restoreCallingIdentity(identity);
5017         }
5018     }
5019 
5020     /**
5021      * Return if the current radio is LTE on CDMA. This
5022      * is a tri-state return value as for a period of time
5023      * the mode may be unknown.
5024      *
5025      * @param callingPackage the name of the package making the call.
5026      * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
5027      * or {@link Phone#LTE_ON_CDMA_TRUE}
5028      */
5029     @Override
getLteOnCdmaMode(String callingPackage, String callingFeatureId)5030     public int getLteOnCdmaMode(String callingPackage, String callingFeatureId) {
5031         return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage,
5032                 callingFeatureId);
5033     }
5034 
5035     @Override
getLteOnCdmaModeForSubscriber(int subId, String callingPackage, String callingFeatureId)5036     public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage,
5037             String callingFeatureId) {
5038         try {
5039             enforceReadPrivilegedPermission("getLteOnCdmaModeForSubscriber");
5040         } catch (SecurityException e) {
5041             return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
5042         }
5043 
5044         final long identity = Binder.clearCallingIdentity();
5045         try {
5046             final Phone phone = getPhone(subId);
5047             if (phone == null) {
5048                 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
5049             } else {
5050                 return TelephonyProperties.lte_on_cdma_device()
5051                         .orElse(PhoneConstants.LTE_ON_CDMA_FALSE);
5052             }
5053         } finally {
5054             Binder.restoreCallingIdentity(identity);
5055         }
5056     }
5057 
5058     /**
5059      * {@hide}
5060      * Returns Default subId, 0 in the case of single standby.
5061      */
getDefaultSubscription()5062     private int getDefaultSubscription() {
5063         return mSubscriptionController.getDefaultSubId();
5064     }
5065 
getSlotForDefaultSubscription()5066     private int getSlotForDefaultSubscription() {
5067         return mSubscriptionController.getPhoneId(getDefaultSubscription());
5068     }
5069 
getPreferredVoiceSubscription()5070     private int getPreferredVoiceSubscription() {
5071         return mSubscriptionController.getDefaultVoiceSubId();
5072     }
5073 
isActiveSubscription(int subId)5074     private boolean isActiveSubscription(int subId) {
5075         return mSubscriptionController.isActiveSubId(subId);
5076     }
5077 
5078     /**
5079      * @see android.telephony.TelephonyManager.WifiCallingChoices
5080      */
getWhenToMakeWifiCalls()5081     public int getWhenToMakeWifiCalls() {
5082         final long identity = Binder.clearCallingIdentity();
5083         try {
5084             return Settings.System.getInt(mApp.getContentResolver(),
5085                     Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
5086                     getWhenToMakeWifiCallsDefaultPreference());
5087         } finally {
5088             Binder.restoreCallingIdentity(identity);
5089         }
5090     }
5091 
5092     /**
5093      * @see android.telephony.TelephonyManager.WifiCallingChoices
5094      */
setWhenToMakeWifiCalls(int preference)5095     public void setWhenToMakeWifiCalls(int preference) {
5096         final long identity = Binder.clearCallingIdentity();
5097         try {
5098             if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
5099             Settings.System.putInt(mApp.getContentResolver(),
5100                     Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
5101         } finally {
5102             Binder.restoreCallingIdentity(identity);
5103         }
5104     }
5105 
getWhenToMakeWifiCallsDefaultPreference()5106     private static int getWhenToMakeWifiCallsDefaultPreference() {
5107         // TODO: Use a build property to choose this value.
5108         return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
5109     }
5110 
getPhoneFromSlotIdOrThrowException(int slotIndex)5111     private Phone getPhoneFromSlotIdOrThrowException(int slotIndex) {
5112         int phoneId = UiccController.getInstance().getPhoneIdFromSlotId(slotIndex);
5113         if (phoneId == -1) {
5114             throw new IllegalArgumentException("Given slot index: " + slotIndex
5115                     + " does not correspond to an active phone");
5116         }
5117         return PhoneFactory.getPhone(phoneId);
5118     }
5119 
5120     @Override
iccOpenLogicalChannel( int subId, String callingPackage, String aid, int p2)5121     public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
5122             int subId, String callingPackage, String aid, int p2) {
5123         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5124                 mApp, subId, "iccOpenLogicalChannel");
5125         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5126         if (DBG) {
5127             log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
5128         }
5129         return iccOpenLogicalChannelWithPermission(getPhoneFromSubId(subId), callingPackage, aid,
5130                 p2);
5131     }
5132 
5133 
5134     @Override
iccOpenLogicalChannelBySlot( int slotIndex, String callingPackage, String aid, int p2)5135     public IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(
5136             int slotIndex, String callingPackage, String aid, int p2) {
5137         enforceModifyPermission();
5138         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5139         if (DBG) {
5140             log("iccOpenLogicalChannelBySlot: slot=" + slotIndex + " aid=" + aid + " p2=" + p2);
5141         }
5142         return iccOpenLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
5143                 callingPackage, aid, p2);
5144     }
5145 
iccOpenLogicalChannelWithPermission(Phone phone, String callingPackage, String aid, int p2)5146     private IccOpenLogicalChannelResponse iccOpenLogicalChannelWithPermission(Phone phone,
5147             String callingPackage, String aid, int p2) {
5148         final long identity = Binder.clearCallingIdentity();
5149         try {
5150             if (TextUtils.equals(ISDR_AID, aid)) {
5151                 // Only allows LPA to open logical channel to ISD-R.
5152                 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
5153                         .getContext().getPackageManager());
5154                 if (bestComponent == null
5155                         || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
5156                     loge("The calling package is not allowed to access ISD-R.");
5157                     throw new SecurityException(
5158                             "The calling package is not allowed to access ISD-R.");
5159                 }
5160             }
5161 
5162             IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
5163                     CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), phone,
5164                     null /* workSource */);
5165             if (DBG) log("iccOpenLogicalChannelWithPermission: " + response);
5166             return response;
5167         } finally {
5168             Binder.restoreCallingIdentity(identity);
5169         }
5170     }
5171 
5172     @Override
iccCloseLogicalChannel(int subId, int channel)5173     public boolean iccCloseLogicalChannel(int subId, int channel) {
5174         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5175                 mApp, subId, "iccCloseLogicalChannel");
5176         if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
5177         return iccCloseLogicalChannelWithPermission(getPhoneFromSubId(subId), channel);
5178     }
5179 
5180     @Override
iccCloseLogicalChannelBySlot(int slotIndex, int channel)5181     public boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel) {
5182         enforceModifyPermission();
5183         if (DBG) log("iccCloseLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel);
5184         return iccCloseLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
5185                 channel);
5186     }
5187 
iccCloseLogicalChannelWithPermission(Phone phone, int channel)5188     private boolean iccCloseLogicalChannelWithPermission(Phone phone, int channel) {
5189         final long identity = Binder.clearCallingIdentity();
5190         try {
5191             if (channel < 0) {
5192                 return false;
5193             }
5194             Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, channel, phone,
5195                     null /* workSource */);
5196             if (DBG) log("iccCloseLogicalChannelWithPermission: " + success);
5197             return success;
5198         } finally {
5199             Binder.restoreCallingIdentity(identity);
5200         }
5201     }
5202 
5203     @Override
iccTransmitApduLogicalChannel(int subId, int channel, int cla, int command, int p1, int p2, int p3, String data)5204     public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
5205             int command, int p1, int p2, int p3, String data) {
5206         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5207                 mApp, subId, "iccTransmitApduLogicalChannel");
5208         if (DBG) {
5209             log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
5210                     + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
5211                     + p3 + " data=" + data);
5212         }
5213         return iccTransmitApduLogicalChannelWithPermission(getPhoneFromSubId(subId), channel, cla,
5214                 command, p1, p2, p3, data);
5215     }
5216 
5217     @Override
iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla, int command, int p1, int p2, int p3, String data)5218     public String iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla,
5219             int command, int p1, int p2, int p3, String data) {
5220         enforceModifyPermission();
5221         if (DBG) {
5222             log("iccTransmitApduLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel
5223                     + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
5224                     + p3 + " data=" + data);
5225         }
5226         return iccTransmitApduLogicalChannelWithPermission(
5227                 getPhoneFromSlotIdOrThrowException(slotIndex), channel, cla, command, p1, p2, p3,
5228                 data);
5229     }
5230 
iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla, int command, int p1, int p2, int p3, String data)5231     private String iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla,
5232             int command, int p1, int p2, int p3, String data) {
5233         final long identity = Binder.clearCallingIdentity();
5234         try {
5235             if (channel <= 0) {
5236                 return "";
5237             }
5238 
5239             IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
5240                     new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), phone,
5241                     null /* workSource */);
5242             if (DBG) log("iccTransmitApduLogicalChannelWithPermission: " + response);
5243 
5244             // Append the returned status code to the end of the response payload.
5245             String s = Integer.toHexString(
5246                     (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
5247             if (response.payload != null) {
5248                 s = IccUtils.bytesToHexString(response.payload) + s;
5249             }
5250             return s;
5251         } finally {
5252             Binder.restoreCallingIdentity(identity);
5253         }
5254     }
5255 
5256     @Override
iccTransmitApduBasicChannel(int subId, String callingPackage, int cla, int command, int p1, int p2, int p3, String data)5257     public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
5258             int command, int p1, int p2, int p3, String data) {
5259         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5260                 mApp, subId, "iccTransmitApduBasicChannel");
5261         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5262         if (DBG) {
5263             log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
5264                     + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
5265         }
5266         return iccTransmitApduBasicChannelWithPermission(getPhoneFromSubId(subId), callingPackage,
5267                 cla, command, p1, p2, p3, data);
5268     }
5269 
5270     @Override
iccTransmitApduBasicChannelBySlot(int slotIndex, String callingPackage, int cla, int command, int p1, int p2, int p3, String data)5271     public String iccTransmitApduBasicChannelBySlot(int slotIndex, String callingPackage, int cla,
5272             int command, int p1, int p2, int p3, String data) {
5273         enforceModifyPermission();
5274         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5275         if (DBG) {
5276             log("iccTransmitApduBasicChannelBySlot: slotIndex=" + slotIndex + " cla=" + cla
5277                     + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3
5278                     + " data=" + data);
5279         }
5280 
5281         return iccTransmitApduBasicChannelWithPermission(
5282                 getPhoneFromSlotIdOrThrowException(slotIndex), callingPackage, cla, command, p1,
5283                 p2, p3, data);
5284     }
5285 
5286     // 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)5287     private String iccTransmitApduBasicChannelWithPermission(Phone phone, String callingPackage,
5288             int cla, int command, int p1, int p2, int p3, String data) {
5289         final long identity = Binder.clearCallingIdentity();
5290         try {
5291             if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
5292                     && TextUtils.equals(ISDR_AID, data)) {
5293                 // Only allows LPA to select ISD-R.
5294                 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
5295                         .getContext().getPackageManager());
5296                 if (bestComponent == null
5297                         || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
5298                     loge("The calling package is not allowed to select ISD-R.");
5299                     throw new SecurityException(
5300                             "The calling package is not allowed to select ISD-R.");
5301                 }
5302             }
5303 
5304             IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
5305                     new IccAPDUArgument(0, cla, command, p1, p2, p3, data), phone,
5306                     null /* workSource */);
5307             if (DBG) log("iccTransmitApduBasicChannelWithPermission: " + response);
5308 
5309             // Append the returned status code to the end of the response payload.
5310             String s = Integer.toHexString(
5311                     (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
5312             if (response.payload != null) {
5313                 s = IccUtils.bytesToHexString(response.payload) + s;
5314             }
5315             return s;
5316         } finally {
5317             Binder.restoreCallingIdentity(identity);
5318         }
5319     }
5320 
5321     @Override
iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3, String filePath)5322     public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
5323             String filePath) {
5324         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5325                 mApp, subId, "iccExchangeSimIO");
5326 
5327         final long identity = Binder.clearCallingIdentity();
5328         try {
5329             if (DBG) {
5330                 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
5331                         + p1 + " " + p2 + " " + p3 + ":" + filePath);
5332             }
5333 
5334             IccIoResult response =
5335                     (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
5336                             new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
5337                             subId);
5338 
5339             if (DBG) {
5340                 log("Exchange SIM_IO [R]" + response);
5341             }
5342 
5343             byte[] result = null;
5344             int length = 2;
5345             if (response.payload != null) {
5346                 length = 2 + response.payload.length;
5347                 result = new byte[length];
5348                 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
5349             } else {
5350                 result = new byte[length];
5351             }
5352 
5353             result[length - 1] = (byte) response.sw2;
5354             result[length - 2] = (byte) response.sw1;
5355             return result;
5356         } finally {
5357             Binder.restoreCallingIdentity(identity);
5358         }
5359     }
5360 
5361     /**
5362      * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
5363      * on a particular subscription
5364      */
getForbiddenPlmns(int subId, int appType, String callingPackage, String callingFeatureId)5365     public String[] getForbiddenPlmns(int subId, int appType, String callingPackage,
5366             String callingFeatureId) {
5367         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5368                 mApp, subId, callingPackage, callingFeatureId, "getForbiddenPlmns")) {
5369             return null;
5370         }
5371 
5372         final long identity = Binder.clearCallingIdentity();
5373         try {
5374             if (appType != TelephonyManager.APPTYPE_USIM
5375                     && appType != TelephonyManager.APPTYPE_SIM) {
5376                 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
5377                 return null;
5378             }
5379             Object response = sendRequest(
5380                     CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
5381             if (response instanceof String[]) {
5382                 return (String[]) response;
5383             }
5384             // Response is an Exception of some kind
5385             // which is signalled to the user as a NULL retval
5386             return null;
5387         } finally {
5388             Binder.restoreCallingIdentity(identity);
5389         }
5390     }
5391 
5392     /**
5393      * Set the forbidden PLMN list from the given app type (ex APPTYPE_USIM) on a particular
5394      * subscription.
5395      *
5396      * @param subId the id of the subscription.
5397      * @param appType the uicc app type, must be USIM or SIM.
5398      * @param fplmns the Forbiden plmns list that needed to be written to the SIM.
5399      * @param callingPackage the op Package name.
5400      * @param callingFeatureId the feature in the package.
5401      * @return number of fplmns that is successfully written to the SIM.
5402      */
setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage, String callingFeatureId)5403     public int setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage,
5404             String callingFeatureId) {
5405         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
5406                 callingFeatureId, "setForbiddenPlmns")) {
5407             if (DBG) logv("no permissions for setForbiddenplmns");
5408             throw new IllegalStateException("No Permissions for setForbiddenPlmns");
5409         }
5410         if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
5411             loge("setForbiddenPlmnList(): App Type must be USIM or SIM");
5412             throw new IllegalArgumentException("Invalid appType: App Type must be USIM or SIM");
5413         }
5414         if (fplmns == null) {
5415             throw new IllegalArgumentException("Fplmn List provided is null");
5416         }
5417         for (String fplmn : fplmns) {
5418             if (!CellIdentity.isValidPlmn(fplmn)) {
5419                 throw new IllegalArgumentException("Invalid fplmn provided: " + fplmn);
5420             }
5421         }
5422         final long identity = Binder.clearCallingIdentity();
5423         try {
5424             Object response = sendRequest(
5425                     CMD_SET_FORBIDDEN_PLMNS,
5426                     new Pair<Integer, List<String>>(new Integer(appType), fplmns),
5427                     subId);
5428             return (int) response;
5429         } finally {
5430             Binder.restoreCallingIdentity(identity);
5431         }
5432     }
5433 
5434     @Override
sendEnvelopeWithStatus(int subId, String content)5435     public String sendEnvelopeWithStatus(int subId, String content) {
5436         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5437                 mApp, subId, "sendEnvelopeWithStatus");
5438 
5439         final long identity = Binder.clearCallingIdentity();
5440         try {
5441             IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
5442             if (response.payload == null) {
5443                 return "";
5444             }
5445 
5446             // Append the returned status code to the end of the response payload.
5447             String s = Integer.toHexString(
5448                     (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
5449             s = IccUtils.bytesToHexString(response.payload) + s;
5450             return s;
5451         } finally {
5452             Binder.restoreCallingIdentity(identity);
5453         }
5454     }
5455 
5456     /**
5457      * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
5458      * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
5459      *
5460      * @param itemID the ID of the item to read
5461      * @return the NV item as a String, or null on error.
5462      */
5463     @Override
nvReadItem(int itemID)5464     public String nvReadItem(int itemID) {
5465         WorkSource workSource = getWorkSource(Binder.getCallingUid());
5466         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5467                 mApp, getDefaultSubscription(), "nvReadItem");
5468 
5469         final long identity = Binder.clearCallingIdentity();
5470         try {
5471             if (DBG) log("nvReadItem: item " + itemID);
5472             String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
5473             if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
5474             return value;
5475         } finally {
5476             Binder.restoreCallingIdentity(identity);
5477         }
5478     }
5479 
5480     /**
5481      * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
5482      * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
5483      *
5484      * @param itemID the ID of the item to read
5485      * @param itemValue the value to write, as a String
5486      * @return true on success; false on any failure
5487      */
5488     @Override
nvWriteItem(int itemID, String itemValue)5489     public boolean nvWriteItem(int itemID, String itemValue) {
5490         WorkSource workSource = getWorkSource(Binder.getCallingUid());
5491         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5492                 mApp, getDefaultSubscription(), "nvWriteItem");
5493 
5494         final long identity = Binder.clearCallingIdentity();
5495         try {
5496             if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
5497             Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
5498                     new Pair<Integer, String>(itemID, itemValue), workSource);
5499             if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
5500             return success;
5501         } finally {
5502             Binder.restoreCallingIdentity(identity);
5503         }
5504     }
5505 
5506     /**
5507      * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
5508      * Used for device configuration by some CDMA operators.
5509      *
5510      * @param preferredRoamingList byte array containing the new PRL
5511      * @return true on success; false on any failure
5512      */
5513     @Override
nvWriteCdmaPrl(byte[] preferredRoamingList)5514     public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
5515         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5516                 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
5517 
5518         final long identity = Binder.clearCallingIdentity();
5519         try {
5520             if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
5521             Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
5522             if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
5523             return success;
5524         } finally {
5525             Binder.restoreCallingIdentity(identity);
5526         }
5527     }
5528 
5529     /**
5530      * Rollback modem configurations to factory default except some config which are in whitelist.
5531      * Used for device configuration by some CDMA operators.
5532      *
5533      * @param slotIndex - device slot.
5534      *
5535      * @return true on success; false on any failure
5536      */
5537     @Override
resetModemConfig(int slotIndex)5538     public boolean resetModemConfig(int slotIndex) {
5539         Phone phone = PhoneFactory.getPhone(slotIndex);
5540         if (phone != null) {
5541             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5542                     mApp, phone.getSubId(), "resetModemConfig");
5543 
5544             final long identity = Binder.clearCallingIdentity();
5545             try {
5546                 Boolean success = (Boolean) sendRequest(CMD_RESET_MODEM_CONFIG, null);
5547                 if (DBG) log("resetModemConfig:" + ' ' + (success ? "ok" : "fail"));
5548                 return success;
5549             } finally {
5550                 Binder.restoreCallingIdentity(identity);
5551             }
5552         }
5553         return false;
5554     }
5555 
5556     /**
5557      * Generate a radio modem reset. Used for device configuration by some CDMA operators.
5558      *
5559      * @param slotIndex - device slot.
5560      *
5561      * @return true on success; false on any failure
5562      */
5563     @Override
rebootModem(int slotIndex)5564     public boolean rebootModem(int slotIndex) {
5565         Phone phone = PhoneFactory.getPhone(slotIndex);
5566         if (phone != null) {
5567             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5568                     mApp, phone.getSubId(), "rebootModem");
5569 
5570             final long identity = Binder.clearCallingIdentity();
5571             try {
5572                 Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
5573                 if (DBG) log("rebootModem:" + ' ' + (success ? "ok" : "fail"));
5574                 return success;
5575             } finally {
5576                 Binder.restoreCallingIdentity(identity);
5577             }
5578         }
5579         return false;
5580     }
5581 
getPcscfAddress(String apnType, String callingPackage, String callingFeatureId)5582     public String[] getPcscfAddress(String apnType, String callingPackage,
5583             String callingFeatureId) {
5584         final Phone defaultPhone = getDefaultPhone();
5585         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
5586                 callingPackage, callingFeatureId, "getPcscfAddress")) {
5587             return new String[0];
5588         }
5589 
5590         final long identity = Binder.clearCallingIdentity();
5591         try {
5592             return defaultPhone.getPcscfAddress(apnType);
5593         } finally {
5594             Binder.restoreCallingIdentity(identity);
5595         }
5596     }
5597 
5598     /**
5599      * Toggle IMS disable and enable for the framework to reset it. See {@link #enableIms(int)} and
5600      * {@link #disableIms(int)}.
5601      * @param slotIndex device slot.
5602      */
resetIms(int slotIndex)5603     public void resetIms(int slotIndex) {
5604         enforceModifyPermission();
5605 
5606         final long identity = Binder.clearCallingIdentity();
5607         try {
5608             if (mImsResolver == null) {
5609                 // may happen if the does not support IMS.
5610                 return;
5611             }
5612             mImsResolver.disableIms(slotIndex);
5613             mImsResolver.enableIms(slotIndex);
5614         } finally {
5615             Binder.restoreCallingIdentity(identity);
5616         }
5617     }
5618 
5619     /**
5620      * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
5621      * status updates, if not already enabled.
5622      */
enableIms(int slotId)5623     public void enableIms(int slotId) {
5624         enforceModifyPermission();
5625 
5626         final long identity = Binder.clearCallingIdentity();
5627         try {
5628             if (mImsResolver == null) {
5629                 // may happen if the device does not support IMS.
5630                 return;
5631             }
5632             mImsResolver.enableIms(slotId);
5633         } finally {
5634             Binder.restoreCallingIdentity(identity);
5635         }
5636     }
5637 
5638     /**
5639      * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
5640      * status updates to disabled.
5641      */
disableIms(int slotId)5642     public void disableIms(int slotId) {
5643         enforceModifyPermission();
5644 
5645         final long identity = Binder.clearCallingIdentity();
5646         try {
5647             if (mImsResolver == null) {
5648                 // may happen if the device does not support IMS.
5649                 return;
5650             }
5651             mImsResolver.disableIms(slotId);
5652         } finally {
5653             Binder.restoreCallingIdentity(identity);
5654         }
5655     }
5656 
5657     /**
5658      * Registers for updates to the MmTelFeature connection through the IImsServiceFeatureCallback
5659      * callback.
5660      */
5661     @Override
registerMmTelFeatureCallback(int slotId, IImsServiceFeatureCallback callback)5662     public void registerMmTelFeatureCallback(int slotId, IImsServiceFeatureCallback callback) {
5663         enforceModifyPermission();
5664 
5665         final long identity = Binder.clearCallingIdentity();
5666         try {
5667             if (mImsResolver == null) {
5668                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5669                         "Device does not support IMS");
5670             }
5671             mImsResolver.listenForFeature(slotId, ImsFeature.FEATURE_MMTEL, callback);
5672         } finally {
5673             Binder.restoreCallingIdentity(identity);
5674         }
5675     }
5676     /**
5677      * Unregister a previously registered IImsServiceFeatureCallback associated with an ImsFeature.
5678      */
5679     @Override
unregisterImsFeatureCallback(IImsServiceFeatureCallback callback)5680     public void unregisterImsFeatureCallback(IImsServiceFeatureCallback callback) {
5681         enforceModifyPermission();
5682 
5683         final long identity = Binder.clearCallingIdentity();
5684         try {
5685             if (mImsResolver == null) return;
5686             mImsResolver.unregisterImsFeatureCallback(callback);
5687         } finally {
5688             Binder.restoreCallingIdentity(identity);
5689         }
5690     }
5691 
5692     /**
5693      * Returns the {@link IImsRegistration} structure associated with the slotId and feature
5694      * specified or null if IMS is not supported on the slot specified.
5695      */
getImsRegistration(int slotId, int feature)5696     public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
5697         enforceModifyPermission();
5698 
5699         final long identity = Binder.clearCallingIdentity();
5700         try {
5701             if (mImsResolver == null) {
5702                 // may happen if the device does not support IMS.
5703                 return null;
5704             }
5705             return mImsResolver.getImsRegistration(slotId, feature);
5706         } finally {
5707             Binder.restoreCallingIdentity(identity);
5708         }
5709     }
5710 
5711     /**
5712      * Returns the {@link IImsConfig} structure associated with the slotId and feature
5713      * specified or null if IMS is not supported on the slot specified.
5714      */
getImsConfig(int slotId, int feature)5715     public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
5716         enforceModifyPermission();
5717 
5718         final long identity = Binder.clearCallingIdentity();
5719         try {
5720             if (mImsResolver == null) {
5721                 // may happen if the device does not support IMS.
5722                 return null;
5723             }
5724             return mImsResolver.getImsConfig(slotId, feature);
5725         } finally {
5726             Binder.restoreCallingIdentity(identity);
5727         }
5728     }
5729 
5730     /**
5731      * Sets the ImsService Package Name that Telephony will bind to.
5732      *
5733      * @param slotIndex the slot ID that the ImsService should bind for.
5734      * @param isCarrierService true if the ImsService is the carrier override, false if the
5735      *         ImsService is the device default ImsService.
5736      * @param featureTypes An integer array of feature types associated with a packageName.
5737      * @param packageName The name of the package that the current configuration will be replaced
5738      *                    with.
5739      * @return true if setting the ImsService to bind to succeeded, false if it did not.
5740      */
setBoundImsServiceOverride(int slotIndex, boolean isCarrierService, int[] featureTypes, String packageName)5741     public boolean setBoundImsServiceOverride(int slotIndex, boolean isCarrierService,
5742             int[] featureTypes, String packageName) {
5743         int[] subIds = SubscriptionManager.getSubId(slotIndex);
5744         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setBoundImsServiceOverride");
5745         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
5746                 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
5747                 "setBoundImsServiceOverride");
5748 
5749         final long identity = Binder.clearCallingIdentity();
5750         try {
5751             if (mImsResolver == null) {
5752                 // may happen if the device does not support IMS.
5753                 return false;
5754             }
5755             Map<Integer, String> featureConfig = new HashMap<>();
5756             for (int featureType : featureTypes) {
5757                 featureConfig.put(featureType, packageName);
5758             }
5759             return mImsResolver.overrideImsServiceConfiguration(slotIndex, isCarrierService,
5760                     featureConfig);
5761         } finally {
5762             Binder.restoreCallingIdentity(identity);
5763         }
5764     }
5765 
5766     /**
5767      * Clears any carrier ImsService overrides for the slot index specified that were previously
5768      * set with {@link #setBoundImsServiceOverride(int, boolean, int[], String)}.
5769      *
5770      * This should only be used for testing.
5771      *
5772      * @param slotIndex the slot ID that the ImsService should bind for.
5773      * @return true if clearing the carrier ImsService override succeeded or false if it did not.
5774      */
5775     @Override
clearCarrierImsServiceOverride(int slotIndex)5776     public boolean clearCarrierImsServiceOverride(int slotIndex) {
5777         int[] subIds = SubscriptionManager.getSubId(slotIndex);
5778         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
5779                 "clearCarrierImsServiceOverride");
5780         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
5781                 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
5782                 "clearCarrierImsServiceOverride");
5783 
5784         final long identity = Binder.clearCallingIdentity();
5785         try {
5786             if (mImsResolver == null) {
5787                 // may happen if the device does not support IMS.
5788                 return false;
5789             }
5790             return mImsResolver.clearCarrierImsServiceConfiguration(slotIndex);
5791         } finally {
5792             Binder.restoreCallingIdentity(identity);
5793         }
5794     }
5795 
5796     /**
5797      * Return the package name of the currently bound ImsService.
5798      *
5799      * @param slotId The slot that the ImsService is associated with.
5800      * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
5801      *         the device default.
5802      * @param featureType The feature associated with the queried configuration.
5803      * @return the package name of the ImsService configuration.
5804      */
getBoundImsServicePackage(int slotId, boolean isCarrierImsService, @ImsFeature.FeatureType int featureType)5805     public String getBoundImsServicePackage(int slotId, boolean isCarrierImsService,
5806             @ImsFeature.FeatureType int featureType) {
5807         int[] subIds = SubscriptionManager.getSubId(slotId);
5808         TelephonyPermissions
5809                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5810                 mApp, (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
5811                 "getBoundImsServicePackage");
5812 
5813         final long identity = Binder.clearCallingIdentity();
5814         try {
5815             if (mImsResolver == null) {
5816                 // may happen if the device does not support IMS.
5817                 return "";
5818             }
5819             // TODO: change API to query RCS separately.
5820             return mImsResolver.getImsServiceConfiguration(slotId, isCarrierImsService,
5821                     featureType);
5822         } finally {
5823             Binder.restoreCallingIdentity(identity);
5824         }
5825     }
5826 
5827     /**
5828      * Get the MmTelFeature state associated with the requested subscription id.
5829      * @param subId The subscription that the MmTelFeature is associated with.
5830      * @param callback A callback with an integer containing the
5831      * {@link android.telephony.ims.feature.ImsFeature.ImsState} associated with the MmTelFeature.
5832      */
5833     @Override
getImsMmTelFeatureState(int subId, IIntegerConsumer callback)5834     public void getImsMmTelFeatureState(int subId, IIntegerConsumer callback) {
5835         enforceReadPrivilegedPermission("getImsMmTelFeatureState");
5836         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
5837             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5838                     "IMS not available on device.");
5839         }
5840         final long token = Binder.clearCallingIdentity();
5841         try {
5842             int slotId = getSlotIndex(subId);
5843             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5844                 Log.w(LOG_TAG, "getImsMmTelFeatureState: called with an inactive subscription '"
5845                         + subId + "'");
5846                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
5847             }
5848             verifyImsMmTelConfiguredOrThrow(slotId);
5849             ImsManager.getInstance(mApp, slotId).getImsServiceState(anInteger -> {
5850                 try {
5851                     callback.accept(anInteger == null ? ImsFeature.STATE_UNAVAILABLE : anInteger);
5852                 } catch (RemoteException e) {
5853                     Log.w(LOG_TAG, "getImsMmTelFeatureState: remote caller is no longer running. "
5854                             + "Ignore");
5855                 }
5856             });
5857         } catch (ImsException e) {
5858             throw new ServiceSpecificException(e.getCode());
5859         } finally {
5860             Binder.restoreCallingIdentity(token);
5861         }
5862     }
5863 
5864     /**
5865      * Sets the ims registration state on all valid {@link Phone}s.
5866      */
setImsRegistrationState(final boolean registered)5867     public void setImsRegistrationState(final boolean registered) {
5868         enforceModifyPermission();
5869 
5870         final long identity = Binder.clearCallingIdentity();
5871         try {
5872             // NOTE: Before S, this method only set the default phone.
5873             for (final Phone phone : PhoneFactory.getPhones()) {
5874                 if (SubscriptionManager.isValidSubscriptionId(phone.getSubId())) {
5875                     phone.setImsRegistrationState(registered);
5876                 }
5877             }
5878         } finally {
5879             Binder.restoreCallingIdentity(identity);
5880         }
5881     }
5882 
5883     /**
5884      * Set the network selection mode to automatic.
5885      *
5886      */
5887     @Override
setNetworkSelectionModeAutomatic(int subId)5888     public void setNetworkSelectionModeAutomatic(int subId) {
5889         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5890                 mApp, subId, "setNetworkSelectionModeAutomatic");
5891 
5892         final long identity = Binder.clearCallingIdentity();
5893         try {
5894             if (!isActiveSubscription(subId)) {
5895                 return;
5896             }
5897             if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
5898             sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId,
5899                     SET_NETWORK_SELECTION_MODE_AUTOMATIC_TIMEOUT_MS);
5900         } finally {
5901             Binder.restoreCallingIdentity(identity);
5902         }
5903     }
5904 
5905     /**
5906      * Ask the radio to connect to the input network and change selection mode to manual.
5907      *
5908      * @param subId the id of the subscription.
5909      * @param operatorInfo the operator information, included the PLMN, long name and short name of
5910      * the operator to attach to.
5911      * @param persistSelection whether the selection will persist until reboot. If true, only allows
5912      * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
5913      * normal network selection next time.
5914      * @return {@code true} on success; {@code true} on any failure.
5915      */
5916     @Override
setNetworkSelectionModeManual( int subId, OperatorInfo operatorInfo, boolean persistSelection)5917     public boolean setNetworkSelectionModeManual(
5918             int subId, OperatorInfo operatorInfo, boolean persistSelection) {
5919         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5920                 mApp, subId, "setNetworkSelectionModeManual");
5921 
5922         if (!isActiveSubscription(subId)) {
5923             return false;
5924         }
5925 
5926         final long identity = Binder.clearCallingIdentity();
5927         try {
5928             ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
5929                     persistSelection);
5930             if (DBG) {
5931                 log("setNetworkSelectionModeManual: subId: " + subId
5932                         + " operator: " + operatorInfo);
5933             }
5934             return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
5935         } finally {
5936             Binder.restoreCallingIdentity(identity);
5937         }
5938     }
5939      /**
5940      * Get the manual network selection
5941      *
5942      * @param subId the id of the subscription.
5943      *
5944      * @return the previously saved user selected PLMN
5945      */
5946     @Override
getManualNetworkSelectionPlmn(int subId)5947     public String getManualNetworkSelectionPlmn(int subId) {
5948         TelephonyPermissions
5949                     .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5950                     mApp, subId, "getManualNetworkSelectionPlmn");
5951 
5952         final long identity = Binder.clearCallingIdentity();
5953         try {
5954             if (!isActiveSubscription(subId)) {
5955                 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
5956             }
5957 
5958             final Phone phone = getPhone(subId);
5959             if (phone == null) {
5960                 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
5961             }
5962             OperatorInfo networkSelection = phone.getSavedNetworkSelection();
5963             return TextUtils.isEmpty(networkSelection.getOperatorNumeric())
5964                 ? phone.getManualNetworkSelectionPlmn() : networkSelection.getOperatorNumeric();
5965         } finally {
5966             Binder.restoreCallingIdentity(identity);
5967         }
5968     }
5969 
5970     /**
5971      * Scans for available networks.
5972      */
5973     @Override
getCellNetworkScanResults(int subId, String callingPackage, String callingFeatureId)5974     public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage,
5975             String callingFeatureId) {
5976         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5977                 mApp, subId, "getCellNetworkScanResults");
5978         LocationAccessPolicy.LocationPermissionResult locationResult =
5979                 LocationAccessPolicy.checkLocationPermission(mApp,
5980                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
5981                                 .setCallingPackage(callingPackage)
5982                                 .setCallingFeatureId(callingFeatureId)
5983                                 .setCallingPid(Binder.getCallingPid())
5984                                 .setCallingUid(Binder.getCallingUid())
5985                                 .setMethod("getCellNetworkScanResults")
5986                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
5987                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
5988                                 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
5989                                 .build());
5990         switch (locationResult) {
5991             case DENIED_HARD:
5992                 throw new SecurityException("Not allowed to access scan results -- location");
5993             case DENIED_SOFT:
5994                 return null;
5995         }
5996 
5997         long identity = Binder.clearCallingIdentity();
5998         try {
5999             if (DBG) log("getCellNetworkScanResults: subId " + subId);
6000             return (CellNetworkScanResult) sendRequest(
6001                     CMD_PERFORM_NETWORK_SCAN, null, subId);
6002         } finally {
6003             Binder.restoreCallingIdentity(identity);
6004         }
6005     }
6006 
6007     /**
6008      * Get the call forwarding info, given the call forwarding reason.
6009      */
6010     @Override
getCallForwarding(int subId, int callForwardingReason, ICallForwardingInfoCallback callback)6011     public void getCallForwarding(int subId, int callForwardingReason,
6012             ICallForwardingInfoCallback callback) {
6013         enforceReadPrivilegedPermission("getCallForwarding");
6014         long identity = Binder.clearCallingIdentity();
6015         try {
6016             if (DBG) {
6017                 log("getCallForwarding: subId " + subId
6018                         + " callForwardingReason" + callForwardingReason);
6019             }
6020 
6021             Phone phone = getPhone(subId);
6022             if (phone == null) {
6023                 try {
6024                     callback.onError(
6025                             TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
6026                 } catch (RemoteException e) {
6027                     // ignore
6028                 }
6029                 return;
6030             }
6031 
6032             Pair<Integer, TelephonyManager.CallForwardingInfoCallback> argument = Pair.create(
6033                     callForwardingReason, new TelephonyManager.CallForwardingInfoCallback() {
6034                         @Override
6035                         public void onCallForwardingInfoAvailable(CallForwardingInfo info) {
6036                             try {
6037                                 callback.onCallForwardingInfoAvailable(info);
6038                             } catch (RemoteException e) {
6039                                 // ignore
6040                             }
6041                         }
6042 
6043                         @Override
6044                         public void onError(int error) {
6045                             try {
6046                                 callback.onError(error);
6047                             } catch (RemoteException e) {
6048                                 // ignore
6049                             }
6050                         }
6051                     });
6052             sendRequestAsync(CMD_GET_CALL_FORWARDING, argument, phone, null);
6053         } finally {
6054             Binder.restoreCallingIdentity(identity);
6055         }
6056     }
6057 
6058     /**
6059      * Sets the voice call forwarding info including status (enable/disable), call forwarding
6060      * reason, the number to forward, and the timeout before the forwarding is attempted.
6061      */
6062     @Override
setCallForwarding(int subId, CallForwardingInfo callForwardingInfo, IIntegerConsumer callback)6063     public void setCallForwarding(int subId, CallForwardingInfo callForwardingInfo,
6064             IIntegerConsumer callback) {
6065         enforceModifyPermission();
6066         long identity = Binder.clearCallingIdentity();
6067         try {
6068             if (DBG) {
6069                 log("setCallForwarding: subId " + subId
6070                         + " callForwardingInfo" + callForwardingInfo);
6071             }
6072 
6073             Phone phone = getPhone(subId);
6074             if (phone == null) {
6075                 try {
6076                     callback.accept(
6077                             TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
6078                 } catch (RemoteException e) {
6079                     // ignore
6080                 }
6081                 return;
6082             }
6083 
6084             Pair<CallForwardingInfo, Consumer<Integer>> arguments = Pair.create(callForwardingInfo,
6085                     FunctionalUtils.ignoreRemoteException(callback::accept));
6086 
6087             sendRequestAsync(CMD_SET_CALL_FORWARDING, arguments, phone, null);
6088         } finally {
6089             Binder.restoreCallingIdentity(identity);
6090         }
6091     }
6092 
6093     /**
6094      * Get the call waiting status for a subId.
6095      */
6096     @Override
getCallWaitingStatus(int subId, IIntegerConsumer callback)6097     public void getCallWaitingStatus(int subId, IIntegerConsumer callback) {
6098         enforceReadPrivilegedPermission("getCallWaitingStatus");
6099         long identity = Binder.clearCallingIdentity();
6100         try {
6101             Phone phone = getPhone(subId);
6102             if (phone == null) {
6103                 try {
6104                     callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
6105                 } catch (RemoteException e) {
6106                     // ignore
6107                 }
6108                 return;
6109             }
6110             CarrierConfigManager configManager = new CarrierConfigManager(phone.getContext());
6111             PersistableBundle c = configManager.getConfigForSubId(subId);
6112             boolean requireUssd = c.getBoolean(
6113                     CarrierConfigManager.KEY_USE_CALL_WAITING_USSD_BOOL, false);
6114 
6115             if (DBG) log("getCallWaitingStatus: subId " + subId);
6116             if (requireUssd) {
6117                 CarrierXmlParser carrierXmlParser = new CarrierXmlParser(phone.getContext(),
6118                         getSubscriptionCarrierId(subId));
6119                 String newUssdCommand = "";
6120                 try {
6121                     newUssdCommand = carrierXmlParser.getFeature(
6122                             CarrierXmlParser.FEATURE_CALL_WAITING)
6123                             .makeCommand(CarrierXmlParser.SsEntry.SSAction.QUERY, null);
6124                 } catch (NullPointerException e) {
6125                     loge("Failed to generate USSD number" + e);
6126                 }
6127                 ResultReceiver wrappedCallback = new CallWaitingUssdResultReceiver(
6128                         mMainThreadHandler, callback, carrierXmlParser,
6129                         CarrierXmlParser.SsEntry.SSAction.QUERY);
6130                 final String ussdCommand = newUssdCommand;
6131                 Executors.newSingleThreadExecutor().execute(() -> {
6132                     handleUssdRequest(subId, ussdCommand, wrappedCallback);
6133                 });
6134             } else {
6135                 Consumer<Integer> argument = FunctionalUtils.ignoreRemoteException(
6136                         callback::accept);
6137                 sendRequestAsync(CMD_GET_CALL_WAITING, argument, phone, null);
6138             }
6139         } finally {
6140             Binder.restoreCallingIdentity(identity);
6141         }
6142     }
6143 
6144     /**
6145      * Sets whether call waiting is enabled for a given subId.
6146      */
6147     @Override
setCallWaitingStatus(int subId, boolean enable, IIntegerConsumer callback)6148     public void setCallWaitingStatus(int subId, boolean enable, IIntegerConsumer callback) {
6149         enforceModifyPermission();
6150         long identity = Binder.clearCallingIdentity();
6151         try {
6152             if (DBG) log("setCallWaitingStatus: subId " + subId + " enable: " + enable);
6153 
6154             Phone phone = getPhone(subId);
6155             if (phone == null) {
6156                 try {
6157                     callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
6158                 } catch (RemoteException e) {
6159                     // ignore
6160                 }
6161                 return;
6162             }
6163 
6164             CarrierConfigManager configManager = new CarrierConfigManager(phone.getContext());
6165             PersistableBundle c = configManager.getConfigForSubId(subId);
6166             boolean requireUssd = c.getBoolean(
6167                     CarrierConfigManager.KEY_USE_CALL_WAITING_USSD_BOOL, false);
6168 
6169             if (DBG) log("getCallWaitingStatus: subId " + subId);
6170             if (requireUssd) {
6171                 CarrierXmlParser carrierXmlParser = new CarrierXmlParser(phone.getContext(),
6172                         getSubscriptionCarrierId(subId));
6173                 CarrierXmlParser.SsEntry.SSAction ssAction =
6174                         enable ? CarrierXmlParser.SsEntry.SSAction.UPDATE_ACTIVATE
6175                                 : CarrierXmlParser.SsEntry.SSAction.UPDATE_DEACTIVATE;
6176                 String newUssdCommand = "";
6177                 try {
6178                     newUssdCommand = carrierXmlParser.getFeature(
6179                             CarrierXmlParser.FEATURE_CALL_WAITING)
6180                             .makeCommand(ssAction, null);
6181                 } catch (NullPointerException e) {
6182                     loge("Failed to generate USSD number" + e);
6183                 }
6184                 ResultReceiver wrappedCallback = new CallWaitingUssdResultReceiver(
6185                         mMainThreadHandler, callback, carrierXmlParser, ssAction);
6186                 final String ussdCommand = newUssdCommand;
6187                 Executors.newSingleThreadExecutor().execute(() -> {
6188                     handleUssdRequest(subId, ussdCommand, wrappedCallback);
6189                 });
6190             } else {
6191                 Pair<Boolean, Consumer<Integer>> arguments = Pair.create(enable,
6192                         FunctionalUtils.ignoreRemoteException(callback::accept));
6193 
6194                 sendRequestAsync(CMD_SET_CALL_WAITING, arguments, phone, null);
6195             }
6196         } finally {
6197             Binder.restoreCallingIdentity(identity);
6198         }
6199     }
6200 
6201     /**
6202      * Starts a new network scan and returns the id of this scan.
6203      *
6204      * @param subId id of the subscription
6205      * @param request contains the radio access networks with bands/channels to scan
6206      * @param messenger callback messenger for scan results or errors
6207      * @param binder for the purpose of auto clean when the user thread crashes
6208      * @return the id of the requested scan which can be used to stop the scan.
6209      */
6210     @Override
requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger, IBinder binder, String callingPackage, String callingFeatureId)6211     public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
6212             IBinder binder, String callingPackage, String callingFeatureId) {
6213         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6214                 mApp, subId, "requestNetworkScan");
6215         LocationAccessPolicy.LocationPermissionResult locationResult =
6216                 LocationAccessPolicy.checkLocationPermission(mApp,
6217                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
6218                                 .setCallingPackage(callingPackage)
6219                                 .setCallingFeatureId(callingFeatureId)
6220                                 .setCallingPid(Binder.getCallingPid())
6221                                 .setCallingUid(Binder.getCallingUid())
6222                                 .setMethod("requestNetworkScan")
6223                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
6224                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
6225                                 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
6226                                 .build());
6227         if (locationResult != LocationAccessPolicy.LocationPermissionResult.ALLOWED) {
6228             SecurityException e = checkNetworkRequestForSanitizedLocationAccess(
6229                     request, subId, callingPackage);
6230             if (e != null) {
6231                 if (locationResult == LocationAccessPolicy.LocationPermissionResult.DENIED_HARD) {
6232                     throw e;
6233                 } else {
6234                     loge(e.getMessage());
6235                     return TelephonyScanManager.INVALID_SCAN_ID;
6236                 }
6237             }
6238         }
6239         int callingUid = Binder.getCallingUid();
6240         int callingPid = Binder.getCallingPid();
6241         final long identity = Binder.clearCallingIdentity();
6242         try {
6243             return mNetworkScanRequestTracker.startNetworkScan(
6244                     request, messenger, binder, getPhone(subId),
6245                     callingUid, callingPid, callingPackage);
6246         } finally {
6247             Binder.restoreCallingIdentity(identity);
6248         }
6249     }
6250 
checkNetworkRequestForSanitizedLocationAccess( NetworkScanRequest request, int subId, String callingPackage)6251     private SecurityException checkNetworkRequestForSanitizedLocationAccess(
6252             NetworkScanRequest request, int subId, String callingPackage) {
6253         boolean hasCarrierPriv = checkCarrierPrivilegesForPackage(subId, callingPackage)
6254                 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
6255         boolean hasNetworkScanPermission =
6256                 mApp.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SCAN)
6257                 == PERMISSION_GRANTED;
6258 
6259         if (!hasCarrierPriv && !hasNetworkScanPermission) {
6260             return new SecurityException("permission.NETWORK_SCAN or carrier privileges is needed"
6261                     + " for network scans without location access.");
6262         }
6263 
6264         if (request.getSpecifiers() != null && request.getSpecifiers().length > 0) {
6265             for (RadioAccessSpecifier ras : request.getSpecifiers()) {
6266                 if (ras.getChannels() != null && ras.getChannels().length > 0) {
6267                     return new SecurityException("Specific channels must not be"
6268                             + " scanned without location access.");
6269                 }
6270             }
6271         }
6272 
6273         return null;
6274     }
6275 
6276     /**
6277      * Stops an existing network scan with the given scanId.
6278      *
6279      * @param subId id of the subscription
6280      * @param scanId id of the scan that needs to be stopped
6281      */
6282     @Override
stopNetworkScan(int subId, int scanId)6283     public void stopNetworkScan(int subId, int scanId) {
6284         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6285                 mApp, subId, "stopNetworkScan");
6286 
6287         int callingUid = Binder.getCallingUid();
6288         final long identity = Binder.clearCallingIdentity();
6289         try {
6290             mNetworkScanRequestTracker.stopNetworkScan(scanId, callingUid);
6291         } finally {
6292             Binder.restoreCallingIdentity(identity);
6293         }
6294     }
6295 
6296     /**
6297      * Get the allowed network types bitmask.
6298      *
6299      * @return the allowed network types bitmask, defined in RILConstants.java.
6300      */
6301     @Override
getAllowedNetworkTypesBitmask(int subId)6302     public int getAllowedNetworkTypesBitmask(int subId) {
6303         TelephonyPermissions
6304                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6305                         mApp, subId, "getAllowedNetworkTypesBitmask");
6306 
6307         final long identity = Binder.clearCallingIdentity();
6308         try {
6309             if (DBG) log("getAllowedNetworkTypesBitmask");
6310             int[] result = (int[]) sendRequest(CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK, null, subId);
6311             int networkTypesBitmask = (result != null ? result[0] : -1);
6312             if (DBG) log("getAllowedNetworkTypesBitmask: " + networkTypesBitmask);
6313             return networkTypesBitmask;
6314         } finally {
6315             Binder.restoreCallingIdentity(identity);
6316         }
6317     }
6318 
6319     /**
6320      * Get the allowed network types for certain reason.
6321      *
6322      * @param subId the id of the subscription.
6323      * @param reason the reason the allowed network type change is taking place
6324      * @return the allowed network types.
6325      */
6326     @Override
getAllowedNetworkTypesForReason(int subId, @TelephonyManager.AllowedNetworkTypesReason int reason)6327     public long getAllowedNetworkTypesForReason(int subId,
6328             @TelephonyManager.AllowedNetworkTypesReason int reason) {
6329         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
6330                 mApp, subId, "getAllowedNetworkTypesForReason");
6331         final long identity = Binder.clearCallingIdentity();
6332         try {
6333             return getPhoneFromSubId(subId).getAllowedNetworkTypes(reason);
6334         } finally {
6335             Binder.restoreCallingIdentity(identity);
6336         }
6337     }
6338 
6339     /**
6340      * Enable/Disable E-UTRA-NR Dual Connectivity
6341      * @param subId subscription id of the sim card
6342      * @param nrDualConnectivityState expected NR dual connectivity state
6343      * This can be passed following states
6344      * <ol>
6345      * <li>Enable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_ENABLE}
6346      * <li>Disable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE}
6347      * <li>Disable NR dual connectivity and force secondary cell to be released
6348      * {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE}
6349      * </ol>
6350      * @return operation result.
6351      */
6352     @Override
setNrDualConnectivityState(int subId, @TelephonyManager.NrDualConnectivityState int nrDualConnectivityState)6353     public int setNrDualConnectivityState(int subId,
6354             @TelephonyManager.NrDualConnectivityState int nrDualConnectivityState) {
6355         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6356                 mApp, subId, "enableNRDualConnectivity");
6357         if (!isRadioInterfaceCapabilitySupported(
6358                 TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE)) {
6359             return TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED;
6360         }
6361 
6362         WorkSource workSource = getWorkSource(Binder.getCallingUid());
6363         final long identity = Binder.clearCallingIdentity();
6364         try {
6365             int result = (int) sendRequest(CMD_ENABLE_NR_DUAL_CONNECTIVITY,
6366                     nrDualConnectivityState, subId,
6367                     workSource);
6368             if (DBG) log("enableNRDualConnectivity result: " + result);
6369             return result;
6370         } finally {
6371             Binder.restoreCallingIdentity(identity);
6372         }
6373     }
6374 
6375     /**
6376      * Is E-UTRA-NR Dual Connectivity enabled
6377      * @return true if dual connectivity is enabled else false
6378      */
6379     @Override
isNrDualConnectivityEnabled(int subId)6380     public boolean isNrDualConnectivityEnabled(int subId) {
6381         TelephonyPermissions
6382                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6383                         mApp, subId, "isNRDualConnectivityEnabled");
6384         if (!isRadioInterfaceCapabilitySupported(
6385                 TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE)) {
6386             return false;
6387         }
6388         WorkSource workSource = getWorkSource(Binder.getCallingUid());
6389         final long identity = Binder.clearCallingIdentity();
6390         try {
6391             boolean isEnabled = (boolean) sendRequest(CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED,
6392                     null, subId, workSource);
6393             if (DBG) log("isNRDualConnectivityEnabled: " + isEnabled);
6394             return isEnabled;
6395         } finally {
6396             Binder.restoreCallingIdentity(identity);
6397         }
6398     }
6399 
6400     /**
6401      * Set the allowed network types of the device and
6402      * provide the reason triggering the allowed network change.
6403      *
6404      * @param subId the id of the subscription.
6405      * @param reason the reason the allowed network type change is taking place
6406      * @param allowedNetworkTypes the allowed network types.
6407      * @return true on success; false on any failure.
6408      */
6409     @Override
setAllowedNetworkTypesForReason(int subId, @TelephonyManager.AllowedNetworkTypesReason int reason, @TelephonyManager.NetworkTypeBitMask long allowedNetworkTypes)6410     public boolean setAllowedNetworkTypesForReason(int subId,
6411             @TelephonyManager.AllowedNetworkTypesReason int reason,
6412             @TelephonyManager.NetworkTypeBitMask long allowedNetworkTypes) {
6413         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6414                 mApp, subId, "setAllowedNetworkTypesForReason");
6415         if (!TelephonyManager.isValidAllowedNetworkTypesReason(reason)) {
6416             loge("setAllowedNetworkTypesForReason: Invalid allowed network type reason: " + reason);
6417             return false;
6418         }
6419         if (!SubscriptionManager.isUsableSubscriptionId(subId)) {
6420             loge("setAllowedNetworkTypesForReason: Invalid subscriptionId:" + subId);
6421             return false;
6422         }
6423 
6424         log("setAllowedNetworkTypesForReason: " + reason + " value: "
6425                 + TelephonyManager.convertNetworkTypeBitmaskToString(allowedNetworkTypes));
6426 
6427 
6428         if (allowedNetworkTypes == getPhoneFromSubId(subId).getAllowedNetworkTypes(reason)) {
6429             log("setAllowedNetworkTypesForReason: " + reason + "does not change value");
6430             return true;
6431         }
6432 
6433         final long identity = Binder.clearCallingIdentity();
6434         try {
6435             Boolean success = (Boolean) sendRequest(
6436                     CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON,
6437                     new Pair<Integer, Long>(reason, allowedNetworkTypes), subId);
6438 
6439             if (DBG) log("setAllowedNetworkTypesForReason: " + (success ? "ok" : "fail"));
6440             return success;
6441         } finally {
6442             Binder.restoreCallingIdentity(identity);
6443         }
6444     }
6445 
6446     /**
6447      * Check whether DUN APN is required for tethering with subId.
6448      *
6449      * @param subId the id of the subscription to require tethering.
6450      * @return {@code true} if DUN APN is required for tethering.
6451      * @hide
6452      */
6453     @Override
isTetheringApnRequiredForSubscriber(int subId)6454     public boolean isTetheringApnRequiredForSubscriber(int subId) {
6455         enforceModifyPermission();
6456         final long identity = Binder.clearCallingIdentity();
6457         final Phone phone = getPhone(subId);
6458         try {
6459             if (phone != null) {
6460                 return phone.hasMatchedTetherApnSetting();
6461             } else {
6462                 return false;
6463             }
6464         } finally {
6465             Binder.restoreCallingIdentity(identity);
6466         }
6467     }
6468 
6469     /**
6470      * Enable or disable always reporting signal strength changes from radio.
6471      *
6472      * @param isEnable {@code true} for enabling; {@code false} for disabling.
6473      */
6474     @Override
setAlwaysReportSignalStrength(int subId, boolean isEnable)6475     public void setAlwaysReportSignalStrength(int subId, boolean isEnable) {
6476         enforceModifyPermission();
6477         enforceSystemCaller();
6478 
6479         final long identity = Binder.clearCallingIdentity();
6480         final Phone phone = getPhone(subId);
6481         try {
6482             if (phone != null) {
6483                 if (DBG) {
6484                     log("setAlwaysReportSignalStrength: subId=" + subId
6485                             + " isEnable=" + isEnable);
6486                 }
6487                 phone.setAlwaysReportSignalStrength(isEnable);
6488             } else {
6489                 loge("setAlwaysReportSignalStrength: no phone found for subId="
6490                         + subId);
6491             }
6492         } finally {
6493             Binder.restoreCallingIdentity(identity);
6494         }
6495     }
6496 
6497     /**
6498      * Get the user enabled state of Mobile Data.
6499      *
6500      * TODO: remove and use isUserDataEnabled.
6501      * This can't be removed now because some vendor codes
6502      * calls through ITelephony directly while they should
6503      * use TelephonyManager.
6504      *
6505      * @return true on enabled
6506      */
6507     @Override
getDataEnabled(int subId)6508     public boolean getDataEnabled(int subId) {
6509         return isUserDataEnabled(subId);
6510     }
6511 
6512     /**
6513      * Get whether mobile data is enabled per user setting.
6514      *
6515      * There are other factors deciding whether mobile data is actually enabled, but they are
6516      * not considered here. See {@link #isDataEnabled(int)} for more details.
6517      *
6518      * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
6519      *
6520      * @return {@code true} if data is enabled else {@code false}
6521      */
6522     @Override
isUserDataEnabled(int subId)6523     public boolean isUserDataEnabled(int subId) {
6524         try {
6525             mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
6526                     null);
6527         } catch (Exception e) {
6528             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6529                     mApp, subId, "isUserDataEnabled");
6530         }
6531 
6532         final long identity = Binder.clearCallingIdentity();
6533         try {
6534             int phoneId = mSubscriptionController.getPhoneId(subId);
6535             if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
6536             Phone phone = PhoneFactory.getPhone(phoneId);
6537             if (phone != null) {
6538                 boolean retVal = phone.isUserDataEnabled();
6539                 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
6540                 return retVal;
6541             } else {
6542                 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
6543                 return false;
6544             }
6545         } finally {
6546             Binder.restoreCallingIdentity(identity);
6547         }
6548     }
6549 
6550     /**
6551      * Checks if the device is capable of mobile data by considering whether whether the
6552      * user has enabled mobile data, whether the carrier has enabled mobile data, and
6553      * whether the network policy allows data connections.
6554      *
6555      * @return {@code true} if the overall data connection is capable; {@code false} if not.
6556      */
6557     @Override
isDataEnabled(int subId)6558     public boolean isDataEnabled(int subId) {
6559         try {
6560             try {
6561                 mApp.enforceCallingOrSelfPermission(
6562                         android.Manifest.permission.ACCESS_NETWORK_STATE,
6563                         null);
6564             } catch (Exception e) {
6565                 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
6566                         "isDataEnabled");
6567             }
6568         } catch (Exception e) {
6569             enforceReadPrivilegedPermission("isDataEnabled");
6570         }
6571 
6572         final long identity = Binder.clearCallingIdentity();
6573         try {
6574             int phoneId = mSubscriptionController.getPhoneId(subId);
6575             if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
6576             Phone phone = PhoneFactory.getPhone(phoneId);
6577             if (phone != null) {
6578                 boolean retVal = phone.getDataEnabledSettings().isDataEnabled();
6579                 if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
6580                 return retVal;
6581             } else {
6582                 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
6583                 return false;
6584             }
6585         } finally {
6586             Binder.restoreCallingIdentity(identity);
6587         }
6588     }
6589 
6590     /**
6591      * Check if data is enabled for a specific reason
6592      * @param subId Subscription index
6593      * @param reason the reason the data enable change is taking place
6594      * @return {@code true} if the overall data is enabled; {@code false} if not.
6595      */
6596     @Override
isDataEnabledForReason(int subId, @TelephonyManager.DataEnabledReason int reason)6597     public boolean isDataEnabledForReason(int subId,
6598             @TelephonyManager.DataEnabledReason int reason) {
6599         try {
6600             mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
6601                     null);
6602         } catch (Exception e) {
6603             mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
6604                     "isDataEnabledForReason");
6605         }
6606 
6607 
6608         final long identity = Binder.clearCallingIdentity();
6609         try {
6610             int phoneId = mSubscriptionController.getPhoneId(subId);
6611             if (DBG) {
6612                 log("isDataEnabledForReason: subId=" + subId + " phoneId=" + phoneId
6613                         + " reason=" + reason);
6614             }
6615             Phone phone = PhoneFactory.getPhone(phoneId);
6616             if (phone != null) {
6617                 boolean retVal;
6618                 if (reason == TelephonyManager.DATA_ENABLED_REASON_USER) {
6619                     retVal = phone.isUserDataEnabled();
6620                 } else {
6621                     retVal = phone.getDataEnabledSettings().isDataEnabledForReason(reason);
6622                 }
6623                 if (DBG) log("isDataEnabledForReason: retVal=" + retVal);
6624                 return retVal;
6625             } else {
6626                 if (DBG) {
6627                     loge("isDataEnabledForReason: no phone subId="
6628                             + subId + " retVal=false");
6629                 }
6630                 return false;
6631             }
6632         } finally {
6633             Binder.restoreCallingIdentity(identity);
6634         }
6635     }
6636 
getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, int uid, Phone phone)6637     private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, int uid,
6638             Phone phone) {
6639         if (uid == Process.PHONE_UID) {
6640             // Skip the check if it's the phone UID (system UID removed in b/184713596)
6641             // TODO (b/184954344): Check for system/phone UID at call site instead of here
6642             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
6643         }
6644 
6645         //load access rules from carrier configs, and check those as well: b/139133814
6646         SubscriptionController subController = SubscriptionController.getInstance();
6647         if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
6648                 || subController == null) return privilegeFromSim;
6649 
6650         PackageManager pkgMgr = phone.getContext().getPackageManager();
6651         String[] packages = pkgMgr.getPackagesForUid(uid);
6652 
6653         final long identity = Binder.clearCallingIdentity();
6654         try {
6655             int subId = phone.getSubId();
6656             if (mCarrierPrivilegeTestOverrideSubIds.contains(subId)) {
6657                 // A test override is in place for the privileges for this subId, so don't try to
6658                 // read the subscription privileges.
6659                 return privilegeFromSim;
6660             }
6661             SubscriptionInfo subInfo = subController.getSubscriptionInfo(subId);
6662             SubscriptionManager subManager = (SubscriptionManager)
6663                     phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
6664             for (String pkg : packages) {
6665                 if (subManager.canManageSubscription(subInfo, pkg)) {
6666                     return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
6667                 }
6668             }
6669             return privilegeFromSim;
6670         } finally {
6671             Binder.restoreCallingIdentity(identity);
6672         }
6673     }
6674 
getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, Phone phone, String pkgName)6675     private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, Phone phone,
6676             String pkgName) {
6677         //load access rules from carrier configs, and check those as well: b/139133814
6678         SubscriptionController subController = SubscriptionController.getInstance();
6679         if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
6680                 || subController == null) return privilegeFromSim;
6681 
6682         final long identity = Binder.clearCallingIdentity();
6683         try {
6684             int subId = phone.getSubId();
6685             if (mCarrierPrivilegeTestOverrideSubIds.contains(subId)) {
6686                 // A test override is in place for the privileges for this subId, so don't try to
6687                 // read the subscription privileges.
6688                 return privilegeFromSim;
6689             }
6690             SubscriptionInfo subInfo = subController.getSubscriptionInfo(subId);
6691             SubscriptionManager subManager = (SubscriptionManager)
6692                     phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
6693             return subManager.canManageSubscription(subInfo, pkgName)
6694                 ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS : privilegeFromSim;
6695         } finally {
6696             Binder.restoreCallingIdentity(identity);
6697         }
6698     }
6699 
6700     @Override
getCarrierPrivilegeStatus(int subId)6701     public int getCarrierPrivilegeStatus(int subId) {
6702         final Phone phone = getPhone(subId);
6703         if (phone == null) {
6704             loge("getCarrierPrivilegeStatus: Invalid subId");
6705             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
6706         }
6707         UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
6708         if (card == null) {
6709             loge("getCarrierPrivilegeStatus: No UICC");
6710             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6711         }
6712 
6713         return getCarrierPrivilegeStatusFromCarrierConfigRules(
6714             card.getCarrierPrivilegeStatusForCurrentTransaction(
6715                 phone.getContext().getPackageManager()), Binder.getCallingUid(), phone);
6716     }
6717 
6718     @Override
getCarrierPrivilegeStatusForUid(int subId, int uid)6719     public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
6720         enforceReadPrivilegedPermission("getCarrierPrivilegeStatusForUid");
6721         final Phone phone = getPhone(subId);
6722         if (phone == null) {
6723             loge("getCarrierPrivilegeStatusForUid: Invalid subId");
6724             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
6725         }
6726         UiccProfile profile =
6727                 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
6728         if (profile == null) {
6729             loge("getCarrierPrivilegeStatusForUid: No UICC");
6730             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6731         }
6732         return getCarrierPrivilegeStatusFromCarrierConfigRules(
6733                 profile.getCarrierPrivilegeStatusForUid(
6734                         phone.getContext().getPackageManager(), uid), uid, phone);
6735     }
6736 
6737     @Override
checkCarrierPrivilegesForPackage(int subId, String pkgName)6738     public int checkCarrierPrivilegesForPackage(int subId, String pkgName) {
6739         enforceReadPrivilegedPermission("checkCarrierPrivilegesForPackage");
6740         if (TextUtils.isEmpty(pkgName)) {
6741             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
6742         }
6743 
6744         int phoneId = SubscriptionManager.getPhoneId(subId);
6745         UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
6746         if (card == null) {
6747             loge("checkCarrierPrivilegesForPackage: No UICC on subId " + subId);
6748             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6749         }
6750         return getCarrierPrivilegeStatusFromCarrierConfigRules(
6751             card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
6752             getPhone(phoneId), pkgName);
6753     }
6754 
6755     @Override
checkCarrierPrivilegesForPackageAnyPhone(String pkgName)6756     public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
6757         // TODO(b/186774706): Remove @RequiresPermission from TelephonyManager API
6758         if (TextUtils.isEmpty(pkgName))
6759             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
6760         int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
6761         for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
6762             UiccCard card = UiccController.getInstance().getUiccCard(i);
6763             if (card == null) {
6764               // No UICC in that slot.
6765               continue;
6766             }
6767 
6768             result = getCarrierPrivilegeStatusFromCarrierConfigRules(
6769                 card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
6770                 getPhone(i), pkgName);
6771             if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
6772                 break;
6773             }
6774         }
6775 
6776         return result;
6777     }
6778 
6779     @Override
getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId)6780     public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
6781         enforceReadPrivilegedPermission("getCarrierPackageNamesForIntentAndPhone");
6782         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
6783             loge("phoneId " + phoneId + " is not valid.");
6784             return null;
6785         }
6786         UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
6787         if (card == null) {
6788             loge("getCarrierPackageNamesForIntentAndPhone: No UICC");
6789             return null ;
6790         }
6791         return card.getCarrierPackageNamesForIntent(mApp.getPackageManager(), intent);
6792     }
6793 
6794     @Override
getPackagesWithCarrierPrivileges(int phoneId)6795     public List<String> getPackagesWithCarrierPrivileges(int phoneId) {
6796         enforceReadPrivilegedPermission("getPackagesWithCarrierPrivileges");
6797         PackageManager pm = mApp.getPackageManager();
6798         List<String> privilegedPackages = new ArrayList<>();
6799         List<PackageInfo> packages = null;
6800         UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
6801         // has UICC in that slot.
6802         if (card != null) {
6803             if (card.hasCarrierPrivilegeRules()) {
6804                 if (packages == null) {
6805                     // Only check packages in user 0 for now
6806                     packages = pm.getInstalledPackagesAsUser(
6807                         PackageManager.MATCH_DISABLED_COMPONENTS
6808                             | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
6809                             | PackageManager.GET_SIGNING_CERTIFICATES,
6810                             UserHandle.SYSTEM.getIdentifier());
6811                 }
6812                 for (int p = packages.size() - 1; p >= 0; p--) {
6813                     PackageInfo pkgInfo = packages.get(p);
6814                     if (pkgInfo != null && pkgInfo.packageName != null
6815                             && card.getCarrierPrivilegeStatus(pkgInfo)
6816                             == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
6817                         privilegedPackages.add(pkgInfo.packageName);
6818                     }
6819                 }
6820             }
6821         }
6822         return privilegedPackages;
6823     }
6824 
6825     @Override
getPackagesWithCarrierPrivilegesForAllPhones()6826     public List<String> getPackagesWithCarrierPrivilegesForAllPhones() {
6827         enforceReadPrivilegedPermission("getPackagesWithCarrierPrivilegesForAllPhones");
6828 
6829         final long identity = Binder.clearCallingIdentity();
6830 
6831         List<String> privilegedPackages = new ArrayList<>();
6832         try {
6833             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
6834                 privilegedPackages.addAll(getPackagesWithCarrierPrivileges(i));
6835             }
6836         } finally {
6837             Binder.restoreCallingIdentity(identity);
6838         }
6839         return privilegedPackages;
6840     }
6841 
getIccId(int subId)6842     private String getIccId(int subId) {
6843         final Phone phone = getPhone(subId);
6844         UiccCard card = phone == null ? null : phone.getUiccCard();
6845         if (card == null) {
6846             return null;
6847         }
6848         String iccId = card.getIccId();
6849         if (TextUtils.isEmpty(iccId)) {
6850             return null;
6851         }
6852         return iccId;
6853     }
6854 
6855     @Override
setCallComposerStatus(int subId, int status)6856     public void setCallComposerStatus(int subId, int status) {
6857         enforceModifyPermission();
6858 
6859         final long identity = Binder.clearCallingIdentity();
6860         try {
6861             Phone phone = getPhone(subId);
6862             if (phone != null) {
6863                 Phone defaultPhone = phone.getImsPhone();
6864                 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
6865                     ImsPhone imsPhone = (ImsPhone) defaultPhone;
6866                     imsPhone.setCallComposerStatus(status);
6867                     ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
6868                             .updateImsServiceConfig();
6869                 }
6870             }
6871         } catch (ImsException e) {
6872             throw new ServiceSpecificException(e.getCode());
6873         }  finally {
6874             Binder.restoreCallingIdentity(identity);
6875         }
6876     }
6877 
6878     @Override
getCallComposerStatus(int subId)6879     public int getCallComposerStatus(int subId) {
6880         enforceReadPrivilegedPermission("getCallComposerStatus");
6881 
6882         final long identity = Binder.clearCallingIdentity();
6883         try {
6884             Phone phone = getPhone(subId);
6885             if (phone != null) {
6886                 Phone defaultPhone = phone.getImsPhone();
6887                 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
6888                     ImsPhone imsPhone = (ImsPhone) defaultPhone;
6889                     return imsPhone.getCallComposerStatus();
6890                 }
6891             }
6892         } finally {
6893             Binder.restoreCallingIdentity(identity);
6894         }
6895         return TelephonyManager.CALL_COMPOSER_STATUS_OFF;
6896     }
6897 
6898     @Override
setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, String number)6899     public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
6900             String number) {
6901         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
6902                 subId, "setLine1NumberForDisplayForSubscriber");
6903 
6904         final long identity = Binder.clearCallingIdentity();
6905         try {
6906             final String iccId = getIccId(subId);
6907             final Phone phone = getPhone(subId);
6908             if (phone == null) {
6909                 return false;
6910             }
6911             final String subscriberId = phone.getSubscriberId();
6912 
6913             if (DBG_MERGE) {
6914                 Rlog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
6915                         + subscriberId + " to " + number);
6916             }
6917 
6918             if (TextUtils.isEmpty(iccId)) {
6919                 return false;
6920             }
6921 
6922             final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
6923 
6924             final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
6925             if (alphaTag == null) {
6926                 editor.remove(alphaTagPrefKey);
6927             } else {
6928                 editor.putString(alphaTagPrefKey, alphaTag);
6929             }
6930 
6931             // Record both the line number and IMSI for this ICCID, since we need to
6932             // track all merged IMSIs based on line number
6933             final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
6934             final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
6935             if (number == null) {
6936                 editor.remove(numberPrefKey);
6937                 editor.remove(subscriberPrefKey);
6938             } else {
6939                 editor.putString(numberPrefKey, number);
6940                 editor.putString(subscriberPrefKey, subscriberId);
6941             }
6942 
6943             editor.commit();
6944             return true;
6945         } finally {
6946             Binder.restoreCallingIdentity(identity);
6947         }
6948     }
6949 
6950     @Override
getLine1NumberForDisplay(int subId, String callingPackage, String callingFeatureId)6951     public String getLine1NumberForDisplay(int subId, String callingPackage,
6952             String callingFeatureId) {
6953         // This is open to apps with WRITE_SMS.
6954         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
6955                 mApp, subId, callingPackage, callingFeatureId, "getLine1NumberForDisplay")) {
6956             if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
6957             return null;
6958         }
6959 
6960         final long identity = Binder.clearCallingIdentity();
6961         try {
6962             String iccId = getIccId(subId);
6963             if (iccId != null) {
6964                 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
6965                 if (DBG_MERGE) {
6966                     log("getLine1NumberForDisplay returning "
6967                             + mTelephonySharedPreferences.getString(numberPrefKey, null));
6968                 }
6969                 return mTelephonySharedPreferences.getString(numberPrefKey, null);
6970             }
6971             if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
6972             return null;
6973         } finally {
6974             Binder.restoreCallingIdentity(identity);
6975         }
6976     }
6977 
6978     @Override
getLine1AlphaTagForDisplay(int subId, String callingPackage, String callingFeatureId)6979     public String getLine1AlphaTagForDisplay(int subId, String callingPackage,
6980             String callingFeatureId) {
6981         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6982                 mApp, subId, callingPackage, callingFeatureId, "getLine1AlphaTagForDisplay")) {
6983             return null;
6984         }
6985 
6986         final long identity = Binder.clearCallingIdentity();
6987         try {
6988             String iccId = getIccId(subId);
6989             if (iccId != null) {
6990                 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
6991                 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
6992             }
6993             return null;
6994         } finally {
6995             Binder.restoreCallingIdentity(identity);
6996         }
6997     }
6998 
6999     @Override
getMergedSubscriberIds(int subId, String callingPackage, String callingFeatureId)7000     public String[] getMergedSubscriberIds(int subId, String callingPackage,
7001             String callingFeatureId) {
7002         // This API isn't public, so no need to provide a valid subscription ID - we're not worried
7003         // about carrier-privileged callers not having access.
7004         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
7005                 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
7006                 callingFeatureId, "getMergedSubscriberIds")) {
7007             return null;
7008         }
7009 
7010         // Clear calling identity, when calling TelephonyManager, because callerUid must be
7011         // the process, where TelephonyManager was instantiated.
7012         // Otherwise AppOps check will fail.
7013         final long identity  = Binder.clearCallingIdentity();
7014         try {
7015             final Context context = mApp;
7016             final TelephonyManager tele = TelephonyManager.from(context);
7017             final SubscriptionManager sub = SubscriptionManager.from(context);
7018 
7019             // Figure out what subscribers are currently active
7020             final ArraySet<String> activeSubscriberIds = new ArraySet<>();
7021 
7022             // Only consider subs which match the current subId
7023             // This logic can be simplified. See b/131189269 for progress.
7024             if (isActiveSubscription(subId)) {
7025                 activeSubscriberIds.add(tele.getSubscriberId(subId));
7026             }
7027 
7028             // First pass, find a number override for an active subscriber
7029             String mergeNumber = null;
7030             final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
7031             for (String key : prefs.keySet()) {
7032                 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
7033                     final String subscriberId = (String) prefs.get(key);
7034                     if (activeSubscriberIds.contains(subscriberId)) {
7035                         final String iccId = key.substring(
7036                                 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
7037                         final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
7038                         mergeNumber = (String) prefs.get(numberKey);
7039                         if (DBG_MERGE) {
7040                             Rlog.d(LOG_TAG, "Found line number " + mergeNumber
7041                                     + " for active subscriber " + subscriberId);
7042                         }
7043                         if (!TextUtils.isEmpty(mergeNumber)) {
7044                             break;
7045                         }
7046                     }
7047                 }
7048             }
7049 
7050             // Shortcut when no active merged subscribers
7051             if (TextUtils.isEmpty(mergeNumber)) {
7052                 return null;
7053             }
7054 
7055             // Second pass, find all subscribers under that line override
7056             final ArraySet<String> result = new ArraySet<>();
7057             for (String key : prefs.keySet()) {
7058                 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
7059                     final String number = (String) prefs.get(key);
7060                     if (mergeNumber.equals(number)) {
7061                         final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
7062                         final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
7063                         final String subscriberId = (String) prefs.get(subscriberKey);
7064                         if (!TextUtils.isEmpty(subscriberId)) {
7065                             result.add(subscriberId);
7066                         }
7067                     }
7068                 }
7069             }
7070 
7071             final String[] resultArray = result.toArray(new String[result.size()]);
7072             Arrays.sort(resultArray);
7073             if (DBG_MERGE) {
7074                 Rlog.d(LOG_TAG,
7075                         "Found subscribers " + Arrays.toString(resultArray) + " after merge");
7076             }
7077             return resultArray;
7078         } finally {
7079             Binder.restoreCallingIdentity(identity);
7080         }
7081     }
7082 
7083     @Override
getMergedImsisFromGroup(int subId, String callingPackage)7084     public String[] getMergedImsisFromGroup(int subId, String callingPackage) {
7085         enforceReadPrivilegedPermission("getMergedImsisFromGroup");
7086 
7087         final long identity = Binder.clearCallingIdentity();
7088         try {
7089             final TelephonyManager telephonyManager = mApp.getSystemService(
7090                     TelephonyManager.class);
7091             String subscriberId = telephonyManager.getSubscriberId(subId);
7092             if (subscriberId == null) {
7093                 if (DBG) {
7094                     log("getMergedImsisFromGroup can't find subscriberId for subId "
7095                             + subId);
7096                 }
7097                 return null;
7098             }
7099 
7100             final SubscriptionInfo info = SubscriptionController.getInstance()
7101                     .getSubscriptionInfo(subId);
7102             final ParcelUuid groupUuid = info.getGroupUuid();
7103             // If it doesn't belong to any group, return just subscriberId of itself.
7104             if (groupUuid == null) {
7105                 return new String[]{subscriberId};
7106             }
7107 
7108             // Get all subscriberIds from the group.
7109             final List<String> mergedSubscriberIds = new ArrayList<>();
7110             final List<SubscriptionInfo> groupInfos = SubscriptionController.getInstance()
7111                     .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
7112                             mApp.getAttributionTag());
7113             for (SubscriptionInfo subInfo : groupInfos) {
7114                 subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
7115                 if (subscriberId != null) {
7116                     mergedSubscriberIds.add(subscriberId);
7117                 }
7118             }
7119 
7120             return mergedSubscriberIds.toArray(new String[mergedSubscriberIds.size()]);
7121         } finally {
7122             Binder.restoreCallingIdentity(identity);
7123 
7124         }
7125     }
7126 
7127     @Override
setOperatorBrandOverride(int subId, String brand)7128     public boolean setOperatorBrandOverride(int subId, String brand) {
7129         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
7130                 subId, "setOperatorBrandOverride");
7131 
7132         final long identity = Binder.clearCallingIdentity();
7133         try {
7134             final Phone phone = getPhone(subId);
7135             return phone == null ? false : phone.setOperatorBrandOverride(brand);
7136         } finally {
7137             Binder.restoreCallingIdentity(identity);
7138         }
7139     }
7140 
7141     @Override
setRoamingOverride(int subId, List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList)7142     public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
7143             List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
7144             List<String> cdmaNonRoamingList) {
7145         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
7146                 mApp, subId, "setRoamingOverride");
7147 
7148         final long identity = Binder.clearCallingIdentity();
7149         try {
7150             final Phone phone = getPhone(subId);
7151             if (phone == null) {
7152                 return false;
7153             }
7154             return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
7155                     cdmaNonRoamingList);
7156         } finally {
7157             Binder.restoreCallingIdentity(identity);
7158         }
7159     }
7160 
7161     @Override
7162     @Deprecated
invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp)7163     public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
7164         enforceModifyPermission();
7165 
7166         int returnValue = 0;
7167         try {
7168             AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
7169             if(result.exception == null) {
7170                 if (result.result != null) {
7171                     byte[] responseData = (byte[])(result.result);
7172                     if(responseData.length > oemResp.length) {
7173                         Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
7174                                 responseData.length +  "bytes. Buffer Size is " +
7175                                 oemResp.length + "bytes.");
7176                     }
7177                     System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
7178                     returnValue = responseData.length;
7179                 }
7180             } else {
7181                 CommandException ex = (CommandException) result.exception;
7182                 returnValue = ex.getCommandError().ordinal();
7183                 if(returnValue > 0) returnValue *= -1;
7184             }
7185         } catch (RuntimeException e) {
7186             Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
7187             returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
7188             if(returnValue > 0) returnValue *= -1;
7189         }
7190 
7191         return returnValue;
7192     }
7193 
7194     @Override
getRadioAccessFamily(int phoneId, String callingPackage)7195     public int getRadioAccessFamily(int phoneId, String callingPackage) {
7196         Phone phone = PhoneFactory.getPhone(phoneId);
7197         try {
7198             TelephonyPermissions
7199                     .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
7200                             mApp, phone.getSubId(), "getRadioAccessFamily");
7201         } catch (SecurityException e) {
7202             EventLog.writeEvent(0x534e4554, "150857259", -1, "Missing Permission");
7203             throw e;
7204         }
7205         int raf = RadioAccessFamily.RAF_UNKNOWN;
7206         if (phone == null) {
7207             return raf;
7208         }
7209         final long identity = Binder.clearCallingIdentity();
7210         try {
7211             TelephonyPermissions
7212                     .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
7213                             mApp, phone.getSubId(), "getRadioAccessFamily");
7214             raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
7215         } finally {
7216             Binder.restoreCallingIdentity(identity);
7217         }
7218         return raf;
7219     }
7220 
7221     @Override
uploadCallComposerPicture(int subscriptionId, String callingPackage, String contentType, ParcelFileDescriptor fd, ResultReceiver callback)7222     public void uploadCallComposerPicture(int subscriptionId, String callingPackage,
7223             String contentType, ParcelFileDescriptor fd, ResultReceiver callback) {
7224         try {
7225             if (!Objects.equals(mApp.getPackageManager().getPackageUid(callingPackage, 0),
7226                     Binder.getCallingUid())) {
7227                 throw new SecurityException("Invalid package:" + callingPackage);
7228             }
7229         } catch (PackageManager.NameNotFoundException e) {
7230             throw new SecurityException("Invalid package:" + callingPackage);
7231         }
7232         RoleManager rm = mApp.getSystemService(RoleManager.class);
7233         List<String> dialerRoleHolders = rm.getRoleHolders(RoleManager.ROLE_DIALER);
7234         if (!dialerRoleHolders.contains(callingPackage)) {
7235             throw new SecurityException("App must be the dialer role holder to"
7236                     + " upload a call composer pic");
7237         }
7238 
7239         Executors.newSingleThreadExecutor().execute(() -> {
7240             ByteArrayOutputStream output = new ByteArrayOutputStream(
7241                     (int) TelephonyManager.getMaximumCallComposerPictureSize());
7242             InputStream input = new ParcelFileDescriptor.AutoCloseInputStream(fd);
7243             boolean readUntilEnd = false;
7244             int totalBytesRead = 0;
7245             byte[] buffer = new byte[16 * 1024];
7246             while (true) {
7247                 int numRead;
7248                 try {
7249                     numRead = input.read(buffer);
7250                 } catch (IOException e) {
7251                     try {
7252                         fd.checkError();
7253                         callback.send(TelephonyManager.CallComposerException.ERROR_INPUT_CLOSED,
7254                                 null);
7255                     } catch (IOException e1) {
7256                         // This means that the other side closed explicitly with an error. If this
7257                         // happens, log and ignore.
7258                         loge("Remote end of call composer picture pipe closed: " + e1);
7259                     }
7260                     break;
7261                 }
7262                 if (numRead == -1) {
7263                     readUntilEnd = true;
7264                     break;
7265                 }
7266                 totalBytesRead += numRead;
7267                 if (totalBytesRead > TelephonyManager.getMaximumCallComposerPictureSize()) {
7268                     loge("Too many bytes read for call composer picture: " + totalBytesRead);
7269                     try {
7270                         input.close();
7271                     } catch (IOException e) {
7272                         // ignore
7273                     }
7274                     break;
7275                 }
7276                 output.write(buffer, 0, numRead);
7277             }
7278             // Generally, the remote end will close the file descriptors. The only case where we
7279             // close is above, where the picture size is too big.
7280 
7281             try {
7282                 fd.checkError();
7283             } catch (IOException e) {
7284                 loge("Remote end for call composer closed with an error: " + e);
7285                 return;
7286             }
7287 
7288             if (!readUntilEnd) {
7289                 loge("Did not finish reading entire image; aborting");
7290                 return;
7291             }
7292 
7293             ImageData imageData = new ImageData(output.toByteArray(), contentType, null);
7294             CallComposerPictureManager.getInstance(mApp, subscriptionId).handleUploadToServer(
7295                     new CallComposerPictureTransfer.Factory() {},
7296                     imageData,
7297                     (result) -> {
7298                         if (result.first != null) {
7299                             ParcelUuid parcelUuid = new ParcelUuid(result.first);
7300                             Bundle outputResult = new Bundle();
7301                             outputResult.putParcelable(
7302                                     TelephonyManager.KEY_CALL_COMPOSER_PICTURE_HANDLE, parcelUuid);
7303                             callback.send(TelephonyManager.CallComposerException.SUCCESS,
7304                                     outputResult);
7305                         } else {
7306                             callback.send(result.second, null);
7307                         }
7308                     }
7309             );
7310         });
7311     }
7312 
7313     @Override
enableVideoCalling(boolean enable)7314     public void enableVideoCalling(boolean enable) {
7315         final Phone defaultPhone = getDefaultPhone();
7316         enforceModifyPermission();
7317 
7318         final long identity = Binder.clearCallingIdentity();
7319         try {
7320             ImsManager.getInstance(defaultPhone.getContext(),
7321                     defaultPhone.getPhoneId()).setVtSetting(enable);
7322         } finally {
7323             Binder.restoreCallingIdentity(identity);
7324         }
7325     }
7326 
7327     @Override
isVideoCallingEnabled(String callingPackage, String callingFeatureId)7328     public boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId) {
7329         final Phone defaultPhone = getDefaultPhone();
7330         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
7331                 callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
7332             return false;
7333         }
7334 
7335         final long identity = Binder.clearCallingIdentity();
7336         try {
7337             // Check the user preference and the  system-level IMS setting. Even if the user has
7338             // enabled video calling, if IMS is disabled we aren't able to support video calling.
7339             // In the long run, we may instead need to check if there exists a connection service
7340             // which can support video calling.
7341             ImsManager imsManager =
7342                     ImsManager.getInstance(defaultPhone.getContext(), defaultPhone.getPhoneId());
7343             return imsManager.isVtEnabledByPlatform()
7344                     && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
7345                     && imsManager.isVtEnabledByUser();
7346         } finally {
7347             Binder.restoreCallingIdentity(identity);
7348         }
7349     }
7350 
7351     @Override
canChangeDtmfToneLength(int subId, String callingPackage, String callingFeatureId)7352     public boolean canChangeDtmfToneLength(int subId, String callingPackage,
7353             String callingFeatureId) {
7354         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
7355                 mApp, subId, callingPackage, callingFeatureId,
7356                 "isVideoCallingEnabled")) {
7357             return false;
7358         }
7359 
7360         final long identity = Binder.clearCallingIdentity();
7361         try {
7362             CarrierConfigManager configManager =
7363                     (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
7364             return configManager.getConfigForSubId(subId)
7365                     .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
7366         } finally {
7367             Binder.restoreCallingIdentity(identity);
7368         }
7369     }
7370 
7371     @Override
isWorldPhone(int subId, String callingPackage, String callingFeatureId)7372     public boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId) {
7373         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
7374                 mApp, subId, callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
7375             return false;
7376         }
7377 
7378         final long identity = Binder.clearCallingIdentity();
7379         try {
7380             CarrierConfigManager configManager =
7381                     (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
7382             return configManager.getConfigForSubId(subId)
7383                     .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
7384         } finally {
7385             Binder.restoreCallingIdentity(identity);
7386         }
7387     }
7388 
7389     @Override
isTtyModeSupported()7390     public boolean isTtyModeSupported() {
7391         TelecomManager telecomManager = mApp.getSystemService(TelecomManager.class);
7392         return telecomManager.isTtySupported();
7393     }
7394 
7395     @Override
isHearingAidCompatibilitySupported()7396     public boolean isHearingAidCompatibilitySupported() {
7397         final long identity = Binder.clearCallingIdentity();
7398         try {
7399             return mApp.getResources().getBoolean(R.bool.hac_enabled);
7400         } finally {
7401             Binder.restoreCallingIdentity(identity);
7402         }
7403     }
7404 
7405     /**
7406      * Determines whether the device currently supports RTT (Real-time text). Based both on carrier
7407      * support for the feature and device firmware support.
7408      *
7409      * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
7410      */
7411     @Override
isRttSupported(int subscriptionId)7412     public boolean isRttSupported(int subscriptionId) {
7413         final long identity = Binder.clearCallingIdentity();
7414         final Phone phone = getPhone(subscriptionId);
7415         if (phone == null) {
7416             loge("isRttSupported: no Phone found. Invalid subId:" + subscriptionId);
7417             return false;
7418         }
7419         try {
7420             boolean isCarrierSupported = mApp.getCarrierConfigForSubId(subscriptionId).getBoolean(
7421                     CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
7422             boolean isDeviceSupported =
7423                     phone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
7424             return isCarrierSupported && isDeviceSupported;
7425         } finally {
7426             Binder.restoreCallingIdentity(identity);
7427         }
7428     }
7429 
7430     /**
7431      * Determines whether the user has turned on RTT. If the carrier wants to ignore the user-set
7432      * RTT setting, will return true if the device and carrier both support RTT.
7433      * Otherwise. only returns true if the device and carrier both also support RTT.
7434      */
isRttEnabled(int subscriptionId)7435     public boolean isRttEnabled(int subscriptionId) {
7436         final long identity = Binder.clearCallingIdentity();
7437         try {
7438             boolean isRttSupported = isRttSupported(subscriptionId);
7439             boolean isUserRttSettingOn = Settings.Secure.getInt(
7440                     mApp.getContentResolver(), Settings.Secure.RTT_CALLING_MODE, 0) != 0;
7441             boolean shouldIgnoreUserRttSetting = mApp.getCarrierConfigForSubId(subscriptionId)
7442                     .getBoolean(CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL);
7443             return isRttSupported && (isUserRttSettingOn || shouldIgnoreUserRttSetting);
7444         } finally {
7445             Binder.restoreCallingIdentity(identity);
7446         }
7447     }
7448 
7449     @Deprecated
7450     @Override
getDeviceId(String callingPackage)7451     public String getDeviceId(String callingPackage) {
7452         return getDeviceIdWithFeature(callingPackage, null);
7453     }
7454 
7455     /**
7456      * Returns the unique device ID of phone, for example, the IMEI for
7457      * GSM and the MEID for CDMA phones. Return null if device ID is not available.
7458      *
7459      * <p>Requires Permission:
7460      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
7461      */
7462     @Override
getDeviceIdWithFeature(String callingPackage, String callingFeatureId)7463     public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
7464         final Phone phone = PhoneFactory.getPhone(0);
7465         if (phone == null) {
7466             return null;
7467         }
7468         int subId = phone.getSubId();
7469         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
7470                 callingPackage, callingFeatureId, "getDeviceId")) {
7471             return null;
7472         }
7473 
7474         final long identity = Binder.clearCallingIdentity();
7475         try {
7476             return phone.getDeviceId();
7477         } finally {
7478             Binder.restoreCallingIdentity(identity);
7479         }
7480     }
7481 
7482     /**
7483      * {@hide}
7484      * Returns the IMS Registration Status on a particular subid
7485      *
7486      * @param subId
7487      */
isImsRegistered(int subId)7488     public boolean isImsRegistered(int subId) {
7489         Phone phone = getPhone(subId);
7490         if (phone != null) {
7491             return phone.isImsRegistered();
7492         } else {
7493             return false;
7494         }
7495     }
7496 
7497     @Override
getSubIdForPhoneAccount(PhoneAccount phoneAccount)7498     public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
7499         final long identity = Binder.clearCallingIdentity();
7500         try {
7501             return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
7502         } finally {
7503             Binder.restoreCallingIdentity(identity);
7504         }
7505     }
7506 
7507     @Override
getSubIdForPhoneAccountHandle( PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId)7508     public int getSubIdForPhoneAccountHandle(
7509             PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId) {
7510         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, getDefaultSubscription(),
7511                 callingPackage, callingFeatureId, "getSubIdForPhoneAccountHandle")) {
7512             throw new SecurityException("Requires READ_PHONE_STATE permission.");
7513         }
7514         final long identity = Binder.clearCallingIdentity();
7515         try {
7516             return PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle);
7517         } finally {
7518             Binder.restoreCallingIdentity(identity);
7519         }
7520     }
7521 
7522     @Override
getPhoneAccountHandleForSubscriptionId(int subscriptionId)7523     public @Nullable PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId) {
7524         TelephonyPermissions
7525                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
7526                 mApp,
7527                 subscriptionId,
7528                 "getPhoneAccountHandleForSubscriptionId, " + "subscriptionId: " + subscriptionId);
7529         final long identity = Binder.clearCallingIdentity();
7530         try {
7531             Phone phone = getPhone(subscriptionId);
7532             if (phone == null) {
7533                 return null;
7534             }
7535             return PhoneUtils.makePstnPhoneAccountHandle(phone);
7536         } finally {
7537             Binder.restoreCallingIdentity(identity);
7538         }
7539     }
7540 
7541     /**
7542      * @return the VoWiFi calling availability.
7543      */
isWifiCallingAvailable(int subId)7544     public boolean isWifiCallingAvailable(int subId) {
7545         final long identity = Binder.clearCallingIdentity();
7546         try {
7547             Phone phone = getPhone(subId);
7548             if (phone != null) {
7549                 return phone.isWifiCallingEnabled();
7550             } else {
7551                 return false;
7552             }
7553         } finally {
7554             Binder.restoreCallingIdentity(identity);
7555         }
7556     }
7557 
7558     /**
7559      * @return the VT calling availability.
7560      */
isVideoTelephonyAvailable(int subId)7561     public boolean isVideoTelephonyAvailable(int subId) {
7562         final long identity = Binder.clearCallingIdentity();
7563         try {
7564             Phone phone = getPhone(subId);
7565             if (phone != null) {
7566                 return phone.isVideoEnabled();
7567             } else {
7568                 return false;
7569             }
7570         } finally {
7571             Binder.restoreCallingIdentity(identity);
7572         }
7573     }
7574 
7575     /**
7576      * @return the IMS registration technology for the MMTEL feature. Valid return values are
7577      * defined in {@link ImsRegistrationImplBase}.
7578      */
getImsRegTechnologyForMmTel(int subId)7579     public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
7580         final long identity = Binder.clearCallingIdentity();
7581         try {
7582             Phone phone = getPhone(subId);
7583             if (phone != null) {
7584                 return phone.getImsRegistrationTech();
7585             } else {
7586                 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
7587             }
7588         } finally {
7589             Binder.restoreCallingIdentity(identity);
7590         }
7591     }
7592 
7593     @Override
factoryReset(int subId)7594     public void factoryReset(int subId) {
7595         enforceSettingsPermission();
7596         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
7597             return;
7598         }
7599         Phone defaultPhone = getDefaultPhone();
7600         if (defaultPhone != null) {
7601             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7602                     mApp, getDefaultPhone().getSubId(), "factoryReset");
7603         }
7604         final long identity = Binder.clearCallingIdentity();
7605 
7606         try {
7607             if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
7608                     UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
7609                 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_USER,
7610                         getDefaultDataEnabled());
7611                 setNetworkSelectionModeAutomatic(subId);
7612                 Phone phone = getPhone(subId);
7613                 cleanUpAllowedNetworkTypes(phone, subId);
7614                 setDataRoamingEnabled(subId, getDefaultDataRoamingEnabled(subId));
7615                 getPhone(subId).resetCarrierKeysForImsiEncryption();
7616             }
7617             // There has been issues when Sms raw table somehow stores orphan
7618             // fragments. They lead to garbled message when new fragments come
7619             // in and combined with those stale ones. In case this happens again,
7620             // user can reset all network settings which will clean up this table.
7621             cleanUpSmsRawTable(getDefaultPhone().getContext());
7622             // Clean up IMS settings as well here.
7623             int slotId = getSlotIndex(subId);
7624             if (slotId > SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
7625                 ImsManager.getInstance(mApp, slotId).factoryReset();
7626             }
7627 
7628             if (defaultPhone == null) {
7629                 return;
7630             }
7631             // Erase modem config if erase modem on network setting is enabled.
7632             String configValue = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_TELEPHONY,
7633                     RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED);
7634             if (configValue != null && Boolean.parseBoolean(configValue)) {
7635                 sendEraseModemConfig(defaultPhone);
7636             }
7637 
7638             sendEraseDataInSharedPreferences(defaultPhone);
7639         } finally {
7640             Binder.restoreCallingIdentity(identity);
7641         }
7642     }
7643 
7644     @VisibleForTesting
cleanUpAllowedNetworkTypes(Phone phone, int subId)7645     void cleanUpAllowedNetworkTypes(Phone phone, int subId) {
7646         if (phone == null || !SubscriptionManager.isUsableSubscriptionId(subId)) {
7647             return;
7648         }
7649         long defaultNetworkType = RadioAccessFamily.getRafFromNetworkType(
7650                 RILConstants.PREFERRED_NETWORK_MODE);
7651         SubscriptionManager.setSubscriptionProperty(subId,
7652                 SubscriptionManager.ALLOWED_NETWORK_TYPES,
7653                 "user=" + defaultNetworkType);
7654         phone.loadAllowedNetworksFromSubscriptionDatabase();
7655         phone.setAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER,
7656                 defaultNetworkType, null);
7657     }
7658 
cleanUpSmsRawTable(Context context)7659     private void cleanUpSmsRawTable(Context context) {
7660         ContentResolver resolver = context.getContentResolver();
7661         Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
7662         resolver.delete(uri, null, null);
7663     }
7664 
7665     @Override
getSimLocaleForSubscriber(int subId)7666     public String getSimLocaleForSubscriber(int subId) {
7667         enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
7668         final Phone phone = getPhone(subId);
7669         if (phone == null) {
7670             log("getSimLocaleForSubscriber, invalid subId");
7671             return null;
7672         }
7673         final long identity = Binder.clearCallingIdentity();
7674         try {
7675             final SubscriptionInfo info = mSubscriptionController.getActiveSubscriptionInfo(subId,
7676                     phone.getContext().getOpPackageName(), phone.getContext().getAttributionTag());
7677             if (info == null) {
7678                 log("getSimLocaleForSubscriber, inactive subId: " + subId);
7679                 return null;
7680             }
7681             // Try and fetch the locale from the carrier properties or from the SIM language
7682             // preferences (EF-PL and EF-LI)...
7683             final int mcc = info.getMcc();
7684             String simLanguage = null;
7685             final Locale localeFromDefaultSim = phone.getLocaleFromSimAndCarrierPrefs();
7686             if (localeFromDefaultSim != null) {
7687                 if (!localeFromDefaultSim.getCountry().isEmpty()) {
7688                     if (DBG) log("Using locale from subId: " + subId + " locale: "
7689                             + localeFromDefaultSim);
7690                     return localeFromDefaultSim.toLanguageTag();
7691                 } else {
7692                     simLanguage = localeFromDefaultSim.getLanguage();
7693                 }
7694             }
7695 
7696             // The SIM language preferences only store a language (e.g. fr = French), not an
7697             // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
7698             // the SIM and carrier preferences does not include a country we add the country
7699             // determined from the SIM MCC to provide an exact locale.
7700             final Locale mccLocale = LocaleUtils.getLocaleFromMcc(mApp, mcc, simLanguage);
7701             if (mccLocale != null) {
7702                 if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale);
7703                 return mccLocale.toLanguageTag();
7704             }
7705 
7706             if (DBG) log("No locale found - returning null");
7707             return null;
7708         } finally {
7709             Binder.restoreCallingIdentity(identity);
7710         }
7711     }
7712 
getAllSubscriptionInfoList()7713     private List<SubscriptionInfo> getAllSubscriptionInfoList() {
7714         return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName(),
7715                 mApp.getAttributionTag());
7716     }
7717 
7718     /**
7719      * NOTE: this method assumes permission checks are done and caller identity has been cleared.
7720      */
getActiveSubscriptionInfoListPrivileged()7721     private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
7722         return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName(),
7723                 mApp.getAttributionTag());
7724     }
7725 
7726     private final ModemActivityInfo mLastModemActivityInfo =
7727             new ModemActivityInfo(0, 0, 0, new int[ModemActivityInfo.getNumTxPowerLevels()], 0);
7728 
7729     /**
7730      * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
7731      * representing the state of the modem.
7732      *
7733      * NOTE: The underlying implementation clears the modem state, so there should only ever be one
7734      * caller to it. Everyone should call this class to get cumulative data.
7735      * @hide
7736      */
7737     @Override
requestModemActivityInfo(ResultReceiver result)7738     public void requestModemActivityInfo(ResultReceiver result) {
7739         enforceModifyPermission();
7740         WorkSource workSource = getWorkSource(Binder.getCallingUid());
7741 
7742         final long identity = Binder.clearCallingIdentity();
7743         try {
7744             sendRequestAsync(CMD_GET_MODEM_ACTIVITY_INFO, result, null, workSource);
7745         } finally {
7746             Binder.restoreCallingIdentity(identity);
7747         }
7748     }
7749 
7750     // Checks that ModemActivityInfo is valid. Sleep time, Idle time, Rx time and Tx time should be
7751     // less than total activity duration.
isModemActivityInfoValid(ModemActivityInfo info)7752     private boolean isModemActivityInfoValid(ModemActivityInfo info) {
7753         if (info == null) {
7754             return false;
7755         }
7756         int activityDurationMs =
7757                 (int) (info.getTimestampMillis() - mLastModemActivityInfo.getTimestampMillis());
7758         int totalTxTimeMs = Arrays.stream(info.getTransmitTimeMillis()).sum();
7759 
7760         return (info.isValid()
7761             && (info.getSleepTimeMillis() <= activityDurationMs)
7762             && (info.getIdleTimeMillis() <= activityDurationMs)
7763             && (info.getReceiveTimeMillis() <= activityDurationMs)
7764             && (totalTxTimeMs <= activityDurationMs));
7765     }
7766 
7767     /**
7768      * {@hide}
7769      * Returns the service state information on specified subscription.
7770      */
7771     @Override
getServiceStateForSubscriber(int subId, String callingPackage, String callingFeatureId)7772     public ServiceState getServiceStateForSubscriber(int subId, String callingPackage,
7773             String callingFeatureId) {
7774         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
7775                 mApp, subId, callingPackage, callingFeatureId, "getServiceStateForSubscriber")) {
7776             return null;
7777         }
7778 
7779         LocationAccessPolicy.LocationPermissionResult fineLocationResult =
7780                 LocationAccessPolicy.checkLocationPermission(mApp,
7781                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
7782                                 .setCallingPackage(callingPackage)
7783                                 .setCallingFeatureId(callingFeatureId)
7784                                 .setCallingPid(Binder.getCallingPid())
7785                                 .setCallingUid(Binder.getCallingUid())
7786                                 .setMethod("getServiceStateForSubscriber")
7787                                 .setLogAsInfo(true)
7788                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
7789                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
7790                                 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
7791                                 .build());
7792 
7793         LocationAccessPolicy.LocationPermissionResult coarseLocationResult =
7794                 LocationAccessPolicy.checkLocationPermission(mApp,
7795                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
7796                                 .setCallingPackage(callingPackage)
7797                                 .setCallingFeatureId(callingFeatureId)
7798                                 .setCallingPid(Binder.getCallingPid())
7799                                 .setCallingUid(Binder.getCallingUid())
7800                                 .setMethod("getServiceStateForSubscriber")
7801                                 .setLogAsInfo(true)
7802                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
7803                                 .setMinSdkVersionForFine(Integer.MAX_VALUE)
7804                                 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
7805                                 .build());
7806         // We don't care about hard or soft here -- all we need to know is how much info to scrub.
7807         boolean hasFinePermission =
7808                 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
7809         boolean hasCoarsePermission =
7810                 coarseLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
7811 
7812         final Phone phone = getPhone(subId);
7813         if (phone == null) {
7814             return null;
7815         }
7816 
7817         final long identity = Binder.clearCallingIdentity();
7818 
7819         boolean isCallingPackageDataService = phone.getDataServicePackages()
7820                 .contains(callingPackage);
7821         try {
7822             // isActiveSubId requires READ_PHONE_STATE, which we already check for above
7823             if (!mSubscriptionController.isActiveSubId(subId, callingPackage, callingFeatureId)) {
7824                 Rlog.d(LOG_TAG,
7825                         "getServiceStateForSubscriber returning null for inactive subId=" + subId);
7826                 return null;
7827             }
7828 
7829             ServiceState ss = phone.getServiceState();
7830 
7831             // Scrub out the location info in ServiceState depending on what level of access
7832             // the caller has.
7833             if (hasFinePermission || isCallingPackageDataService) return ss;
7834             if (hasCoarsePermission) return ss.createLocationInfoSanitizedCopy(false);
7835             return ss.createLocationInfoSanitizedCopy(true);
7836         } finally {
7837             Binder.restoreCallingIdentity(identity);
7838         }
7839     }
7840 
7841     /**
7842      * Returns the URI for the per-account voicemail ringtone set in Phone settings.
7843      *
7844      * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
7845      * voicemail ringtone.
7846      * @return The URI for the ringtone to play when receiving a voicemail from a specific
7847      * PhoneAccount.
7848      */
7849     @Override
getVoicemailRingtoneUri(PhoneAccountHandle accountHandle)7850     public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
7851         final long identity = Binder.clearCallingIdentity();
7852         try {
7853             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
7854             if (phone == null) {
7855                 phone = getDefaultPhone();
7856             }
7857 
7858             return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
7859         } finally {
7860             Binder.restoreCallingIdentity(identity);
7861         }
7862     }
7863 
7864     /**
7865      * Sets the per-account voicemail ringtone.
7866      *
7867      * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
7868      * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
7869      *
7870      * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
7871      * voicemail ringtone.
7872      * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
7873      * PhoneAccount.
7874      */
7875     @Override
setVoicemailRingtoneUri(String callingPackage, PhoneAccountHandle phoneAccountHandle, Uri uri)7876     public void setVoicemailRingtoneUri(String callingPackage,
7877             PhoneAccountHandle phoneAccountHandle, Uri uri) {
7878         final Phone defaultPhone = getDefaultPhone();
7879         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
7880         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
7881         if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
7882             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7883                     mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
7884                     "setVoicemailRingtoneUri");
7885         }
7886 
7887         final long identity = Binder.clearCallingIdentity();
7888         try {
7889             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
7890             if (phone == null) {
7891                 phone = defaultPhone;
7892             }
7893             VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
7894         } finally {
7895             Binder.restoreCallingIdentity(identity);
7896         }
7897     }
7898 
7899     /**
7900      * Returns whether vibration is set for voicemail notification in Phone settings.
7901      *
7902      * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
7903      * voicemail vibration setting.
7904      * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
7905      */
7906     @Override
isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle)7907     public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
7908         final long identity = Binder.clearCallingIdentity();
7909         try {
7910             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
7911             if (phone == null) {
7912                 phone = getDefaultPhone();
7913             }
7914 
7915             return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
7916         } finally {
7917             Binder.restoreCallingIdentity(identity);
7918         }
7919     }
7920 
7921     /**
7922      * Sets the per-account voicemail vibration.
7923      *
7924      * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
7925      * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
7926      *
7927      * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
7928      * voicemail vibration setting.
7929      * @param enabled Whether to enable or disable vibration for voicemail notifications from a
7930      * specific PhoneAccount.
7931      */
7932     @Override
setVoicemailVibrationEnabled(String callingPackage, PhoneAccountHandle phoneAccountHandle, boolean enabled)7933     public void setVoicemailVibrationEnabled(String callingPackage,
7934             PhoneAccountHandle phoneAccountHandle, boolean enabled) {
7935         final Phone defaultPhone = getDefaultPhone();
7936         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
7937         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
7938         if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
7939             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7940                     mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
7941                     "setVoicemailVibrationEnabled");
7942         }
7943 
7944         final long identity = Binder.clearCallingIdentity();
7945         try {
7946             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
7947             if (phone == null) {
7948                 phone = defaultPhone;
7949             }
7950             VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
7951         } finally {
7952             Binder.restoreCallingIdentity(identity);
7953         }
7954     }
7955 
7956     /**
7957      * Make sure either called from same process as self (phone) or IPC caller has read privilege.
7958      *
7959      * @throws SecurityException if the caller does not have the required permission
7960      */
enforceReadPrivilegedPermission(String message)7961     private void enforceReadPrivilegedPermission(String message) {
7962         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
7963                 message);
7964     }
7965 
7966     /**
7967      * Make sure either called from same process as self (phone) or IPC caller has send SMS
7968      * permission.
7969      *
7970      * @throws SecurityException if the caller does not have the required permission
7971      */
enforceSendSmsPermission()7972     private void enforceSendSmsPermission() {
7973         mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
7974     }
7975 
7976     /**
7977      * Make sure called from the package in charge of visual voicemail.
7978      *
7979      * @throws SecurityException if the caller is not the visual voicemail package.
7980      */
enforceVisualVoicemailPackage(String callingPackage, int subId)7981     private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
7982         final long identity = Binder.clearCallingIdentity();
7983         try {
7984             ComponentName componentName =
7985                     RemoteVvmTaskManager.getRemotePackage(mApp, subId);
7986             if (componentName == null) {
7987                 throw new SecurityException(
7988                         "Caller not current active visual voicemail package[null]");
7989             }
7990             String vvmPackage = componentName.getPackageName();
7991             if (!callingPackage.equals(vvmPackage)) {
7992                 throw new SecurityException("Caller not current active visual voicemail package["
7993                         + vvmPackage + "]");
7994             }
7995         } finally {
7996             Binder.restoreCallingIdentity(identity);
7997         }
7998     }
7999 
8000     /**
8001      * Return the application ID for the app type.
8002      *
8003      * @param subId the subscription ID that this request applies to.
8004      * @param appType the uicc app type.
8005      * @return Application ID for specificied app type, or null if no uicc.
8006      */
8007     @Override
getAidForAppType(int subId, int appType)8008     public String getAidForAppType(int subId, int appType) {
8009         enforceReadPrivilegedPermission("getAidForAppType");
8010         Phone phone = getPhone(subId);
8011 
8012         final long identity = Binder.clearCallingIdentity();
8013         try {
8014             if (phone == null) {
8015                 return null;
8016             }
8017             String aid = null;
8018             try {
8019                 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
8020                         .getApplicationByType(appType).getAid();
8021             } catch (Exception e) {
8022                 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
8023             }
8024             return aid;
8025         } finally {
8026             Binder.restoreCallingIdentity(identity);
8027         }
8028     }
8029 
8030     /**
8031      * Return the Electronic Serial Number.
8032      *
8033      * @param subId the subscription ID that this request applies to.
8034      * @return ESN or null if error.
8035      */
8036     @Override
getEsn(int subId)8037     public String getEsn(int subId) {
8038         enforceReadPrivilegedPermission("getEsn");
8039         Phone phone = getPhone(subId);
8040 
8041         final long identity = Binder.clearCallingIdentity();
8042         try {
8043             if (phone == null) {
8044                 return null;
8045             }
8046             String esn = null;
8047             try {
8048                 esn = phone.getEsn();
8049             } catch (Exception e) {
8050                 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
8051             }
8052             return esn;
8053         } finally {
8054             Binder.restoreCallingIdentity(identity);
8055         }
8056     }
8057 
8058     /**
8059      * Return the Preferred Roaming List Version.
8060      *
8061      * @param subId the subscription ID that this request applies to.
8062      * @return PRLVersion or null if error.
8063      */
8064     @Override
getCdmaPrlVersion(int subId)8065     public String getCdmaPrlVersion(int subId) {
8066         enforceReadPrivilegedPermission("getCdmaPrlVersion");
8067         Phone phone = getPhone(subId);
8068 
8069         final long identity = Binder.clearCallingIdentity();
8070         try {
8071             if (phone == null) {
8072                 return null;
8073             }
8074             String cdmaPrlVersion = null;
8075             try {
8076                 cdmaPrlVersion = phone.getCdmaPrlVersion();
8077             } catch (Exception e) {
8078                 Log.e(LOG_TAG, "Not getting PRLVersion", e);
8079             }
8080             return cdmaPrlVersion;
8081         } finally {
8082             Binder.restoreCallingIdentity(identity);
8083         }
8084     }
8085 
8086     /**
8087      * Get snapshot of Telephony histograms
8088      * @return List of Telephony histograms
8089      * @hide
8090      */
8091     @Override
getTelephonyHistograms()8092     public List<TelephonyHistogram> getTelephonyHistograms() {
8093         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8094                 mApp, getDefaultSubscription(), "getTelephonyHistograms");
8095 
8096         final long identity = Binder.clearCallingIdentity();
8097         try {
8098             return RIL.getTelephonyRILTimingHistograms();
8099         } finally {
8100             Binder.restoreCallingIdentity(identity);
8101         }
8102     }
8103 
8104     /**
8105      * {@hide}
8106      * Set the allowed carrier list and the excluded carrier list, indicating the priority between
8107      * the two lists.
8108      * Require system privileges. In the future we may add this to carrier APIs.
8109      *
8110      * @return Integer with the result of the operation, as defined in {@link TelephonyManager}.
8111      */
8112     @Override
8113     @TelephonyManager.SetCarrierRestrictionResult
setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules)8114     public int setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules) {
8115         enforceModifyPermission();
8116         WorkSource workSource = getWorkSource(Binder.getCallingUid());
8117 
8118         if (carrierRestrictionRules == null) {
8119             throw new NullPointerException("carrier restriction cannot be null");
8120         }
8121 
8122         final long identity = Binder.clearCallingIdentity();
8123         try {
8124             return (int) sendRequest(CMD_SET_ALLOWED_CARRIERS, carrierRestrictionRules,
8125                     workSource);
8126         } finally {
8127             Binder.restoreCallingIdentity(identity);
8128         }
8129     }
8130 
8131     /**
8132      * {@hide}
8133      * Get the allowed carrier list and the excluded carrier list, including the priority between
8134      * the two lists.
8135      * Require system privileges. In the future we may add this to carrier APIs.
8136      *
8137      * @return {@link android.telephony.CarrierRestrictionRules}
8138      */
8139     @Override
getAllowedCarriers()8140     public CarrierRestrictionRules getAllowedCarriers() {
8141         enforceReadPrivilegedPermission("getAllowedCarriers");
8142         WorkSource workSource = getWorkSource(Binder.getCallingUid());
8143 
8144         final long identity = Binder.clearCallingIdentity();
8145         try {
8146             Object response = sendRequest(CMD_GET_ALLOWED_CARRIERS, null, workSource);
8147             if (response instanceof CarrierRestrictionRules) {
8148                 return (CarrierRestrictionRules) response;
8149             }
8150             // Response is an Exception of some kind,
8151             // which is signalled to the user as a NULL retval
8152             return null;
8153         } catch (Exception e) {
8154             Log.e(LOG_TAG, "getAllowedCarriers. Exception ex=" + e);
8155             return null;
8156         } finally {
8157             Binder.restoreCallingIdentity(identity);
8158         }
8159     }
8160 
8161     /**
8162      * Action set from carrier signalling broadcast receivers to enable/disable radio
8163      * @param subId the subscription ID that this action applies to.
8164      * @param enabled control enable or disable radio.
8165      * {@hide}
8166      */
8167     @Override
carrierActionSetRadioEnabled(int subId, boolean enabled)8168     public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
8169         enforceModifyPermission();
8170         final Phone phone = getPhone(subId);
8171 
8172         final long identity = Binder.clearCallingIdentity();
8173         if (phone == null) {
8174             loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
8175             return;
8176         }
8177         try {
8178             phone.carrierActionSetRadioEnabled(enabled);
8179         } catch (Exception e) {
8180             Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
8181         } finally {
8182             Binder.restoreCallingIdentity(identity);
8183         }
8184     }
8185 
8186     /**
8187      * Action set from carrier signalling broadcast receivers to start/stop reporting the default
8188      * network status based on which carrier apps could apply actions accordingly,
8189      * enable/disable default url handler for example.
8190      *
8191      * @param subId the subscription ID that this action applies to.
8192      * @param report control start/stop reporting the default network status.
8193      * {@hide}
8194      */
8195     @Override
carrierActionReportDefaultNetworkStatus(int subId, boolean report)8196     public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
8197         enforceModifyPermission();
8198         final Phone phone = getPhone(subId);
8199 
8200         final long identity = Binder.clearCallingIdentity();
8201         if (phone == null) {
8202             loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
8203             return;
8204         }
8205         try {
8206             phone.carrierActionReportDefaultNetworkStatus(report);
8207         } catch (Exception e) {
8208             Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
8209         } finally {
8210             Binder.restoreCallingIdentity(identity);
8211         }
8212     }
8213 
8214     /**
8215      * Action set from carrier signalling broadcast receivers to reset all carrier actions
8216      * @param subId the subscription ID that this action applies to.
8217      * {@hide}
8218      */
8219     @Override
carrierActionResetAll(int subId)8220     public void carrierActionResetAll(int subId) {
8221         enforceModifyPermission();
8222         final Phone phone = getPhone(subId);
8223         if (phone == null) {
8224             loge("carrierAction: ResetAll fails with invalid sibId: " + subId);
8225             return;
8226         }
8227         try {
8228             phone.carrierActionResetAll();
8229         } catch (Exception e) {
8230             Log.e(LOG_TAG, "carrierAction: ResetAll fails. Exception ex=" + e);
8231         }
8232     }
8233 
8234     /**
8235      * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
8236      * bug report is being generated.
8237      */
8238     @Override
dump(FileDescriptor fd, PrintWriter writer, String[] args)8239     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
8240         if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
8241                 != PackageManager.PERMISSION_GRANTED) {
8242             writer.println("Permission Denial: can't dump Phone from pid="
8243                     + Binder.getCallingPid()
8244                     + ", uid=" + Binder.getCallingUid()
8245                     + "without permission "
8246                     + android.Manifest.permission.DUMP);
8247             return;
8248         }
8249         DumpsysHandler.dump(mApp, fd, writer, args);
8250     }
8251 
8252     @Override
handleShellCommand(@onNull ParcelFileDescriptor in, @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, @NonNull String[] args)8253     public int handleShellCommand(@NonNull ParcelFileDescriptor in,
8254             @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
8255             @NonNull String[] args) {
8256         return new TelephonyShellCommand(this, getDefaultPhone().getContext()).exec(
8257                 this, in.getFileDescriptor(), out.getFileDescriptor(),
8258                         err.getFileDescriptor(), args);
8259     }
8260 
8261     /**
8262      * Policy control of data connection with reason {@@TelephonyManager.DataEnabledReason}
8263      * @param subId Subscription index
8264      * @param reason the reason the data enable change is taking place
8265      * @param enabled True if enabling the data, otherwise disabling.
8266      * @hide
8267      */
8268     @Override
setDataEnabledForReason(int subId, @TelephonyManager.DataEnabledReason int reason, boolean enabled)8269     public void setDataEnabledForReason(int subId, @TelephonyManager.DataEnabledReason int reason,
8270             boolean enabled) {
8271         if (reason == TelephonyManager.DATA_ENABLED_REASON_USER
8272                 || reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
8273             try {
8274                 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
8275                         mApp, subId, "setDataEnabledForReason");
8276             } catch (SecurityException se) {
8277                 enforceModifyPermission();
8278             }
8279         } else {
8280             enforceModifyPermission();
8281         }
8282 
8283         final long identity = Binder.clearCallingIdentity();
8284         try {
8285             Phone phone = getPhone(subId);
8286             if (phone != null) {
8287                 if (reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
8288                     phone.carrierActionSetMeteredApnsEnabled(enabled);
8289                 } else {
8290                     phone.getDataEnabledSettings().setDataEnabled(reason, enabled);
8291                 }
8292             }
8293         } finally {
8294             Binder.restoreCallingIdentity(identity);
8295         }
8296     }
8297 
8298     /**
8299      * Get Client request stats
8300      * @return List of Client Request Stats
8301      * @hide
8302      */
8303     @Override
getClientRequestStats(String callingPackage, String callingFeatureId, int subId)8304     public List<ClientRequestStats> getClientRequestStats(String callingPackage,
8305             String callingFeatureId, int subId) {
8306         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
8307                 mApp, subId, callingPackage, callingFeatureId, "getClientRequestStats")) {
8308             return null;
8309         }
8310         Phone phone = getPhone(subId);
8311 
8312         final long identity = Binder.clearCallingIdentity();
8313         try {
8314             if (phone != null) {
8315                 return phone.getClientRequestStats();
8316             }
8317 
8318             return null;
8319         } finally {
8320             Binder.restoreCallingIdentity(identity);
8321         }
8322     }
8323 
getWorkSource(int uid)8324     private WorkSource getWorkSource(int uid) {
8325         String packageName = mApp.getPackageManager().getNameForUid(uid);
8326         return new WorkSource(uid, packageName);
8327     }
8328 
8329     /**
8330      * Set SIM card power state.
8331      *
8332      * @param slotIndex SIM slot id.
8333      * @param state  State of SIM (power down, power up, pass through)
8334      * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
8335      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
8336      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
8337      *
8338      **/
8339     @Override
setSimPowerStateForSlot(int slotIndex, int state)8340     public void setSimPowerStateForSlot(int slotIndex, int state) {
8341         enforceModifyPermission();
8342         Phone phone = PhoneFactory.getPhone(slotIndex);
8343 
8344         WorkSource workSource = getWorkSource(Binder.getCallingUid());
8345 
8346         final long identity = Binder.clearCallingIdentity();
8347         try {
8348             if (phone != null) {
8349                 phone.setSimPowerState(state, null, workSource);
8350             }
8351         } finally {
8352             Binder.restoreCallingIdentity(identity);
8353         }
8354     }
8355 
8356     /**
8357      * Set SIM card power state.
8358      *
8359      * @param slotIndex SIM slot id.
8360      * @param state  State of SIM (power down, power up, pass through)
8361      * @param callback  callback to trigger after success or failure
8362      * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
8363      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
8364      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
8365      *
8366      **/
8367     @Override
setSimPowerStateForSlotWithCallback(int slotIndex, int state, IIntegerConsumer callback)8368     public void setSimPowerStateForSlotWithCallback(int slotIndex, int state,
8369             IIntegerConsumer callback) {
8370         enforceModifyPermission();
8371         Phone phone = PhoneFactory.getPhone(slotIndex);
8372 
8373         WorkSource workSource = getWorkSource(Binder.getCallingUid());
8374 
8375         final long identity = Binder.clearCallingIdentity();
8376         try {
8377             if (phone != null) {
8378                 Pair<Integer, IIntegerConsumer> arguments = Pair.create(state, callback);
8379                 sendRequestAsync(CMD_SET_SIM_POWER, arguments, phone, workSource);
8380             }
8381         } finally {
8382             Binder.restoreCallingIdentity(identity);
8383         }
8384     }
8385 
isUssdApiAllowed(int subId)8386     private boolean isUssdApiAllowed(int subId) {
8387         CarrierConfigManager configManager =
8388                 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
8389         if (configManager == null) {
8390             return false;
8391         }
8392         PersistableBundle pb = configManager.getConfigForSubId(subId);
8393         if (pb == null) {
8394             return false;
8395         }
8396         return pb.getBoolean(
8397                 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
8398     }
8399 
8400     /**
8401      * Check if phone is in emergency callback mode
8402      * @return true if phone is in emergency callback mode
8403      * @param subId sub id
8404      */
8405     @Override
getEmergencyCallbackMode(int subId)8406     public boolean getEmergencyCallbackMode(int subId) {
8407         enforceReadPrivilegedPermission("getEmergencyCallbackMode");
8408         final Phone phone = getPhone(subId);
8409 
8410         final long identity = Binder.clearCallingIdentity();
8411         try {
8412             if (phone != null) {
8413                 return phone.isInEcm();
8414             } else {
8415                 return false;
8416             }
8417         } finally {
8418             Binder.restoreCallingIdentity(identity);
8419         }
8420     }
8421 
8422     /**
8423      * Get the current signal strength information for the given subscription.
8424      * Because this information is not updated when the device is in a low power state
8425      * it should not be relied-upon to be current.
8426      * @param subId Subscription index
8427      * @return the most recent cached signal strength info from the modem
8428      */
8429     @Override
getSignalStrength(int subId)8430     public SignalStrength getSignalStrength(int subId) {
8431         final long identity = Binder.clearCallingIdentity();
8432         try {
8433             Phone p = getPhone(subId);
8434             if (p == null) {
8435                 return null;
8436             }
8437 
8438             return p.getSignalStrength();
8439         } finally {
8440             Binder.restoreCallingIdentity(identity);
8441         }
8442     }
8443 
8444     /**
8445      * Get the current modem radio state for the given slot.
8446      * @param slotIndex slot index.
8447      * @param callingPackage the name of the package making the call.
8448      * @param callingFeatureId The feature in the package.
8449      * @return the current radio power state from the modem
8450      */
8451     @Override
getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId)8452     public int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId) {
8453         Phone phone = PhoneFactory.getPhone(slotIndex);
8454         if (phone != null) {
8455             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, phone.getSubId(),
8456                     callingPackage, callingFeatureId, "getRadioPowerState")) {
8457                 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
8458             }
8459 
8460             final long identity = Binder.clearCallingIdentity();
8461             try {
8462                 return phone.getRadioPowerState();
8463             } finally {
8464                 Binder.restoreCallingIdentity(identity);
8465             }
8466         }
8467         return TelephonyManager.RADIO_POWER_UNAVAILABLE;
8468     }
8469 
8470     /**
8471      * Checks if data roaming is enabled on the subscription with id {@code subId}.
8472      *
8473      * <p>Requires one of the following permissions:
8474      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
8475      * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
8476      * privileges.
8477      *
8478      * @param subId subscription id
8479      * @return {@code true} if data roaming is enabled on this subscription, otherwise return
8480      * {@code false}.
8481      */
8482     @Override
isDataRoamingEnabled(int subId)8483     public boolean isDataRoamingEnabled(int subId) {
8484         try {
8485             mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
8486                     null);
8487         } catch (Exception e) {
8488             TelephonyPermissions.enforceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
8489                     mApp, subId, "isDataRoamingEnabled");
8490         }
8491 
8492         boolean isEnabled = false;
8493         final long identity = Binder.clearCallingIdentity();
8494         try {
8495             Phone phone = getPhone(subId);
8496             isEnabled =  phone != null ? phone.getDataRoamingEnabled() : false;
8497         } finally {
8498             Binder.restoreCallingIdentity(identity);
8499         }
8500         return isEnabled;
8501     }
8502 
8503 
8504     /**
8505      * Enables/Disables the data roaming on the subscription with id {@code subId}.
8506      *
8507      * <p> Requires permission:
8508      * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
8509      * privileges.
8510      *
8511      * @param subId subscription id
8512      * @param isEnabled {@code true} means enable, {@code false} means disable.
8513      */
8514     @Override
setDataRoamingEnabled(int subId, boolean isEnabled)8515     public void setDataRoamingEnabled(int subId, boolean isEnabled) {
8516         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8517                 mApp, subId, "setDataRoamingEnabled");
8518 
8519         final long identity = Binder.clearCallingIdentity();
8520         try {
8521             Phone phone = getPhone(subId);
8522             if (phone != null) {
8523                 phone.setDataRoamingEnabled(isEnabled);
8524             }
8525         } finally {
8526             Binder.restoreCallingIdentity(identity);
8527         }
8528     }
8529 
8530     @Override
isManualNetworkSelectionAllowed(int subId)8531     public boolean isManualNetworkSelectionAllowed(int subId) {
8532         TelephonyPermissions
8533                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
8534                 mApp, subId, "isManualNetworkSelectionAllowed");
8535 
8536         boolean isAllowed = true;
8537         final long identity = Binder.clearCallingIdentity();
8538         try {
8539             Phone phone = getPhone(subId);
8540             if (phone != null) {
8541                 isAllowed = phone.isCspPlmnEnabled();
8542             }
8543         } finally {
8544             Binder.restoreCallingIdentity(identity);
8545         }
8546         return isAllowed;
8547     }
8548 
8549     @Override
getUiccCardsInfo(String callingPackage)8550     public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
8551         // Verify that tha callingPackage belongs to the calling UID
8552         mApp.getSystemService(AppOpsManager.class)
8553                 .checkPackage(Binder.getCallingUid(), callingPackage);
8554 
8555         boolean hasReadPermission = false;
8556         try {
8557             enforceReadPrivilegedPermission("getUiccCardsInfo");
8558             hasReadPermission = true;
8559         } catch (SecurityException e) {
8560             // even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
8561             // has carrier privileges on an active UICC
8562             if (checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
8563                         != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
8564                 throw new SecurityException("Caller does not have permission.");
8565             }
8566         }
8567 
8568         final long identity = Binder.clearCallingIdentity();
8569         try {
8570             UiccController uiccController = UiccController.getInstance();
8571             ArrayList<UiccCardInfo> cardInfos = uiccController.getAllUiccCardInfos();
8572             if (hasReadPermission) {
8573                 return cardInfos;
8574             }
8575 
8576             // Remove private info if the caller doesn't have access
8577             ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
8578             for (UiccCardInfo cardInfo : cardInfos) {
8579                 // For an inactive eUICC, the UiccCard will be null even though the UiccCardInfo
8580                 // is available
8581                 UiccCard card = uiccController.getUiccCardForSlot(cardInfo.getSlotIndex());
8582                 if (card == null || card.getUiccProfile() == null) {
8583                     // assume no access if the card or profile is unavailable
8584                     filteredInfos.add(cardInfo.getUnprivileged());
8585                     continue;
8586                 }
8587                 UiccProfile profile = card.getUiccProfile();
8588                 if (profile.getCarrierPrivilegeStatus(mApp.getPackageManager(), callingPackage)
8589                         == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
8590                     filteredInfos.add(cardInfo);
8591                 } else {
8592                     filteredInfos.add(cardInfo.getUnprivileged());
8593                 }
8594             }
8595             return filteredInfos;
8596         } finally {
8597             Binder.restoreCallingIdentity(identity);
8598         }
8599     }
8600 
8601     @Override
getUiccSlotsInfo()8602     public UiccSlotInfo[] getUiccSlotsInfo() {
8603         enforceReadPrivilegedPermission("getUiccSlotsInfo");
8604 
8605         final long identity = Binder.clearCallingIdentity();
8606         try {
8607             UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
8608             if (slots == null) {
8609                 Rlog.i(LOG_TAG, "slots is null.");
8610                 return null;
8611             }
8612 
8613             UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
8614             for (int i = 0; i < slots.length; i++) {
8615                 UiccSlot slot = slots[i];
8616                 if (slot == null) {
8617                     continue;
8618                 }
8619 
8620                 String cardId;
8621                 UiccCard card = slot.getUiccCard();
8622                 if (card != null) {
8623                     cardId = card.getCardId();
8624                 } else {
8625                     cardId = slot.getEid();
8626                     if (TextUtils.isEmpty(cardId)) {
8627                         cardId = slot.getIccId();
8628                     }
8629                 }
8630 
8631                 if (cardId != null) {
8632                     // if cardId is an ICCID, strip off trailing Fs before exposing to user
8633                     // if cardId is an EID, it's all digits so this is fine
8634                     cardId = IccUtils.stripTrailingFs(cardId);
8635                 }
8636 
8637                 int cardState = 0;
8638                 switch (slot.getCardState()) {
8639                     case CARDSTATE_ABSENT:
8640                         cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
8641                         break;
8642                     case CARDSTATE_PRESENT:
8643                         cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
8644                         break;
8645                     case CARDSTATE_ERROR:
8646                         cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
8647                         break;
8648                     case CARDSTATE_RESTRICTED:
8649                         cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
8650                         break;
8651                     default:
8652                         break;
8653 
8654                 }
8655 
8656                 infos[i] = new UiccSlotInfo(
8657                         slot.isActive(),
8658                         slot.isEuicc(),
8659                         cardId,
8660                         cardState,
8661                         slot.getPhoneId(),
8662                         slot.isExtendedApduSupported(),
8663                         slot.isRemovable());
8664             }
8665             return infos;
8666         } finally {
8667             Binder.restoreCallingIdentity(identity);
8668         }
8669     }
8670 
8671     @Override
switchSlots(int[] physicalSlots)8672     public boolean switchSlots(int[] physicalSlots) {
8673         enforceModifyPermission();
8674 
8675         final long identity = Binder.clearCallingIdentity();
8676         try {
8677             return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
8678         } finally {
8679             Binder.restoreCallingIdentity(identity);
8680         }
8681     }
8682 
8683     @Override
getCardIdForDefaultEuicc(int subId, String callingPackage)8684     public int getCardIdForDefaultEuicc(int subId, String callingPackage) {
8685         final long identity = Binder.clearCallingIdentity();
8686         try {
8687             return UiccController.getInstance().getCardIdForDefaultEuicc();
8688         } finally {
8689             Binder.restoreCallingIdentity(identity);
8690         }
8691     }
8692 
8693     /**
8694      * A test API to reload the UICC profile.
8695      *
8696      * <p>Requires that the calling app has permission
8697      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
8698      * @hide
8699      */
8700     @Override
refreshUiccProfile(int subId)8701     public void refreshUiccProfile(int subId) {
8702         enforceModifyPermission();
8703 
8704         final long identity = Binder.clearCallingIdentity();
8705         try {
8706             Phone phone = getPhone(subId);
8707             if (phone == null) {
8708                 return;
8709             }
8710             UiccCard uiccCard = phone.getUiccCard();
8711             if (uiccCard == null) {
8712                 return;
8713             }
8714             UiccProfile uiccProfile = uiccCard.getUiccProfile();
8715             if (uiccProfile == null) {
8716                 return;
8717             }
8718             uiccProfile.refresh();
8719         } finally {
8720             Binder.restoreCallingIdentity(identity);
8721         }
8722     }
8723 
8724     /**
8725      * Returns false if the mobile data is disabled by default, otherwise return true.
8726      */
getDefaultDataEnabled()8727     private boolean getDefaultDataEnabled() {
8728         return TelephonyProperties.mobile_data().orElse(true);
8729     }
8730 
8731     /**
8732      * Returns true if the data roaming is enabled by default, i.e the system property
8733      * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
8734      * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
8735      */
getDefaultDataRoamingEnabled(int subId)8736     private boolean getDefaultDataRoamingEnabled(int subId) {
8737         final CarrierConfigManager configMgr = (CarrierConfigManager)
8738                 mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
8739         boolean isDataRoamingEnabled = TelephonyProperties.data_roaming().orElse(false);
8740         isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
8741                 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
8742         return isDataRoamingEnabled;
8743     }
8744 
8745     /**
8746      * Returns the default network type for the given {@code subId}, if the default network type is
8747      * not set, return {@link Phone#PREFERRED_NT_MODE}.
8748      */
getDefaultNetworkType(int subId)8749     private int getDefaultNetworkType(int subId) {
8750         List<Integer> list = TelephonyProperties.default_network();
8751         int phoneId = mSubscriptionController.getPhoneId(subId);
8752         if (phoneId >= 0 && phoneId < list.size() && list.get(phoneId) != null) {
8753             return list.get(phoneId);
8754         }
8755         return Phone.PREFERRED_NT_MODE;
8756     }
8757 
8758     @Override
setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn)8759     public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
8760             gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn) {
8761         enforceModifyPermission();
8762 
8763         final long identity = Binder.clearCallingIdentity();
8764         try {
8765             final Phone phone = getPhone(subId);
8766             if (phone == null) {
8767                 loge("setCarrierTestOverride fails with invalid subId: " + subId);
8768                 return;
8769             }
8770             phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn,
8771                     carrierPrivilegeRules, apn);
8772             if (carrierPrivilegeRules == null) {
8773                 mCarrierPrivilegeTestOverrideSubIds.remove(subId);
8774             } else {
8775                 mCarrierPrivilegeTestOverrideSubIds.add(subId);
8776             }
8777         } finally {
8778             Binder.restoreCallingIdentity(identity);
8779         }
8780     }
8781 
8782     @Override
getCarrierIdListVersion(int subId)8783     public int getCarrierIdListVersion(int subId) {
8784         enforceReadPrivilegedPermission("getCarrierIdListVersion");
8785 
8786         final long identity = Binder.clearCallingIdentity();
8787         try {
8788             final Phone phone = getPhone(subId);
8789             if (phone == null) {
8790                 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
8791                 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
8792             }
8793             return phone.getCarrierIdListVersion();
8794         } finally {
8795             Binder.restoreCallingIdentity(identity);
8796         }
8797     }
8798 
8799     @Override
getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage, String callingFeatureId)8800     public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage,
8801             String callingFeatureId) {
8802         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
8803                 mApp, subId, callingPackage, callingFeatureId,
8804                 "getNumberOfModemsWithSimultaneousDataConnections")) {
8805             return -1;
8806         }
8807 
8808         final long identity = Binder.clearCallingIdentity();
8809         try {
8810             return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
8811         } finally {
8812             Binder.restoreCallingIdentity(identity);
8813         }
8814     }
8815 
8816     @Override
getCdmaRoamingMode(int subId)8817     public int getCdmaRoamingMode(int subId) {
8818         TelephonyPermissions
8819                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
8820                 mApp, subId, "getCdmaRoamingMode");
8821 
8822         final long identity = Binder.clearCallingIdentity();
8823         try {
8824             return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
8825         } finally {
8826             Binder.restoreCallingIdentity(identity);
8827         }
8828     }
8829 
8830     @Override
setCdmaRoamingMode(int subId, int mode)8831     public boolean setCdmaRoamingMode(int subId, int mode) {
8832         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8833                 mApp, subId, "setCdmaRoamingMode");
8834 
8835         final long identity = Binder.clearCallingIdentity();
8836         try {
8837             return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
8838         } finally {
8839             Binder.restoreCallingIdentity(identity);
8840         }
8841     }
8842 
8843     @Override
getCdmaSubscriptionMode(int subId)8844     public int getCdmaSubscriptionMode(int subId) {
8845         TelephonyPermissions
8846                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
8847                         mApp, subId, "getCdmaSubscriptionMode");
8848 
8849         final long identity = Binder.clearCallingIdentity();
8850         try {
8851             return (int) sendRequest(CMD_GET_CDMA_SUBSCRIPTION_MODE, null /* argument */, subId);
8852         } finally {
8853             Binder.restoreCallingIdentity(identity);
8854         }
8855     }
8856 
8857     @Override
setCdmaSubscriptionMode(int subId, int mode)8858     public boolean setCdmaSubscriptionMode(int subId, int mode) {
8859         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8860                 mApp, subId, "setCdmaSubscriptionMode");
8861 
8862         final long identity = Binder.clearCallingIdentity();
8863         try {
8864             return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
8865         } finally {
8866             Binder.restoreCallingIdentity(identity);
8867         }
8868     }
8869 
8870     @Override
getEmergencyNumberList( String callingPackage, String callingFeatureId)8871     public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
8872             String callingPackage, String callingFeatureId) {
8873         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
8874                 mApp, getDefaultSubscription(), callingPackage, callingFeatureId,
8875                 "getEmergencyNumberList")) {
8876             throw new SecurityException("Requires READ_PHONE_STATE permission.");
8877         }
8878         final long identity = Binder.clearCallingIdentity();
8879         try {
8880             Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
8881             for (Phone phone: PhoneFactory.getPhones()) {
8882                 if (phone.getEmergencyNumberTracker() != null
8883                         && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
8884                     emergencyNumberListInternal.put(
8885                             phone.getSubId(),
8886                             phone.getEmergencyNumberTracker().getEmergencyNumberList());
8887                 }
8888             }
8889             return emergencyNumberListInternal;
8890         } finally {
8891             Binder.restoreCallingIdentity(identity);
8892         }
8893     }
8894 
8895     @Override
isEmergencyNumber(String number, boolean exactMatch)8896     public boolean isEmergencyNumber(String number, boolean exactMatch) {
8897         final Phone defaultPhone = getDefaultPhone();
8898         if (!exactMatch) {
8899             TelephonyPermissions
8900                     .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
8901                             mApp, defaultPhone.getSubId(), "isEmergencyNumber(Potential)");
8902         }
8903         final long identity = Binder.clearCallingIdentity();
8904         try {
8905             for (Phone phone: PhoneFactory.getPhones()) {
8906                 if (phone.getEmergencyNumberTracker() != null
8907                         && phone.getEmergencyNumberTracker()
8908                                 .isEmergencyNumber(number, exactMatch)) {
8909                     return true;
8910                 }
8911             }
8912             return false;
8913         } finally {
8914             Binder.restoreCallingIdentity(identity);
8915         }
8916     }
8917 
8918     /**
8919      * Start emergency callback mode for GsmCdmaPhone for testing.
8920      */
8921     @Override
startEmergencyCallbackMode()8922     public void startEmergencyCallbackMode() {
8923         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
8924                 "startEmergencyCallbackMode");
8925         enforceModifyPermission();
8926         final long identity = Binder.clearCallingIdentity();
8927         try {
8928             for (Phone phone : PhoneFactory.getPhones()) {
8929                 Rlog.d(LOG_TAG, "startEmergencyCallbackMode phone type: " + phone.getPhoneType());
8930                 if (phone != null && ((phone.getPhoneType() == PHONE_TYPE_GSM)
8931                         || (phone.getPhoneType() == PHONE_TYPE_CDMA))) {
8932                     GsmCdmaPhone gsmCdmaPhone = (GsmCdmaPhone) phone;
8933                     gsmCdmaPhone.obtainMessage(
8934                             GsmCdmaPhone.EVENT_EMERGENCY_CALLBACK_MODE_ENTER).sendToTarget();
8935                     Rlog.d(LOG_TAG, "startEmergencyCallbackMode: triggered");
8936                 }
8937             }
8938         } finally {
8939             Binder.restoreCallingIdentity(identity);
8940         }
8941     }
8942 
8943     /**
8944      * Update emergency number list for test mode.
8945      */
8946     @Override
updateEmergencyNumberListTestMode(int action, EmergencyNumber num)8947     public void updateEmergencyNumberListTestMode(int action, EmergencyNumber num) {
8948         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
8949                 "updateEmergencyNumberListTestMode");
8950 
8951         final long identity = Binder.clearCallingIdentity();
8952         try {
8953             for (Phone phone: PhoneFactory.getPhones()) {
8954                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
8955                 if (tracker != null) {
8956                     tracker.executeEmergencyNumberTestModeCommand(action, num);
8957                 }
8958             }
8959         } finally {
8960             Binder.restoreCallingIdentity(identity);
8961         }
8962     }
8963 
8964     /**
8965      * Get the full emergency number list for test mode.
8966      */
8967     @Override
getEmergencyNumberListTestMode()8968     public List<String> getEmergencyNumberListTestMode() {
8969         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
8970                 "getEmergencyNumberListTestMode");
8971 
8972         final long identity = Binder.clearCallingIdentity();
8973         try {
8974             Set<String> emergencyNumbers = new HashSet<>();
8975             for (Phone phone: PhoneFactory.getPhones()) {
8976                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
8977                 if (tracker != null) {
8978                     for (EmergencyNumber num : tracker.getEmergencyNumberList()) {
8979                         emergencyNumbers.add(num.getNumber());
8980                     }
8981                 }
8982             }
8983             return new ArrayList<>(emergencyNumbers);
8984         } finally {
8985             Binder.restoreCallingIdentity(identity);
8986         }
8987     }
8988 
8989     @Override
getEmergencyNumberDbVersion(int subId)8990     public int getEmergencyNumberDbVersion(int subId) {
8991         enforceReadPrivilegedPermission("getEmergencyNumberDbVersion");
8992 
8993         final long identity = Binder.clearCallingIdentity();
8994         try {
8995             final Phone phone = getPhone(subId);
8996             if (phone == null) {
8997                 loge("getEmergencyNumberDbVersion fails with invalid subId: " + subId);
8998                 return TelephonyManager.INVALID_EMERGENCY_NUMBER_DB_VERSION;
8999             }
9000             return phone.getEmergencyNumberDbVersion();
9001         } finally {
9002             Binder.restoreCallingIdentity(identity);
9003         }
9004     }
9005 
9006     @Override
notifyOtaEmergencyNumberDbInstalled()9007     public void notifyOtaEmergencyNumberDbInstalled() {
9008         enforceModifyPermission();
9009 
9010         final long identity = Binder.clearCallingIdentity();
9011         try {
9012             for (Phone phone: PhoneFactory.getPhones()) {
9013                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
9014                 if (tracker != null) {
9015                     tracker.updateOtaEmergencyNumberDatabase();
9016                 }
9017             }
9018         } finally {
9019             Binder.restoreCallingIdentity(identity);
9020         }
9021     }
9022 
9023     @Override
updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor)9024     public void updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor) {
9025         enforceActiveEmergencySessionPermission();
9026 
9027         final long identity = Binder.clearCallingIdentity();
9028         try {
9029             for (Phone phone: PhoneFactory.getPhones()) {
9030                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
9031                 if (tracker != null) {
9032                     tracker.updateOtaEmergencyNumberDbFilePath(otaParcelFileDescriptor);
9033                 }
9034             }
9035         } finally {
9036             Binder.restoreCallingIdentity(identity);
9037         }
9038     }
9039 
9040     @Override
resetOtaEmergencyNumberDbFilePath()9041     public void resetOtaEmergencyNumberDbFilePath() {
9042         enforceActiveEmergencySessionPermission();
9043 
9044         final long identity = Binder.clearCallingIdentity();
9045         try {
9046             for (Phone phone: PhoneFactory.getPhones()) {
9047                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
9048                 if (tracker != null) {
9049                     tracker.resetOtaEmergencyNumberDbFilePath();
9050                 }
9051             }
9052         } finally {
9053             Binder.restoreCallingIdentity(identity);
9054         }
9055     }
9056 
9057     @Override
getCertsFromCarrierPrivilegeAccessRules(int subId)9058     public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
9059         enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
9060         Phone phone = getPhone(subId);
9061         if (phone == null) {
9062             return null;
9063         }
9064         final long identity = Binder.clearCallingIdentity();
9065         try {
9066             UiccProfile profile = UiccController.getInstance()
9067                     .getUiccProfileForPhone(phone.getPhoneId());
9068             if (profile != null) {
9069                 return profile.getCertsFromCarrierPrivilegeAccessRules();
9070             }
9071         } finally {
9072             Binder.restoreCallingIdentity(identity);
9073         }
9074         return null;
9075     }
9076 
9077     /**
9078      * Enable or disable a modem stack.
9079      */
9080     @Override
enableModemForSlot(int slotIndex, boolean enable)9081     public boolean enableModemForSlot(int slotIndex, boolean enable) {
9082         enforceModifyPermission();
9083 
9084         final long identity = Binder.clearCallingIdentity();
9085         try {
9086             Phone phone = PhoneFactory.getPhone(slotIndex);
9087             if (phone == null) {
9088                 return false;
9089             } else {
9090                 return (Boolean) sendRequest(CMD_REQUEST_ENABLE_MODEM, enable, phone, null);
9091             }
9092         } finally {
9093             Binder.restoreCallingIdentity(identity);
9094         }
9095     }
9096 
9097     /**
9098      * Whether a modem stack is enabled or not.
9099      */
9100     @Override
isModemEnabledForSlot(int slotIndex, String callingPackage, String callingFeatureId)9101     public boolean isModemEnabledForSlot(int slotIndex, String callingPackage,
9102             String callingFeatureId) {
9103         Phone phone = PhoneFactory.getPhone(slotIndex);
9104         if (phone == null) return false;
9105 
9106         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
9107                 mApp, phone.getSubId(), callingPackage, callingFeatureId,
9108                 "isModemEnabledForSlot")) {
9109             throw new SecurityException("Requires READ_PHONE_STATE permission.");
9110         }
9111 
9112         final long identity = Binder.clearCallingIdentity();
9113         try {
9114             try {
9115                 return mPhoneConfigurationManager.getPhoneStatusFromCache(phone.getPhoneId());
9116             } catch (NoSuchElementException ex) {
9117                 return (Boolean) sendRequest(CMD_GET_MODEM_STATUS, null, phone, null);
9118             }
9119         } finally {
9120             Binder.restoreCallingIdentity(identity);
9121         }
9122     }
9123 
9124     @Override
setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted)9125     public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
9126         enforceModifyPermission();
9127 
9128         final long identity = Binder.clearCallingIdentity();
9129         try {
9130             mTelephonySharedPreferences.edit()
9131                     .putBoolean(PREF_MULTI_SIM_RESTRICTED, isMultiSimCarrierRestricted)
9132                     .commit();
9133         } finally {
9134             Binder.restoreCallingIdentity(identity);
9135         }
9136     }
9137 
9138     @Override
9139     @TelephonyManager.IsMultiSimSupportedResult
isMultiSimSupported(String callingPackage, String callingFeatureId)9140     public int isMultiSimSupported(String callingPackage, String callingFeatureId) {
9141         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
9142                 getDefaultPhone().getSubId(), callingPackage, callingFeatureId,
9143                 "isMultiSimSupported")) {
9144             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
9145         }
9146 
9147         final long identity = Binder.clearCallingIdentity();
9148         try {
9149             return isMultiSimSupportedInternal();
9150         } finally {
9151             Binder.restoreCallingIdentity(identity);
9152         }
9153     }
9154 
9155     @TelephonyManager.IsMultiSimSupportedResult
isMultiSimSupportedInternal()9156     private int isMultiSimSupportedInternal() {
9157         // If the device has less than 2 SIM cards, indicate that multisim is restricted.
9158         int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
9159         if (numPhysicalSlots < 2) {
9160             loge("isMultiSimSupportedInternal: requires at least 2 cards");
9161             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
9162         }
9163         // Check if the hardware supports multisim functionality. If usage of multisim is not
9164         // supported by the modem, indicate that it is restricted.
9165         PhoneCapability staticCapability =
9166                 mPhoneConfigurationManager.getStaticPhoneCapability();
9167         if (staticCapability == null) {
9168             loge("isMultiSimSupportedInternal: no static configuration available");
9169             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
9170         }
9171         if (staticCapability.getLogicalModemList().size() < 2) {
9172             loge("isMultiSimSupportedInternal: maximum number of modem is < 2");
9173             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
9174         }
9175         // Check if support of multiple SIMs is restricted by carrier
9176         if (mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false)) {
9177             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_CARRIER;
9178         }
9179 
9180         return TelephonyManager.MULTISIM_ALLOWED;
9181     }
9182 
9183     /**
9184      * Switch configs to enable multi-sim or switch back to single-sim
9185      * Note: Switch from multi-sim to single-sim is only possible with MODIFY_PHONE_STATE
9186      * permission, but the other way around is possible with either MODIFY_PHONE_STATE
9187      * or carrier privileges
9188      * @param numOfSims number of active sims we want to switch to
9189      */
9190     @Override
switchMultiSimConfig(int numOfSims)9191     public void switchMultiSimConfig(int numOfSims) {
9192         if (numOfSims == 1) {
9193             enforceModifyPermission();
9194         } else {
9195             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9196                     mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
9197         }
9198         final long identity = Binder.clearCallingIdentity();
9199 
9200         try {
9201             //only proceed if multi-sim is not restricted
9202             if (isMultiSimSupportedInternal() != TelephonyManager.MULTISIM_ALLOWED) {
9203                 loge("switchMultiSimConfig not possible. It is restricted or not supported.");
9204                 return;
9205             }
9206             mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
9207         } finally {
9208             Binder.restoreCallingIdentity(identity);
9209         }
9210     }
9211 
9212     @Override
isApplicationOnUicc(int subId, int appType)9213     public boolean isApplicationOnUicc(int subId, int appType) {
9214         enforceReadPrivilegedPermission("isApplicationOnUicc");
9215         Phone phone = getPhone(subId);
9216         if (phone == null) {
9217             return false;
9218         }
9219         final long identity = Binder.clearCallingIdentity();
9220         try {
9221             UiccCard uiccCard = phone.getUiccCard();
9222             if (uiccCard == null) {
9223                 return false;
9224             }
9225             UiccProfile uiccProfile = uiccCard.getUiccProfile();
9226             if (uiccProfile == null) {
9227                 return false;
9228             }
9229             if (TelephonyManager.APPTYPE_SIM <= appType
9230                     && appType <= TelephonyManager.APPTYPE_ISIM) {
9231                 return uiccProfile.isApplicationOnIcc(AppType.values()[appType]);
9232             }
9233             return false;
9234         } finally {
9235             Binder.restoreCallingIdentity(identity);
9236         }
9237     }
9238 
9239     /**
9240      * Get whether making changes to modem configurations will trigger reboot.
9241      * Return value defaults to true.
9242      */
9243     @Override
doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage, String callingFeatureId)9244     public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage,
9245             String callingFeatureId) {
9246         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
9247                 mApp, subId, callingPackage, callingFeatureId,
9248                 "doesSwitchMultiSimConfigTriggerReboot")) {
9249             return false;
9250         }
9251         final long identity = Binder.clearCallingIdentity();
9252         try {
9253             return mPhoneConfigurationManager.isRebootRequiredForModemConfigChange();
9254         } finally {
9255             Binder.restoreCallingIdentity(identity);
9256         }
9257     }
9258 
updateModemStateMetrics()9259     private void updateModemStateMetrics() {
9260         TelephonyMetrics metrics = TelephonyMetrics.getInstance();
9261         // TODO: check the state for each modem if the api is ready.
9262         metrics.updateEnabledModemBitmap((1 << TelephonyManager.from(mApp).getPhoneCount()) - 1);
9263     }
9264 
9265     @Override
getSlotsMapping()9266     public int[] getSlotsMapping() {
9267         enforceReadPrivilegedPermission("getSlotsMapping");
9268 
9269         final long identity = Binder.clearCallingIdentity();
9270         try {
9271             int phoneCount = TelephonyManager.getDefault().getPhoneCount();
9272             // All logical slots should have a mapping to a physical slot.
9273             int[] logicalSlotsMapping = new int[phoneCount];
9274             UiccSlotInfo[] slotInfos = getUiccSlotsInfo();
9275             for (int i = 0; i < slotInfos.length; i++) {
9276                 if (SubscriptionManager.isValidPhoneId(slotInfos[i].getLogicalSlotIdx())) {
9277                     logicalSlotsMapping[slotInfos[i].getLogicalSlotIdx()] = i;
9278                 }
9279             }
9280             return logicalSlotsMapping;
9281         } finally {
9282             Binder.restoreCallingIdentity(identity);
9283         }
9284     }
9285 
9286     /**
9287      * Get the IRadio HAL Version
9288      */
9289     @Override
getRadioHalVersion()9290     public int getRadioHalVersion() {
9291         Phone phone = getDefaultPhone();
9292         if (phone == null) return -1;
9293         HalVersion hv = phone.getHalVersion();
9294         if (hv.equals(HalVersion.UNKNOWN)) return -1;
9295         return hv.major * 100 + hv.minor;
9296     }
9297 
9298     /**
9299      * Get the current calling package name.
9300      * @return the current calling package name
9301      */
9302     @Override
getCurrentPackageName()9303     public String getCurrentPackageName() {
9304         return mApp.getPackageManager().getPackagesForUid(Binder.getCallingUid())[0];
9305     }
9306 
9307     /**
9308      * Return whether data is enabled for certain APN type. This will tell if framework will accept
9309      * corresponding network requests on a subId.
9310      *
9311      *  Data is enabled if:
9312      *  1) user data is turned on, or
9313      *  2) APN is un-metered for this subscription, or
9314      *  3) APN type is whitelisted. E.g. MMS is whitelisted if
9315      *  {@link TelephonyManager#MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED} is enabled.
9316      *
9317      * @return whether data is allowed for a apn type.
9318      *
9319      * @hide
9320      */
9321     @Override
isDataEnabledForApn(int apnType, int subId, String callingPackage)9322     public boolean isDataEnabledForApn(int apnType, int subId, String callingPackage) {
9323         enforceReadPrivilegedPermission("Needs READ_PRIVILEGED_PHONE_STATE for "
9324                 + "isDataEnabledForApn");
9325 
9326         // Now that all security checks passes, perform the operation as ourselves.
9327         final long identity = Binder.clearCallingIdentity();
9328         try {
9329             Phone phone = getPhone(subId);
9330             if (phone == null) return false;
9331 
9332             boolean isMetered = ApnSettingUtils.isMeteredApnType(apnType, phone);
9333             return !isMetered || phone.getDataEnabledSettings().isDataEnabled(apnType);
9334         } finally {
9335             Binder.restoreCallingIdentity(identity);
9336         }
9337     }
9338 
9339     @Override
isApnMetered(@pnType int apnType, int subId)9340     public boolean isApnMetered(@ApnType int apnType, int subId) {
9341         enforceReadPrivilegedPermission("isApnMetered");
9342 
9343         // Now that all security checks passes, perform the operation as ourselves.
9344         final long identity = Binder.clearCallingIdentity();
9345         try {
9346             Phone phone = getPhone(subId);
9347             if (phone == null) return true; // By default return true.
9348 
9349             return ApnSettingUtils.isMeteredApnType(apnType, phone);
9350         } finally {
9351             Binder.restoreCallingIdentity(identity);
9352         }
9353     }
9354 
9355     @Override
setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers, int subscriptionId, IBooleanConsumer resultCallback)9356     public void setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers,
9357             int subscriptionId, IBooleanConsumer resultCallback) {
9358         enforceModifyPermission();
9359         long token = Binder.clearCallingIdentity();
9360         try {
9361             Phone phone = getPhone(subscriptionId);
9362             if (phone == null) {
9363                 try {
9364                     if (resultCallback != null) {
9365                         resultCallback.accept(false);
9366                     }
9367                 } catch (RemoteException e) {
9368                     // ignore
9369                 }
9370                 return;
9371             }
9372             Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> argument =
9373                     Pair.create(specifiers, (x) -> {
9374                         try {
9375                             if (resultCallback != null) {
9376                                 resultCallback.accept(x);
9377                             }
9378                         } catch (RemoteException e) {
9379                             // ignore
9380                         }
9381                     });
9382             sendRequestAsync(CMD_SET_SYSTEM_SELECTION_CHANNELS, argument, phone, null);
9383         } finally {
9384             Binder.restoreCallingIdentity(token);
9385         }
9386     }
9387 
9388     @Override
getSystemSelectionChannels(int subId)9389     public List<RadioAccessSpecifier> getSystemSelectionChannels(int subId) {
9390         TelephonyPermissions
9391                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
9392                         mApp, subId, "getSystemSelectionChannels");
9393         WorkSource workSource = getWorkSource(Binder.getCallingUid());
9394         final long identity = Binder.clearCallingIdentity();
9395         try {
9396             Object result = sendRequest(CMD_GET_SYSTEM_SELECTION_CHANNELS, null, subId, workSource);
9397             if (result instanceof IllegalStateException) {
9398                 throw (IllegalStateException) result;
9399             }
9400             List<RadioAccessSpecifier> specifiers = (List<RadioAccessSpecifier>) result;
9401             if (DBG) log("getSystemSelectionChannels: " + specifiers);
9402             return specifiers;
9403         } finally {
9404             Binder.restoreCallingIdentity(identity);
9405         }
9406     }
9407 
9408     @Override
isMvnoMatched(int subId, int mvnoType, @NonNull String mvnoMatchData)9409     public boolean isMvnoMatched(int subId, int mvnoType, @NonNull String mvnoMatchData) {
9410         enforceReadPrivilegedPermission("isMvnoMatched");
9411         IccRecords iccRecords = UiccController.getInstance().getIccRecords(
9412                 SubscriptionManager.getPhoneId(subId), UiccController.APP_FAM_3GPP);
9413         if (iccRecords == null) {
9414             Log.d(LOG_TAG, "isMvnoMatched# IccRecords is null");
9415             return false;
9416         }
9417         return ApnSettingUtils.mvnoMatches(iccRecords, mvnoType, mvnoMatchData);
9418     }
9419 
9420     @Override
enqueueSmsPickResult(String callingPackage, String callingAttributionTag, IIntegerConsumer pendingSubIdResult)9421     public void enqueueSmsPickResult(String callingPackage, String callingAttributionTag,
9422             IIntegerConsumer pendingSubIdResult) {
9423         if (callingPackage == null) {
9424             callingPackage = getCurrentPackageName();
9425         }
9426         SmsPermissions permissions = new SmsPermissions(getDefaultPhone(), mApp,
9427                 (AppOpsManager) mApp.getSystemService(Context.APP_OPS_SERVICE));
9428         if (!permissions.checkCallingCanSendSms(callingPackage, callingAttributionTag,
9429                 "Sending message")) {
9430             throw new SecurityException("Requires SEND_SMS permission to perform this operation");
9431         }
9432         PickSmsSubscriptionActivity.addPendingResult(pendingSubIdResult);
9433         Intent intent = new Intent();
9434         intent.setClass(mApp, PickSmsSubscriptionActivity.class);
9435         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9436         // Bring up choose default SMS subscription dialog right now
9437         intent.putExtra(PickSmsSubscriptionActivity.DIALOG_TYPE_KEY,
9438                 PickSmsSubscriptionActivity.SMS_PICK_FOR_MESSAGE);
9439         mApp.startActivity(intent);
9440     }
9441 
9442     @Override
getMmsUAProfUrl(int subId)9443     public String getMmsUAProfUrl(int subId) {
9444         //TODO investigate if this API should require proper permission check in R b/133791609
9445         final long identity = Binder.clearCallingIdentity();
9446         try {
9447             String carrierUAProfUrl = mApp.getCarrierConfigForSubId(subId).getString(
9448                     CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING);
9449             if (!TextUtils.isEmpty(carrierUAProfUrl)) {
9450                 return carrierUAProfUrl;
9451             }
9452             return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
9453                     .getString(com.android.internal.R.string.config_mms_user_agent_profile_url);
9454         } finally {
9455             Binder.restoreCallingIdentity(identity);
9456         }
9457     }
9458 
9459     @Override
getMmsUserAgent(int subId)9460     public String getMmsUserAgent(int subId) {
9461         //TODO investigate if this API should require proper permission check in R b/133791609
9462         final long identity = Binder.clearCallingIdentity();
9463         try {
9464             String carrierUserAgent = mApp.getCarrierConfigForSubId(subId).getString(
9465                     CarrierConfigManager.KEY_MMS_USER_AGENT_STRING);
9466             if (!TextUtils.isEmpty(carrierUserAgent)) {
9467                 return carrierUserAgent;
9468             }
9469             return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
9470                     .getString(com.android.internal.R.string.config_mms_user_agent);
9471         } finally {
9472             Binder.restoreCallingIdentity(identity);
9473         }
9474     }
9475 
9476     @Override
isMobileDataPolicyEnabled(int subscriptionId, int policy)9477     public boolean isMobileDataPolicyEnabled(int subscriptionId, int policy) {
9478         enforceReadPrivilegedPermission("isMobileDataPolicyEnabled");
9479 
9480         final long identity = Binder.clearCallingIdentity();
9481         try {
9482             Phone phone = getPhone(subscriptionId);
9483             if (phone == null) return false;
9484 
9485             switch (policy) {
9486                 case TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL:
9487                     return phone.getDataEnabledSettings().isDataAllowedInVoiceCall();
9488                 case TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED:
9489                     return phone.getDataEnabledSettings().isMmsAlwaysAllowed();
9490                 default:
9491                     throw new IllegalArgumentException(policy + " is not a valid policy");
9492             }
9493         } finally {
9494             Binder.restoreCallingIdentity(identity);
9495         }
9496     }
9497 
9498     @Override
setMobileDataPolicyEnabled(int subscriptionId, int policy, boolean enabled)9499     public void setMobileDataPolicyEnabled(int subscriptionId, int policy,
9500             boolean enabled) {
9501         enforceModifyPermission();
9502 
9503         final long identity = Binder.clearCallingIdentity();
9504         try {
9505             Phone phone = getPhone(subscriptionId);
9506             if (phone == null) return;
9507 
9508             switch (policy) {
9509                 case TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL:
9510                     phone.getDataEnabledSettings().setAllowDataDuringVoiceCall(enabled);
9511                     break;
9512                 case TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED:
9513                     phone.getDataEnabledSettings().setAlwaysAllowMmsData(enabled);
9514                     break;
9515                 default:
9516                     throw new IllegalArgumentException(policy + " is not a valid policy");
9517             }
9518         } finally {
9519             Binder.restoreCallingIdentity(identity);
9520         }
9521     }
9522 
9523     /**
9524      * Updates whether conference event package handling is enabled.
9525      * @param isCepEnabled {@code true} if CEP handling is enabled (default), or {@code false}
9526      *                                 otherwise.
9527      */
9528     @Override
setCepEnabled(boolean isCepEnabled)9529     public void setCepEnabled(boolean isCepEnabled) {
9530         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCepEnabled");
9531 
9532         final long identity = Binder.clearCallingIdentity();
9533         try {
9534             Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled);
9535             for (Phone phone : PhoneFactory.getPhones()) {
9536                 Phone defaultPhone = phone.getImsPhone();
9537                 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
9538                     ImsPhone imsPhone = (ImsPhone) defaultPhone;
9539                     ImsPhoneCallTracker imsPhoneCallTracker =
9540                             (ImsPhoneCallTracker) imsPhone.getCallTracker();
9541                     imsPhoneCallTracker.setConferenceEventPackageEnabled(isCepEnabled);
9542                     Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled + ", for imsPhone "
9543                             + imsPhone.getMsisdn());
9544                 }
9545             }
9546         } finally {
9547             Binder.restoreCallingIdentity(identity);
9548         }
9549     }
9550 
9551     /**
9552      * Notify that an RCS autoconfiguration XML file has been received for provisioning.
9553      *
9554      * @param config       The XML file to be read. ASCII/UTF8 encoded text if not compressed.
9555      * @param isCompressed The XML file is compressed in gzip format and must be decompressed
9556      *                     before being read.
9557      */
9558     @Override
notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean isCompressed)9559     public void notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean
9560             isCompressed) {
9561         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9562                 mApp, subId, "notifyRcsAutoConfigurationReceived");
9563         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
9564             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
9565         }
9566         if (!isImsAvailableOnDevice()) {
9567             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
9568                     "IMS not available on device.");
9569         }
9570 
9571         final long identity = Binder.clearCallingIdentity();
9572         try {
9573             RcsProvisioningMonitor.getInstance().updateConfig(subId, config, isCompressed);
9574         } finally {
9575             Binder.restoreCallingIdentity(identity);
9576         }
9577     }
9578 
9579     @Override
isIccLockEnabled(int subId)9580     public boolean isIccLockEnabled(int subId) {
9581         enforceReadPrivilegedPermission("isIccLockEnabled");
9582 
9583         // Now that all security checks passes, perform the operation as ourselves.
9584         final long identity = Binder.clearCallingIdentity();
9585         try {
9586             Phone phone = getPhone(subId);
9587             if (phone != null && phone.getIccCard() != null) {
9588                 return phone.getIccCard().getIccLockEnabled();
9589             } else {
9590                 return false;
9591             }
9592         } finally {
9593             Binder.restoreCallingIdentity(identity);
9594         }
9595     }
9596 
9597     /**
9598      * Set the ICC pin lock enabled or disabled.
9599      *
9600      * @return an integer representing the status of IccLock enabled or disabled in the following
9601      * three cases:
9602      *   - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if enabled or disabled IccLock
9603      *   successfully.
9604      *   - Positive number and zero for remaining password attempts.
9605      *   - Negative number for other failure cases (such like enabling/disabling PIN failed).
9606      *
9607      */
9608     @Override
setIccLockEnabled(int subId, boolean enabled, String password)9609     public int setIccLockEnabled(int subId, boolean enabled, String password) {
9610         enforceModifyPermission();
9611 
9612         Phone phone = getPhone(subId);
9613         if (phone == null) {
9614             return 0;
9615         }
9616         // Now that all security checks passes, perform the operation as ourselves.
9617         final long identity = Binder.clearCallingIdentity();
9618         try {
9619             int attemptsRemaining = (int) sendRequest(CMD_SET_ICC_LOCK_ENABLED,
9620                     new Pair<Boolean, String>(enabled, password), phone, null);
9621             return attemptsRemaining;
9622 
9623         } catch (Exception e) {
9624             Log.e(LOG_TAG, "setIccLockEnabled. Exception e =" + e);
9625         } finally {
9626             Binder.restoreCallingIdentity(identity);
9627         }
9628         return 0;
9629     }
9630 
9631     /**
9632      * Change the ICC password used in ICC pin lock.
9633      *
9634      * @return an integer representing the status of IccLock changed in the following three cases:
9635      *   - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if changed IccLock successfully.
9636      *   - Positive number and zero for remaining password attempts.
9637      *   - Negative number for other failure cases (such like enabling/disabling PIN failed).
9638      *
9639      */
9640     @Override
changeIccLockPassword(int subId, String oldPassword, String newPassword)9641     public int changeIccLockPassword(int subId, String oldPassword, String newPassword) {
9642         enforceModifyPermission();
9643 
9644         Phone phone = getPhone(subId);
9645         if (phone == null) {
9646             return 0;
9647         }
9648         // Now that all security checks passes, perform the operation as ourselves.
9649         final long identity = Binder.clearCallingIdentity();
9650         try {
9651             int attemptsRemaining = (int) sendRequest(CMD_CHANGE_ICC_LOCK_PASSWORD,
9652                     new Pair<String, String>(oldPassword, newPassword), phone, null);
9653             return attemptsRemaining;
9654 
9655         } catch (Exception e) {
9656             Log.e(LOG_TAG, "changeIccLockPassword. Exception e =" + e);
9657         } finally {
9658             Binder.restoreCallingIdentity(identity);
9659         }
9660         return 0;
9661     }
9662 
9663     /**
9664      * Request for receiving user activity notification
9665      */
9666     @Override
requestUserActivityNotification()9667     public void requestUserActivityNotification() {
9668         if (!mNotifyUserActivity.get()
9669                 && !mMainThreadHandler.hasMessages(MSG_NOTIFY_USER_ACTIVITY)) {
9670             mNotifyUserActivity.set(true);
9671         }
9672     }
9673 
9674     /**
9675      * Called when userActivity is signalled in the power manager.
9676      * This is safe to call from any thread, with any window manager locks held or not.
9677      */
9678     @Override
userActivity()9679     public void userActivity() {
9680         // ***************************************
9681         // *  Inherited from PhoneWindowManager  *
9682         // ***************************************
9683         // THIS IS CALLED FROM DEEP IN THE POWER MANAGER
9684         // WITH ITS LOCKS HELD.
9685         //
9686         // This code must be VERY careful about the locks
9687         // it acquires.
9688         // In fact, the current code acquires way too many,
9689         // and probably has lurking deadlocks.
9690 
9691         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9692             throw new SecurityException("Only the OS may call notifyUserActivity()");
9693         }
9694 
9695         if (mNotifyUserActivity.getAndSet(false)) {
9696             mMainThreadHandler.sendEmptyMessageDelayed(MSG_NOTIFY_USER_ACTIVITY,
9697                     USER_ACTIVITY_NOTIFICATION_DELAY);
9698         }
9699     }
9700 
9701     @Override
canConnectTo5GInDsdsMode()9702     public boolean canConnectTo5GInDsdsMode() {
9703         return mApp.getResources().getBoolean(R.bool.config_5g_connection_in_dsds_mode);
9704     }
9705 
9706     @Override
getEquivalentHomePlmns(int subId, String callingPackage, String callingFeatureId)9707     public @NonNull List<String> getEquivalentHomePlmns(int subId, String callingPackage,
9708             String callingFeatureId) {
9709         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
9710                 mApp, subId, callingPackage, callingFeatureId, "getEquivalentHomePlmns")) {
9711             throw new SecurityException("Requires READ_PHONE_STATE permission.");
9712         }
9713 
9714         Phone phone = getPhone(subId);
9715         if (phone == null) {
9716             throw new RuntimeException("phone is not available");
9717         }
9718         // Now that all security checks passes, perform the operation as ourselves.
9719         final long identity = Binder.clearCallingIdentity();
9720         try {
9721             return phone.getEquivalentHomePlmns();
9722         } finally {
9723             Binder.restoreCallingIdentity(identity);
9724         }
9725     }
9726 
9727     @Override
isRadioInterfaceCapabilitySupported( final @NonNull @TelephonyManager.RadioInterfaceCapability String capability)9728     public boolean isRadioInterfaceCapabilitySupported(
9729             final @NonNull @TelephonyManager.RadioInterfaceCapability String capability) {
9730         Set<String> radioInterfaceCapabilities =
9731                 mRadioInterfaceCapabilities.getCapabilities();
9732         if (radioInterfaceCapabilities == null) {
9733             throw new RuntimeException("radio interface capabilities are not available");
9734         }
9735         return radioInterfaceCapabilities.contains(capability);
9736     }
9737 
9738     @Override
bootstrapAuthenticationRequest(int subId, int appType, Uri nafUrl, UaSecurityProtocolIdentifier securityProtocol, boolean forceBootStrapping, IBootstrapAuthenticationCallback callback)9739     public void bootstrapAuthenticationRequest(int subId, int appType, Uri nafUrl,
9740             UaSecurityProtocolIdentifier securityProtocol,
9741             boolean forceBootStrapping, IBootstrapAuthenticationCallback callback) {
9742         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
9743                 Binder.getCallingUid(), "bootstrapAuthenticationRequest",
9744                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
9745                 Manifest.permission.MODIFY_PHONE_STATE);
9746         if (DBG) {
9747             log("bootstrapAuthenticationRequest, subId:" + subId + ", appType:"
9748                     + appType + ", NAF:" + nafUrl + ", sp:" + securityProtocol
9749                     + ", forceBootStrapping:" + forceBootStrapping + ", callback:" + callback);
9750         }
9751 
9752         if (!SubscriptionManager.isValidSubscriptionId(subId)
9753                 || appType < TelephonyManager.APPTYPE_UNKNOWN
9754                 || appType > TelephonyManager.APPTYPE_ISIM
9755                 || nafUrl == null || securityProtocol == null || callback == null) {
9756             Log.d(LOG_TAG, "bootstrapAuthenticationRequest failed due to invalid parameters");
9757             if (callback != null) {
9758                 try {
9759                     callback.onAuthenticationFailure(
9760                             0, TelephonyManager.GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED);
9761                 } catch (RemoteException exception) {
9762                     log("Fail to notify onAuthenticationFailure due to " + exception);
9763                 }
9764                 return;
9765             }
9766         }
9767 
9768         final long token = Binder.clearCallingIdentity();
9769         try {
9770             getGbaManager(subId).bootstrapAuthenticationRequest(
9771                     new GbaAuthRequest(subId, appType, nafUrl, securityProtocol.toByteArray(),
9772                     forceBootStrapping, callback));
9773         } finally {
9774             Binder.restoreCallingIdentity(token);
9775         }
9776     }
9777 
9778     /**
9779      * Attempts to set the radio power state for all phones for thermal reason.
9780      * This does not guarantee that the
9781      * requested radio power state will actually be set. See {@link
9782      * PhoneInternalInterface#setRadioPowerForReason} for more details.
9783      *
9784      * @param enable {@code true} if trying to turn radio on.
9785      * @return {@code true} if phone setRadioPowerForReason was called. Otherwise, returns {@code
9786      * false}.
9787      */
setRadioPowerForThermal(boolean enable)9788     private boolean setRadioPowerForThermal(boolean enable) {
9789         boolean isPhoneAvailable = false;
9790         for (int i = 0; i < TelephonyManager.getDefault().getActiveModemCount(); i++) {
9791             Phone phone = PhoneFactory.getPhone(i);
9792             if (phone != null) {
9793                 phone.setRadioPowerForReason(enable, Phone.RADIO_POWER_REASON_THERMAL);
9794                 isPhoneAvailable = true;
9795             }
9796         }
9797 
9798         // return true if successfully informed the phone object about the thermal radio power
9799         // request.
9800         return isPhoneAvailable;
9801     }
9802 
handleDataThrottlingRequest(int subId, DataThrottlingRequest dataThrottlingRequest)9803     private int handleDataThrottlingRequest(int subId,
9804             DataThrottlingRequest dataThrottlingRequest) {
9805         boolean isDataThrottlingSupported = isRadioInterfaceCapabilitySupported(
9806                 TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING);
9807         if (!isDataThrottlingSupported && dataThrottlingRequest.getDataThrottlingAction()
9808                 != DataThrottlingRequest.DATA_THROTTLING_ACTION_NO_DATA_THROTTLING) {
9809             throw new IllegalArgumentException("modem does not support data throttling");
9810         }
9811 
9812         // Ensure that radio is on. If not able to power on due to phone being unavailable, return
9813         // THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
9814         if (!setRadioPowerForThermal(true)) {
9815             return TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
9816         }
9817 
9818         setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL, true);
9819 
9820         if (isDataThrottlingSupported) {
9821             int thermalMitigationResult =
9822                 (int) sendRequest(CMD_SET_DATA_THROTTLING, dataThrottlingRequest, subId);
9823             if (thermalMitigationResult == SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS) {
9824                 throw new IllegalArgumentException("modem returned INVALID_ARGUMENTS");
9825             } else if (thermalMitigationResult
9826                     == MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE) {
9827                 log("Modem likely does not support data throttling on secondary carrier. Data " +
9828                         "throttling action = " + dataThrottlingRequest.getDataThrottlingAction());
9829                 return TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
9830             }
9831             return thermalMitigationResult;
9832         }
9833 
9834         return TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
9835     }
9836 
getThermalMitigationAllowlist(Context context)9837     private static List<String> getThermalMitigationAllowlist(Context context) {
9838         if (sThermalMitigationAllowlistedPackages.isEmpty()) {
9839             for (String pckg : context.getResources()
9840                     .getStringArray(R.array.thermal_mitigation_allowlisted_packages)) {
9841                 sThermalMitigationAllowlistedPackages.add(pckg);
9842             }
9843         }
9844 
9845         return sThermalMitigationAllowlistedPackages;
9846     }
9847 
isAnyPhoneInEmergencyState()9848     private boolean isAnyPhoneInEmergencyState() {
9849         TelecomManager tm = mApp.getSystemService(TelecomManager.class);
9850         if (tm.isInEmergencyCall()) {
9851             Log.e(LOG_TAG , "Phone state is not valid. One of the phones is in an emergency call");
9852             return true;
9853         }
9854         for (Phone phone : PhoneFactory.getPhones()) {
9855             if (phone.isInEmergencySmsMode() || phone.isInEcm()) {
9856                 Log.e(LOG_TAG, "Phone state is not valid. isInEmergencySmsMode = "
9857                     + phone.isInEmergencySmsMode() + " isInEmergencyCallbackMode = "
9858                     + phone.isInEcm());
9859                 return true;
9860             }
9861         }
9862 
9863         return false;
9864     }
9865 
9866     /**
9867      * Used by shell commands to add an authorized package name for thermal mitigation.
9868      * @param packageName name of package to be allowlisted
9869      * @param context
9870      */
addPackageToThermalMitigationAllowlist(String packageName, Context context)9871     static void addPackageToThermalMitigationAllowlist(String packageName, Context context) {
9872         sThermalMitigationAllowlistedPackages = getThermalMitigationAllowlist(context);
9873         sThermalMitigationAllowlistedPackages.add(packageName);
9874     }
9875 
9876     /**
9877      * Used by shell commands to remove an authorized package name for thermal mitigation.
9878      * @param packageName name of package to remove from allowlist
9879      * @param context
9880      */
removePackageFromThermalMitigationAllowlist(String packageName, Context context)9881     static void removePackageFromThermalMitigationAllowlist(String packageName, Context context) {
9882         sThermalMitigationAllowlistedPackages = getThermalMitigationAllowlist(context);
9883         sThermalMitigationAllowlistedPackages.remove(packageName);
9884     }
9885 
9886     /**
9887      * Thermal mitigation request to control functionalities at modem.
9888      *
9889      * @param subId the id of the subscription.
9890      * @param thermalMitigationRequest holds all necessary information to be passed down to modem.
9891      * @param callingPackage the package name of the calling package.
9892      *
9893      * @return thermalMitigationResult enum as defined in android.telephony.Annotation.
9894      */
9895     @Override
9896     @ThermalMitigationResult
sendThermalMitigationRequest( int subId, ThermalMitigationRequest thermalMitigationRequest, String callingPackage)9897     public int sendThermalMitigationRequest(
9898             int subId,
9899             ThermalMitigationRequest thermalMitigationRequest,
9900             String callingPackage) throws IllegalArgumentException {
9901         enforceModifyPermission();
9902 
9903         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
9904         if (!getThermalMitigationAllowlist(getDefaultPhone().getContext())
9905                 .contains(callingPackage)) {
9906             throw new SecurityException("Calling package must be configured in the device config. "
9907                     + "calling package: " + callingPackage);
9908         }
9909 
9910         WorkSource workSource = getWorkSource(Binder.getCallingUid());
9911         final long identity = Binder.clearCallingIdentity();
9912 
9913         int thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR;
9914         try {
9915             int thermalMitigationAction = thermalMitigationRequest.getThermalMitigationAction();
9916             switch (thermalMitigationAction) {
9917                 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_DATA_THROTTLING:
9918                     thermalMitigationResult =
9919                         handleDataThrottlingRequest(subId,
9920                                 thermalMitigationRequest.getDataThrottlingRequest());
9921                     break;
9922                 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY:
9923                     if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
9924                         throw new IllegalArgumentException("dataThrottlingRequest must be null for "
9925                                 + "ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY");
9926                     }
9927 
9928                     // Ensure that radio is on. If not able to power on due to phone being
9929                     // unavailable, return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
9930                     if (!setRadioPowerForThermal(true)) {
9931                         thermalMitigationResult =
9932                                 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
9933                         break;
9934                     }
9935 
9936                     setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL,
9937                             false);
9938                     thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
9939                     break;
9940                 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF:
9941                     if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
9942                         throw new IllegalArgumentException("dataThrottlingRequest  must be null for"
9943                                 + " ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF");
9944                     }
9945 
9946                     TelecomAccountRegistry registry = TelecomAccountRegistry.getInstance(null);
9947                     if (registry != null) {
9948                         Phone phone = getPhone(subId);
9949                         if (phone == null) {
9950                             thermalMitigationResult =
9951                                 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
9952                             break;
9953                         }
9954 
9955                         TelephonyConnectionService service =
9956                                 registry.getTelephonyConnectionService();
9957                         if (service != null && service.isEmergencyCallPending()) {
9958                             Log.e(LOG_TAG, "An emergency call is pending");
9959                             thermalMitigationResult =
9960                                     TelephonyManager.THERMAL_MITIGATION_RESULT_INVALID_STATE;
9961                             break;
9962                         } else if (isAnyPhoneInEmergencyState()) {
9963                             thermalMitigationResult =
9964                                 TelephonyManager.THERMAL_MITIGATION_RESULT_INVALID_STATE;
9965                             break;
9966                         }
9967                     } else {
9968                         thermalMitigationResult =
9969                                 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
9970                         break;
9971                     }
9972 
9973                     // Turn radio off. If not able to power off due to phone being unavailable,
9974                     // return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
9975                     if (!setRadioPowerForThermal(false)) {
9976                         thermalMitigationResult =
9977                                 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
9978                         break;
9979                     }
9980                     thermalMitigationResult =
9981                         TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
9982                     break;
9983                 default:
9984                     throw new IllegalArgumentException("the requested thermalMitigationAction does "
9985                             + "not exist. Requested action: " + thermalMitigationAction);
9986             }
9987         } catch (IllegalArgumentException e) {
9988             throw e;
9989         } catch (Exception e) {
9990             Log.e(LOG_TAG, "thermalMitigationRequest. Exception e =" + e);
9991             thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
9992         } finally {
9993             Binder.restoreCallingIdentity(identity);
9994         }
9995 
9996         if (DBG) {
9997             log("thermalMitigationRequest returning with thermalMitigationResult: "
9998                     + thermalMitigationResult);
9999         }
10000 
10001         return thermalMitigationResult;
10002     }
10003 
10004     /**
10005      * Set the GbaService Package Name that Telephony will bind to.
10006      *
10007      * @param subId The sim that the GbaService is associated with.
10008      * @param packageName The name of the package to be replaced with.
10009      * @return true if setting the GbaService to bind to succeeded, false if it did not.
10010      */
10011     @Override
setBoundGbaServiceOverride(int subId, String packageName)10012     public boolean setBoundGbaServiceOverride(int subId, String packageName) {
10013         enforceModifyPermission();
10014 
10015         final long identity = Binder.clearCallingIdentity();
10016         try {
10017             return getGbaManager(subId).overrideServicePackage(packageName);
10018         } finally {
10019             Binder.restoreCallingIdentity(identity);
10020         }
10021     }
10022 
10023     /**
10024      * Return the package name of the currently bound GbaService.
10025      *
10026      * @param subId The sim that the GbaService is associated with.
10027      * @return the package name of the GbaService configuration, null if GBA is not supported.
10028      */
10029     @Override
getBoundGbaService(int subId)10030     public String getBoundGbaService(int subId) {
10031         enforceReadPrivilegedPermission("getBoundGbaServicePackage");
10032 
10033         final long identity = Binder.clearCallingIdentity();
10034         try {
10035             return getGbaManager(subId).getServicePackage();
10036         } finally {
10037             Binder.restoreCallingIdentity(identity);
10038         }
10039     }
10040 
10041     /**
10042      * Set the release time for telephony to unbind GbaService.
10043      *
10044      * @param subId The sim that the GbaService is associated with.
10045      * @param interval The release time to unbind GbaService by millisecond.
10046      * @return true if setting the GbaService to bind to succeeded, false if it did not.
10047      */
10048     @Override
setGbaReleaseTimeOverride(int subId, int interval)10049     public boolean setGbaReleaseTimeOverride(int subId, int interval) {
10050         enforceModifyPermission();
10051 
10052         final long identity = Binder.clearCallingIdentity();
10053         try {
10054             return getGbaManager(subId).overrideReleaseTime(interval);
10055         } finally {
10056             Binder.restoreCallingIdentity(identity);
10057         }
10058     }
10059 
10060     /**
10061      * Return the release time for telephony to unbind GbaService.
10062      *
10063      * @param subId The sim that the GbaService is associated with.
10064      * @return The release time to unbind GbaService by millisecond.
10065      */
10066     @Override
getGbaReleaseTime(int subId)10067     public int getGbaReleaseTime(int subId) {
10068         enforceReadPrivilegedPermission("getGbaReleaseTime");
10069 
10070         final long identity = Binder.clearCallingIdentity();
10071         try {
10072             return getGbaManager(subId).getReleaseTime();
10073         } finally {
10074             Binder.restoreCallingIdentity(identity);
10075         }
10076     }
10077 
getGbaManager(int subId)10078     private GbaManager getGbaManager(int subId) {
10079         GbaManager instance = GbaManager.getInstance(subId);
10080         if (instance == null) {
10081             String packageName = mApp.getResources().getString(R.string.config_gba_package);
10082             int releaseTime = mApp.getResources().getInteger(R.integer.config_gba_release_time);
10083             instance = GbaManager.make(mApp, subId, packageName, releaseTime);
10084         }
10085         return instance;
10086     }
10087 
10088     /**
10089      * indicate whether the device and the carrier can support
10090      * RCS VoLTE single registration.
10091      */
10092     @Override
isRcsVolteSingleRegistrationCapable(int subId)10093     public boolean isRcsVolteSingleRegistrationCapable(int subId) {
10094         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
10095                 Binder.getCallingUid(), "isRcsVolteSingleRegistrationCapable",
10096                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
10097                 permission.READ_PRIVILEGED_PHONE_STATE);
10098 
10099         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
10100             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
10101         }
10102 
10103         final long identity = Binder.clearCallingIdentity();
10104         try {
10105             RcsProvisioningMonitor rpm = RcsProvisioningMonitor.getInstance();
10106             if (rpm != null) {
10107                 Boolean isCapable = rpm.isRcsVolteSingleRegistrationEnabled(subId);
10108                 if (isCapable != null) {
10109                     return isCapable;
10110                 }
10111             }
10112             throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
10113                     "service is temporarily unavailable.");
10114         } finally {
10115             Binder.restoreCallingIdentity(identity);
10116         }
10117     }
10118 
10119     /**
10120      * Register RCS provisioning callback.
10121      */
10122     @Override
registerRcsProvisioningCallback(int subId, IRcsConfigCallback callback)10123     public void registerRcsProvisioningCallback(int subId,
10124             IRcsConfigCallback callback) {
10125         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
10126                 Binder.getCallingUid(), "registerRcsProvisioningCallback",
10127                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
10128                 permission.READ_PRIVILEGED_PHONE_STATE);
10129 
10130         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
10131             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
10132         }
10133         if (!isImsAvailableOnDevice()) {
10134             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
10135                     "IMS not available on device.");
10136         }
10137 
10138         final long identity = Binder.clearCallingIdentity();
10139         try {
10140             if (!RcsProvisioningMonitor.getInstance()
10141                     .registerRcsProvisioningCallback(subId, callback)) {
10142                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
10143                         "Active subscription not found.");
10144             }
10145         } finally {
10146             Binder.restoreCallingIdentity(identity);
10147         }
10148     }
10149 
10150     /**
10151      * Unregister RCS provisioning callback.
10152      */
10153     @Override
unregisterRcsProvisioningCallback(int subId, IRcsConfigCallback callback)10154     public void unregisterRcsProvisioningCallback(int subId,
10155             IRcsConfigCallback callback) {
10156         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
10157                 Binder.getCallingUid(), "unregisterRcsProvisioningCallback",
10158                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
10159                 permission.READ_PRIVILEGED_PHONE_STATE);
10160 
10161         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
10162             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
10163         }
10164         if (!isImsAvailableOnDevice()) {
10165             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
10166                     "IMS not available on device.");
10167         }
10168 
10169         final long identity = Binder.clearCallingIdentity();
10170         try {
10171             RcsProvisioningMonitor.getInstance()
10172                     .unregisterRcsProvisioningCallback(subId, callback);
10173         } finally {
10174             Binder.restoreCallingIdentity(identity);
10175         }
10176     }
10177 
10178     /**
10179      * trigger RCS reconfiguration.
10180      */
triggerRcsReconfiguration(int subId)10181     public void triggerRcsReconfiguration(int subId) {
10182         TelephonyPermissions.enforceAnyPermissionGranted(mApp, Binder.getCallingUid(),
10183                 "triggerRcsReconfiguration",
10184                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
10185 
10186         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
10187             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
10188         }
10189         if (!isImsAvailableOnDevice()) {
10190             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
10191                     "IMS not available on device.");
10192         }
10193 
10194         final long identity = Binder.clearCallingIdentity();
10195         try {
10196             RcsProvisioningMonitor.getInstance().requestReconfig(subId);
10197         } finally {
10198             Binder.restoreCallingIdentity(identity);
10199         }
10200     }
10201 
10202     /**
10203      * Provide the client configuration parameters of the RCS application.
10204      */
setRcsClientConfiguration(int subId, RcsClientConfiguration rcc)10205     public void setRcsClientConfiguration(int subId, RcsClientConfiguration rcc) {
10206         TelephonyPermissions.enforceAnyPermissionGranted(mApp, Binder.getCallingUid(),
10207                 "setRcsClientConfiguration",
10208                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
10209 
10210         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
10211             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
10212         }
10213         if (!isImsAvailableOnDevice()) {
10214             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
10215                     "IMS not available on device.");
10216         }
10217 
10218         final long identity = Binder.clearCallingIdentity();
10219 
10220         try {
10221             IImsConfig configBinder = getImsConfig(getSlotIndex(subId), ImsFeature.FEATURE_RCS);
10222             if (configBinder == null) {
10223                 Rlog.e(LOG_TAG, "null result for setRcsClientConfiguration");
10224                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
10225                         "could not find the requested subscription");
10226             } else {
10227                 configBinder.setRcsClientConfiguration(rcc);
10228             }
10229         } catch (RemoteException e) {
10230             Rlog.e(LOG_TAG, "fail to setRcsClientConfiguration " + e.getMessage());
10231             throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
10232                     "service is temporarily unavailable.");
10233         } finally {
10234             Binder.restoreCallingIdentity(identity);
10235         }
10236     }
10237 
10238     /**
10239      * Enables or disables the test mode for RCS VoLTE single registration.
10240      */
10241     @Override
setRcsSingleRegistrationTestModeEnabled(boolean enabled)10242     public void setRcsSingleRegistrationTestModeEnabled(boolean enabled) {
10243         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10244                 "setRcsSingleRegistrationTestModeEnabled");
10245 
10246         RcsProvisioningMonitor.getInstance().setTestModeEnabled(enabled);
10247     }
10248 
10249     /**
10250      * Gets the test mode for RCS VoLTE single registration.
10251      */
10252     @Override
getRcsSingleRegistrationTestModeEnabled()10253     public boolean getRcsSingleRegistrationTestModeEnabled() {
10254         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10255                 "getRcsSingleRegistrationTestModeEnabled");
10256 
10257         return RcsProvisioningMonitor.getInstance().getTestModeEnabled();
10258     }
10259 
10260     /**
10261      * Overrides the config of RCS VoLTE single registration enabled for the device.
10262      */
10263     @Override
setDeviceSingleRegistrationEnabledOverride(String enabledStr)10264     public void setDeviceSingleRegistrationEnabledOverride(String enabledStr) {
10265         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10266                 "setDeviceSingleRegistrationEnabledOverride");
10267         enforceModifyPermission();
10268 
10269         Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
10270                 : Boolean.parseBoolean(enabledStr);
10271         RcsProvisioningMonitor.getInstance().overrideDeviceSingleRegistrationEnabled(enabled);
10272         mApp.imsRcsController.setDeviceSingleRegistrationSupportOverride(enabled);
10273     }
10274 
10275     /**
10276      * Sends a device to device communication message.  Only usable via shell.
10277      * @param message message to send.
10278      * @param value message value.
10279      */
10280     @Override
sendDeviceToDeviceMessage(int message, int value)10281     public void sendDeviceToDeviceMessage(int message, int value) {
10282         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10283                 "sendDeviceToDeviceMessage");
10284         enforceModifyPermission();
10285 
10286         final long identity = Binder.clearCallingIdentity();
10287         try {
10288             TelephonyConnectionService service =
10289                     TelecomAccountRegistry.getInstance(null).getTelephonyConnectionService();
10290             if (service == null) {
10291                 Rlog.e(LOG_TAG, "sendDeviceToDeviceMessage: not in a call.");
10292                 return;
10293             }
10294             service.sendTestDeviceToDeviceMessage(message, value);
10295         } finally {
10296             Binder.restoreCallingIdentity(identity);
10297         }
10298     }
10299 
10300     /**
10301      * Sets the specified device to device transport active.
10302      * @param transport The transport to set active.
10303      */
10304     @Override
setActiveDeviceToDeviceTransport(@onNull String transport)10305     public void setActiveDeviceToDeviceTransport(@NonNull String transport) {
10306         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10307                 "setActiveDeviceToDeviceTransport");
10308         enforceModifyPermission();
10309 
10310         final long identity = Binder.clearCallingIdentity();
10311         try {
10312             TelephonyConnectionService service =
10313                     TelecomAccountRegistry.getInstance(null).getTelephonyConnectionService();
10314             if (service == null) {
10315                 Rlog.e(LOG_TAG, "setActiveDeviceToDeviceTransport: not in a call.");
10316                 return;
10317             }
10318             service.setActiveDeviceToDeviceTransport(transport);
10319         } finally {
10320             Binder.restoreCallingIdentity(identity);
10321         }
10322     }
10323 
10324     @Override
setDeviceToDeviceForceEnabled(boolean isForceEnabled)10325     public void setDeviceToDeviceForceEnabled(boolean isForceEnabled) {
10326         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10327                 "setDeviceToDeviceForceEnabled");
10328 
10329         final long identity = Binder.clearCallingIdentity();
10330         try {
10331             Arrays.stream(PhoneFactory.getPhones()).forEach(
10332                     p -> {
10333                         Phone thePhone = p.getImsPhone();
10334                         if (thePhone != null && thePhone instanceof ImsPhone) {
10335                             ImsPhone imsPhone = (ImsPhone) thePhone;
10336                             CallTracker tracker = imsPhone.getCallTracker();
10337                             if (tracker != null && tracker instanceof ImsPhoneCallTracker) {
10338                                 ImsPhoneCallTracker imsPhoneCallTracker =
10339                                         (ImsPhoneCallTracker) tracker;
10340                                 imsPhoneCallTracker.setDeviceToDeviceForceEnabled(isForceEnabled);
10341                             }
10342                         }
10343                     }
10344             );
10345         } finally {
10346             Binder.restoreCallingIdentity(identity);
10347         }
10348     }
10349 
10350     /**
10351      * Gets the config of RCS VoLTE single registration enabled for the device.
10352      */
10353     @Override
getDeviceSingleRegistrationEnabled()10354     public boolean getDeviceSingleRegistrationEnabled() {
10355         enforceReadPrivilegedPermission("getDeviceSingleRegistrationEnabled");
10356         return RcsProvisioningMonitor.getInstance().getDeviceSingleRegistrationEnabled();
10357     }
10358 
10359     /**
10360      * Overrides the config of RCS VoLTE single registration enabled for the carrier/subscription.
10361      */
10362     @Override
setCarrierSingleRegistrationEnabledOverride(int subId, String enabledStr)10363     public boolean setCarrierSingleRegistrationEnabledOverride(int subId, String enabledStr) {
10364         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10365                 "setCarrierSingleRegistrationEnabledOverride");
10366         enforceModifyPermission();
10367 
10368         Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
10369                 : Boolean.parseBoolean(enabledStr);
10370         return RcsProvisioningMonitor.getInstance().overrideCarrierSingleRegistrationEnabled(
10371                 subId, enabled);
10372     }
10373 
10374     /**
10375      * Gets the config of RCS VoLTE single registration enabled for the carrier/subscription.
10376      */
10377     @Override
getCarrierSingleRegistrationEnabled(int subId)10378     public boolean getCarrierSingleRegistrationEnabled(int subId) {
10379         enforceReadPrivilegedPermission("getCarrierSingleRegistrationEnabled");
10380         return RcsProvisioningMonitor.getInstance().getCarrierSingleRegistrationEnabled(subId);
10381     }
10382 
10383     /**
10384      * Overrides the ims feature validation result
10385      */
10386     @Override
setImsFeatureValidationOverride(int subId, String enabledStr)10387     public boolean setImsFeatureValidationOverride(int subId, String enabledStr) {
10388         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10389                 "setImsFeatureValidationOverride");
10390 
10391         Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
10392                 : Boolean.parseBoolean(enabledStr);
10393         return RcsProvisioningMonitor.getInstance().overrideImsFeatureValidation(
10394                 subId, enabled);
10395     }
10396 
10397     /**
10398      * Gets the ims feature validation override value
10399      */
10400     @Override
getImsFeatureValidationOverride(int subId)10401     public boolean getImsFeatureValidationOverride(int subId) {
10402         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10403                 "getImsFeatureValidationOverride");
10404         return RcsProvisioningMonitor.getInstance().getImsFeatureValidationOverride(subId);
10405     }
10406 
10407     /**
10408      * Get the mobile provisioning url that is used to launch a browser to allow users to manage
10409      * their mobile plan.
10410      */
10411     @Override
getMobileProvisioningUrl()10412     public String getMobileProvisioningUrl() {
10413         enforceReadPrivilegedPermission("getMobileProvisioningUrl");
10414         final long identity = Binder.clearCallingIdentity();
10415         try {
10416             return getDefaultPhone().getMobileProvisioningUrl();
10417         } finally {
10418             Binder.restoreCallingIdentity(identity);
10419         }
10420     }
10421 
10422     /**
10423      * Get the EAB contact from the EAB database.
10424      */
10425     @Override
getContactFromEab(String contact)10426     public String getContactFromEab(String contact) {
10427         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getContactFromEab");
10428         enforceModifyPermission();
10429         final long identity = Binder.clearCallingIdentity();
10430         try {
10431             return EabUtil.getContactFromEab(getDefaultPhone().getContext(), contact);
10432         } finally {
10433             Binder.restoreCallingIdentity(identity);
10434         }
10435     }
10436 
10437     /**
10438      * Get the EAB capability from the EAB database.
10439      */
10440     @Override
getCapabilityFromEab(String contact)10441     public String getCapabilityFromEab(String contact) {
10442         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getCapabilityFromEab");
10443         enforceModifyPermission();
10444         final long identity = Binder.clearCallingIdentity();
10445         try {
10446             return EabUtil.getCapabilityFromEab(getDefaultPhone().getContext(), contact);
10447         } finally {
10448             Binder.restoreCallingIdentity(identity);
10449         }
10450     }
10451 
10452     /**
10453      * Remove the EAB contacts from the EAB database.
10454      */
10455     @Override
removeContactFromEab(int subId, String contacts)10456     public int removeContactFromEab(int subId, String contacts) {
10457         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "removeCapabilitiesFromEab");
10458         enforceModifyPermission();
10459         final long identity = Binder.clearCallingIdentity();
10460         try {
10461             return EabUtil.removeContactFromEab(subId, contacts, getDefaultPhone().getContext());
10462         } finally {
10463             Binder.restoreCallingIdentity(identity);
10464         }
10465     }
10466 
10467     @Override
getDeviceUceEnabled()10468     public boolean getDeviceUceEnabled() {
10469         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getDeviceUceEnabled");
10470         final long identity = Binder.clearCallingIdentity();
10471         try {
10472             return mApp.getDeviceUceEnabled();
10473         } finally {
10474             Binder.restoreCallingIdentity(identity);
10475         }
10476     }
10477 
10478     @Override
setDeviceUceEnabled(boolean isEnabled)10479     public void setDeviceUceEnabled(boolean isEnabled) {
10480         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setDeviceUceEnabled");
10481         final long identity = Binder.clearCallingIdentity();
10482         try {
10483             mApp.setDeviceUceEnabled(isEnabled);
10484         } finally {
10485             Binder.restoreCallingIdentity(identity);
10486         }
10487     }
10488 
10489     /**
10490      * Add new feature tags to the Set used to calculate the capabilities in PUBLISH.
10491      * @return current RcsContactUceCapability instance that will be used for PUBLISH.
10492      */
10493     // Used for SHELL command only right now.
10494     @Override
addUceRegistrationOverrideShell(int subId, List<String> featureTags)10495     public RcsContactUceCapability addUceRegistrationOverrideShell(int subId,
10496             List<String> featureTags) {
10497         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10498                 "addUceRegistrationOverrideShell");
10499         final long identity = Binder.clearCallingIdentity();
10500         try {
10501             return mApp.imsRcsController.addUceRegistrationOverrideShell(subId,
10502                     new ArraySet<>(featureTags));
10503         } catch (ImsException e) {
10504             throw new ServiceSpecificException(e.getCode(), e.getMessage());
10505         } finally {
10506             Binder.restoreCallingIdentity(identity);
10507         }
10508     }
10509 
10510     /**
10511      * Remove existing feature tags to the Set used to calculate the capabilities in PUBLISH.
10512      * @return current RcsContactUceCapability instance that will be used for PUBLISH.
10513      */
10514     // Used for SHELL command only right now.
10515     @Override
removeUceRegistrationOverrideShell(int subId, List<String> featureTags)10516     public RcsContactUceCapability removeUceRegistrationOverrideShell(int subId,
10517             List<String> featureTags) {
10518         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10519                 "removeUceRegistrationOverrideShell");
10520         final long identity = Binder.clearCallingIdentity();
10521         try {
10522             return mApp.imsRcsController.removeUceRegistrationOverrideShell(subId,
10523                     new ArraySet<>(featureTags));
10524         } catch (ImsException e) {
10525             throw new ServiceSpecificException(e.getCode(), e.getMessage());
10526         } finally {
10527             Binder.restoreCallingIdentity(identity);
10528         }
10529     }
10530 
10531     /**
10532      * Clear all overrides in the Set used to calculate the capabilities in PUBLISH.
10533      * @return current RcsContactUceCapability instance that will be used for PUBLISH.
10534      */
10535     // Used for SHELL command only right now.
10536     @Override
clearUceRegistrationOverrideShell(int subId)10537     public RcsContactUceCapability clearUceRegistrationOverrideShell(int subId) {
10538         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10539                 "clearUceRegistrationOverrideShell");
10540         final long identity = Binder.clearCallingIdentity();
10541         try {
10542             return mApp.imsRcsController.clearUceRegistrationOverrideShell(subId);
10543         } catch (ImsException e) {
10544             throw new ServiceSpecificException(e.getCode(), e.getMessage());
10545         } finally {
10546             Binder.restoreCallingIdentity(identity);
10547         }
10548     }
10549 
10550     /**
10551      * @return current RcsContactUceCapability instance that will be used for PUBLISH.
10552      */
10553     // Used for SHELL command only right now.
10554     @Override
getLatestRcsContactUceCapabilityShell(int subId)10555     public RcsContactUceCapability getLatestRcsContactUceCapabilityShell(int subId) {
10556         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10557                 "getLatestRcsContactUceCapabilityShell");
10558         final long identity = Binder.clearCallingIdentity();
10559         try {
10560             return mApp.imsRcsController.getLatestRcsContactUceCapabilityShell(subId);
10561         } catch (ImsException e) {
10562             throw new ServiceSpecificException(e.getCode(), e.getMessage());
10563         } finally {
10564             Binder.restoreCallingIdentity(identity);
10565         }
10566     }
10567 
10568     /**
10569      * Returns the last PIDF XML sent to the network during the last PUBLISH or "none" if the
10570      * device does not have an active PUBLISH.
10571      */
10572     // Used for SHELL command only right now.
10573     @Override
getLastUcePidfXmlShell(int subId)10574     public String getLastUcePidfXmlShell(int subId) {
10575         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "uceGetLastPidfXml");
10576         final long identity = Binder.clearCallingIdentity();
10577         try {
10578             return mApp.imsRcsController.getLastUcePidfXmlShell(subId);
10579         } catch (ImsException e) {
10580             throw new ServiceSpecificException(e.getCode(), e.getMessage());
10581         } finally {
10582             Binder.restoreCallingIdentity(identity);
10583         }
10584     }
10585 
10586     /**
10587      * Remove UCE requests cannot be sent to the network status.
10588      */
10589     // Used for SHELL command only right now.
10590     @Override
removeUceRequestDisallowedStatus(int subId)10591     public boolean removeUceRequestDisallowedStatus(int subId) {
10592         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "uceRemoveDisallowedStatus");
10593         final long identity = Binder.clearCallingIdentity();
10594         try {
10595             return mApp.imsRcsController.removeUceRequestDisallowedStatus(subId);
10596         } catch (ImsException e) {
10597             throw new ServiceSpecificException(e.getCode(), e.getMessage());
10598         } finally {
10599             Binder.restoreCallingIdentity(identity);
10600         }
10601     }
10602 
10603     /**
10604      * Remove UCE requests cannot be sent to the network status.
10605      */
10606     // Used for SHELL command only.
10607     @Override
setCapabilitiesRequestTimeout(int subId, long timeoutAfterMs)10608     public boolean setCapabilitiesRequestTimeout(int subId, long timeoutAfterMs) {
10609         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCapRequestTimeout");
10610         final long identity = Binder.clearCallingIdentity();
10611         try {
10612             return mApp.imsRcsController.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
10613         } catch (ImsException e) {
10614             throw new ServiceSpecificException(e.getCode(), e.getMessage());
10615         } finally {
10616             Binder.restoreCallingIdentity(identity);
10617         }
10618     }
10619 
10620     @Override
setSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request, String callingPackage)10621     public void setSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request,
10622             String callingPackage) {
10623         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
10624                 mApp, subId, "setSignalStrengthUpdateRequest");
10625 
10626         final int callingUid = Binder.getCallingUid();
10627         // Verify that tha callingPackage belongs to the calling UID
10628         mApp.getSystemService(AppOpsManager.class)
10629                 .checkPackage(callingUid, callingPackage);
10630 
10631         validateSignalStrengthUpdateRequest(request, callingUid);
10632 
10633         final long identity = Binder.clearCallingIdentity();
10634         try {
10635             Object result = sendRequest(CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST,
10636                     new Pair<Integer, SignalStrengthUpdateRequest>(callingUid, request), subId);
10637 
10638             if (result instanceof IllegalStateException) {
10639                 throw (IllegalStateException) result;
10640             }
10641         } finally {
10642             Binder.restoreCallingIdentity(identity);
10643         }
10644     }
10645 
10646     @Override
clearSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request, String callingPackage)10647     public void clearSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request,
10648             String callingPackage) {
10649         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
10650                 mApp, subId, "clearSignalStrengthUpdateRequest");
10651 
10652         final int callingUid = Binder.getCallingUid();
10653         // Verify that tha callingPackage belongs to the calling UID
10654         mApp.getSystemService(AppOpsManager.class)
10655                 .checkPackage(callingUid, callingPackage);
10656 
10657         final long identity = Binder.clearCallingIdentity();
10658         try {
10659             Object result = sendRequest(CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST,
10660                     new Pair<Integer, SignalStrengthUpdateRequest>(callingUid, request), subId);
10661 
10662             if (result instanceof IllegalStateException) {
10663                 throw (IllegalStateException) result;
10664             }
10665         } finally {
10666             Binder.restoreCallingIdentity(identity);
10667         }
10668     }
10669 
validateSignalStrengthUpdateRequest(SignalStrengthUpdateRequest request, int callingUid)10670     private static void validateSignalStrengthUpdateRequest(SignalStrengthUpdateRequest request,
10671             int callingUid) {
10672         if (callingUid == Process.PHONE_UID || callingUid == Process.SYSTEM_UID) {
10673             // phone/system process do not have further restriction on request
10674             return;
10675         }
10676 
10677         // Applications has restrictions on how to use the request:
10678         // Only system caller can set mIsSystemThresholdReportingRequestedWhileIdle
10679         if (request.isSystemThresholdReportingRequestedWhileIdle()) {
10680             // This is not system caller which has been checked above
10681             throw new IllegalArgumentException(
10682                     "Only system can set isSystemThresholdReportingRequestedWhileIdle");
10683         }
10684 
10685         for (SignalThresholdInfo info : request.getSignalThresholdInfos()) {
10686             // Only system caller can set mHysteresisMs/mHysteresisDb/mIsEnabled.
10687             if (info.getHysteresisMs() != SignalThresholdInfo.HYSTERESIS_MS_DISABLED
10688                     || info.getHysteresisDb() != SignalThresholdInfo.HYSTERESIS_DB_DISABLED
10689                     || info.isEnabled()) {
10690                 throw new IllegalArgumentException(
10691                         "Only system can set hide fields in SignalThresholdInfo");
10692             }
10693 
10694             // Thresholds length for each RAN need in range. This has been validated in
10695             // SignalThresholdInfo#Builder#setThreshold. Here we prevent apps calling hide method
10696             // setThresholdUnlimited (e.g. through reflection) with too short or too long thresholds
10697             final int[] thresholds = info.getThresholds();
10698             Objects.requireNonNull(thresholds);
10699             if (thresholds.length < SignalThresholdInfo.getMinimumNumberOfThresholdsAllowed()
10700                     || thresholds.length
10701                     > SignalThresholdInfo.getMaximumNumberOfThresholdsAllowed()) {
10702                 throw new IllegalArgumentException(
10703                         "thresholds length is out of range: " + thresholds.length);
10704             }
10705         }
10706     }
10707 
10708     /**
10709      * Gets the current phone capability.
10710      *
10711      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
10712      * @return the PhoneCapability which describes the data connection capability of modem.
10713      * It's used to evaluate possible phone config change, for example from single
10714      * SIM device to multi-SIM device.
10715      */
10716     @Override
getPhoneCapability()10717     public PhoneCapability getPhoneCapability() {
10718         enforceReadPrivilegedPermission("getPhoneCapability");
10719         final long identity = Binder.clearCallingIdentity();
10720         try {
10721             return mPhoneConfigurationManager.getCurrentPhoneCapability();
10722         } finally {
10723             Binder.restoreCallingIdentity(identity);
10724         }
10725     }
10726 
10727     /**
10728      * Prepare TelephonyManager for an unattended reboot. The reboot is
10729      * required to be done shortly after the API is invoked.
10730      */
10731     @Override
10732     @TelephonyManager.PrepareUnattendedRebootResult
prepareForUnattendedReboot()10733     public int prepareForUnattendedReboot() {
10734         enforceRebootPermission();
10735 
10736         final long identity = Binder.clearCallingIdentity();
10737         try {
10738             return (int) sendRequest(CMD_PREPARE_UNATTENDED_REBOOT, null);
10739         } finally {
10740             Binder.restoreCallingIdentity(identity);
10741         }
10742     }
10743 
10744     /**
10745      * Request to get the current slicing configuration including URSP rules and
10746      * NSSAIs (configured, allowed and rejected).
10747      *
10748      * Requires carrier privileges or READ_PRIVILEGED_PHONE_STATE permission.
10749      */
10750     @Override
getSlicingConfig(ResultReceiver callback)10751     public void getSlicingConfig(ResultReceiver callback) {
10752         enforceReadPrivilegedPermission("getSlicingConfig");
10753 
10754         final long identity = Binder.clearCallingIdentity();
10755         try {
10756             Phone phone = getDefaultPhone();
10757             sendRequestAsync(CMD_GET_SLICING_CONFIG, callback, phone, null);
10758         } finally {
10759             Binder.restoreCallingIdentity(identity);
10760         }
10761     }
10762 }
10763