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