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