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