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.FEATURE_TELEPHONY_IMS;
20 import static android.content.pm.PackageManager.FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION;
21 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
22 import static android.permission.flags.Flags.opEnableMobileDataByUser;
23 import static android.telephony.TelephonyManager.ENABLE_FEATURE_MAPPING;
24 import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
25 import static android.telephony.TelephonyManager.HAL_SERVICE_RADIO;
26 import static android.telephony.satellite.SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED;
27 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ACCESS_BARRED;
28 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
29 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
30 
31 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_CDMA;
32 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_GSM;
33 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_IMS;
34 import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
35 import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT;
36 
37 import android.Manifest;
38 import android.Manifest.permission;
39 import android.annotation.NonNull;
40 import android.annotation.Nullable;
41 import android.annotation.RequiresPermission;
42 import android.app.ActivityManager;
43 import android.app.AppOpsManager;
44 import android.app.PendingIntent;
45 import android.app.PropertyInvalidatedCache;
46 import android.app.compat.CompatChanges;
47 import android.app.role.RoleManager;
48 import android.compat.annotation.ChangeId;
49 import android.compat.annotation.EnabledSince;
50 import android.content.ActivityNotFoundException;
51 import android.content.ComponentName;
52 import android.content.ContentResolver;
53 import android.content.Context;
54 import android.content.Intent;
55 import android.content.SharedPreferences;
56 import android.content.pm.ComponentInfo;
57 import android.content.pm.PackageManager;
58 import android.net.Uri;
59 import android.os.AsyncResult;
60 import android.os.Binder;
61 import android.os.Build;
62 import android.os.Bundle;
63 import android.os.DropBoxManager;
64 import android.os.Handler;
65 import android.os.IBinder;
66 import android.os.ICancellationSignal;
67 import android.os.LocaleList;
68 import android.os.Looper;
69 import android.os.Message;
70 import android.os.Messenger;
71 import android.os.ParcelFileDescriptor;
72 import android.os.ParcelUuid;
73 import android.os.PersistableBundle;
74 import android.os.Process;
75 import android.os.RemoteException;
76 import android.os.ResultReceiver;
77 import android.os.ServiceSpecificException;
78 import android.os.SystemClock;
79 import android.os.SystemProperties;
80 import android.os.UserHandle;
81 import android.os.UserManager;
82 import android.os.WorkSource;
83 import android.preference.PreferenceManager;
84 import android.provider.DeviceConfig;
85 import android.provider.Settings;
86 import android.provider.Telephony;
87 import android.service.carrier.CarrierIdentifier;
88 import android.sysprop.TelephonyProperties;
89 import android.telecom.PhoneAccount;
90 import android.telecom.PhoneAccountHandle;
91 import android.telecom.TelecomManager;
92 import android.telephony.AccessNetworkConstants;
93 import android.telephony.ActivityStatsTechSpecificInfo;
94 import android.telephony.Annotation.ApnType;
95 import android.telephony.Annotation.DataActivityType;
96 import android.telephony.Annotation.ThermalMitigationResult;
97 import android.telephony.AnomalyReporter;
98 import android.telephony.CallForwardingInfo;
99 import android.telephony.CarrierConfigManager;
100 import android.telephony.CarrierRestrictionRules;
101 import android.telephony.CellBroadcastIdRange;
102 import android.telephony.CellIdentity;
103 import android.telephony.CellIdentityCdma;
104 import android.telephony.CellIdentityGsm;
105 import android.telephony.CellInfo;
106 import android.telephony.CellInfoGsm;
107 import android.telephony.CellInfoWcdma;
108 import android.telephony.ClientRequestStats;
109 import android.telephony.DataThrottlingRequest;
110 import android.telephony.IBootstrapAuthenticationCallback;
111 import android.telephony.ICellInfoCallback;
112 import android.telephony.IccOpenLogicalChannelResponse;
113 import android.telephony.LocationAccessPolicy;
114 import android.telephony.ModemActivityInfo;
115 import android.telephony.NeighboringCellInfo;
116 import android.telephony.NetworkScanRequest;
117 import android.telephony.PhoneCapability;
118 import android.telephony.PhoneNumberRange;
119 import android.telephony.RadioAccessFamily;
120 import android.telephony.RadioAccessSpecifier;
121 import android.telephony.ServiceState;
122 import android.telephony.SignalStrength;
123 import android.telephony.SignalStrengthUpdateRequest;
124 import android.telephony.SignalThresholdInfo;
125 import android.telephony.SubscriptionInfo;
126 import android.telephony.SubscriptionManager;
127 import android.telephony.TelephonyFrameworkInitializer;
128 import android.telephony.TelephonyHistogram;
129 import android.telephony.TelephonyManager;
130 import android.telephony.TelephonyManager.SimState;
131 import android.telephony.TelephonyScanManager;
132 import android.telephony.ThermalMitigationRequest;
133 import android.telephony.UiccCardInfo;
134 import android.telephony.UiccPortInfo;
135 import android.telephony.UiccSlotInfo;
136 import android.telephony.UiccSlotMapping;
137 import android.telephony.UssdResponse;
138 import android.telephony.VisualVoicemailSmsFilterSettings;
139 import android.telephony.data.NetworkSlicingConfig;
140 import android.telephony.emergency.EmergencyNumber;
141 import android.telephony.gba.GbaAuthRequest;
142 import android.telephony.gba.UaSecurityProtocolIdentifier;
143 import android.telephony.ims.ImsException;
144 import android.telephony.ims.ProvisioningManager;
145 import android.telephony.ims.RcsClientConfiguration;
146 import android.telephony.ims.RcsContactUceCapability;
147 import android.telephony.ims.RegistrationManager;
148 import android.telephony.ims.aidl.IFeatureProvisioningCallback;
149 import android.telephony.ims.aidl.IImsCapabilityCallback;
150 import android.telephony.ims.aidl.IImsConfig;
151 import android.telephony.ims.aidl.IImsConfigCallback;
152 import android.telephony.ims.aidl.IImsRegistration;
153 import android.telephony.ims.aidl.IImsRegistrationCallback;
154 import android.telephony.ims.aidl.IRcsConfigCallback;
155 import android.telephony.ims.feature.ImsFeature;
156 import android.telephony.ims.stub.ImsConfigImplBase;
157 import android.telephony.ims.stub.ImsRegistrationImplBase;
158 import android.telephony.satellite.INtnSignalStrengthCallback;
159 import android.telephony.satellite.ISatelliteCapabilitiesCallback;
160 import android.telephony.satellite.ISatelliteCommunicationAllowedStateCallback;
161 import android.telephony.satellite.ISatelliteDatagramCallback;
162 import android.telephony.satellite.ISatelliteModemStateCallback;
163 import android.telephony.satellite.ISatelliteProvisionStateCallback;
164 import android.telephony.satellite.ISatelliteSupportedStateCallback;
165 import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
166 import android.telephony.satellite.NtnSignalStrength;
167 import android.telephony.satellite.NtnSignalStrengthCallback;
168 import android.telephony.satellite.SatelliteCapabilities;
169 import android.telephony.satellite.SatelliteDatagram;
170 import android.telephony.satellite.SatelliteDatagramCallback;
171 import android.telephony.satellite.SatelliteManager;
172 import android.telephony.satellite.SatelliteProvisionStateCallback;
173 import android.text.TextUtils;
174 import android.util.ArraySet;
175 import android.util.EventLog;
176 import android.util.Log;
177 import android.util.Pair;
178 
179 import com.android.ims.ImsManager;
180 import com.android.ims.internal.IImsServiceFeatureCallback;
181 import com.android.ims.rcs.uce.eab.EabUtil;
182 import com.android.internal.annotations.VisibleForTesting;
183 import com.android.internal.telephony.CallForwardInfo;
184 import com.android.internal.telephony.CallManager;
185 import com.android.internal.telephony.CallStateException;
186 import com.android.internal.telephony.CallTracker;
187 import com.android.internal.telephony.CarrierPrivilegesTracker;
188 import com.android.internal.telephony.CarrierResolver;
189 import com.android.internal.telephony.CellNetworkScanResult;
190 import com.android.internal.telephony.CommandException;
191 import com.android.internal.telephony.CommandsInterface;
192 import com.android.internal.telephony.GbaManager;
193 import com.android.internal.telephony.GsmCdmaPhone;
194 import com.android.internal.telephony.HalVersion;
195 import com.android.internal.telephony.IBooleanConsumer;
196 import com.android.internal.telephony.ICallForwardingInfoCallback;
197 import com.android.internal.telephony.IImsStateCallback;
198 import com.android.internal.telephony.IIntegerConsumer;
199 import com.android.internal.telephony.INumberVerificationCallback;
200 import com.android.internal.telephony.ITelephony;
201 import com.android.internal.telephony.IccCard;
202 import com.android.internal.telephony.IccCardConstants;
203 import com.android.internal.telephony.IccLogicalChannelRequest;
204 import com.android.internal.telephony.LocaleTracker;
205 import com.android.internal.telephony.NetworkScanRequestTracker;
206 import com.android.internal.telephony.OperatorInfo;
207 import com.android.internal.telephony.Phone;
208 import com.android.internal.telephony.PhoneConfigurationManager;
209 import com.android.internal.telephony.PhoneConstantConversions;
210 import com.android.internal.telephony.PhoneConstants;
211 import com.android.internal.telephony.PhoneFactory;
212 import com.android.internal.telephony.ProxyController;
213 import com.android.internal.telephony.RIL;
214 import com.android.internal.telephony.RILConstants;
215 import com.android.internal.telephony.RadioInterfaceCapabilityController;
216 import com.android.internal.telephony.ServiceStateTracker;
217 import com.android.internal.telephony.SmsApplication;
218 import com.android.internal.telephony.SmsController;
219 import com.android.internal.telephony.SmsPermissions;
220 import com.android.internal.telephony.TelephonyCountryDetector;
221 import com.android.internal.telephony.TelephonyIntents;
222 import com.android.internal.telephony.TelephonyPermissions;
223 import com.android.internal.telephony.data.DataUtils;
224 import com.android.internal.telephony.domainselection.DomainSelectionResolver;
225 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
226 import com.android.internal.telephony.euicc.EuiccConnector;
227 import com.android.internal.telephony.flags.FeatureFlags;
228 import com.android.internal.telephony.ims.ImsResolver;
229 import com.android.internal.telephony.imsphone.ImsPhone;
230 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
231 import com.android.internal.telephony.metrics.RcsStats;
232 import com.android.internal.telephony.metrics.TelephonyMetrics;
233 import com.android.internal.telephony.satellite.SatelliteController;
234 import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
235 import com.android.internal.telephony.subscription.SubscriptionManagerService;
236 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
237 import com.android.internal.telephony.uicc.IccIoResult;
238 import com.android.internal.telephony.uicc.IccUtils;
239 import com.android.internal.telephony.uicc.SIMRecords;
240 import com.android.internal.telephony.uicc.UiccCard;
241 import com.android.internal.telephony.uicc.UiccCardApplication;
242 import com.android.internal.telephony.uicc.UiccController;
243 import com.android.internal.telephony.uicc.UiccPort;
244 import com.android.internal.telephony.uicc.UiccProfile;
245 import com.android.internal.telephony.uicc.UiccSlot;
246 import com.android.internal.telephony.util.LocaleUtils;
247 import com.android.internal.telephony.util.TelephonyUtils;
248 import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
249 import com.android.internal.util.FunctionalUtils;
250 import com.android.internal.util.HexDump;
251 import com.android.phone.callcomposer.CallComposerPictureManager;
252 import com.android.phone.callcomposer.CallComposerPictureTransfer;
253 import com.android.phone.callcomposer.ImageData;
254 import com.android.phone.satellite.accesscontrol.SatelliteAccessController;
255 import com.android.phone.satellite.entitlement.SatelliteEntitlementController;
256 import com.android.phone.settings.PickSmsSubscriptionActivity;
257 import com.android.phone.slice.SlicePurchaseController;
258 import com.android.phone.utils.CarrierAllowListInfo;
259 import com.android.phone.vvm.PhoneAccountHandleConverter;
260 import com.android.phone.vvm.RemoteVvmTaskManager;
261 import com.android.phone.vvm.VisualVoicemailSettingsUtil;
262 import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
263 import com.android.server.feature.flags.Flags;
264 import com.android.services.telephony.TelecomAccountRegistry;
265 import com.android.services.telephony.TelephonyConnectionService;
266 import com.android.services.telephony.domainselection.TelephonyDomainSelectionService;
267 import com.android.telephony.Rlog;
268 
269 import java.io.ByteArrayOutputStream;
270 import java.io.FileDescriptor;
271 import java.io.IOException;
272 import java.io.InputStream;
273 import java.io.PrintWriter;
274 import java.util.ArrayList;
275 import java.util.Arrays;
276 import java.util.Collection;
277 import java.util.Collections;
278 import java.util.HashMap;
279 import java.util.HashSet;
280 import java.util.List;
281 import java.util.Locale;
282 import java.util.Map;
283 import java.util.NoSuchElementException;
284 import java.util.Objects;
285 import java.util.Set;
286 import java.util.UUID;
287 import java.util.concurrent.Executors;
288 import java.util.concurrent.atomic.AtomicBoolean;
289 import java.util.function.Consumer;
290 
291 /**
292  * Implementation of the ITelephony interface.
293  */
294 public class PhoneInterfaceManager extends ITelephony.Stub {
295     private static final String LOG_TAG = "PhoneInterfaceManager";
296     private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
297     private static final boolean DBG_LOC = false;
298     private static final boolean DBG_MERGE = false;
299 
300     // Message codes used with mMainThreadHandler
301     private static final int CMD_HANDLE_PIN_MMI = 1;
302     private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
303     private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
304     private static final int CMD_OPEN_CHANNEL = 9;
305     private static final int EVENT_OPEN_CHANNEL_DONE = 10;
306     private static final int CMD_CLOSE_CHANNEL = 11;
307     private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
308     private static final int CMD_NV_READ_ITEM = 13;
309     private static final int EVENT_NV_READ_ITEM_DONE = 14;
310     private static final int CMD_NV_WRITE_ITEM = 15;
311     private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
312     private static final int CMD_NV_WRITE_CDMA_PRL = 17;
313     private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
314     private static final int CMD_RESET_MODEM_CONFIG = 19;
315     private static final int EVENT_RESET_MODEM_CONFIG_DONE = 20;
316     private static final int CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK = 21;
317     private static final int EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE = 22;
318     private static final int CMD_SEND_ENVELOPE = 25;
319     private static final int EVENT_SEND_ENVELOPE_DONE = 26;
320     private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
321     private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
322     private static final int CMD_EXCHANGE_SIM_IO = 31;
323     private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
324     private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
325     private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
326     private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
327     private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
328     private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
329     private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
330     private static final int CMD_PERFORM_NETWORK_SCAN = 39;
331     private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
332     private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
333     private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
334     private static final int CMD_SET_ALLOWED_CARRIERS = 43;
335     private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
336     private static final int CMD_GET_ALLOWED_CARRIERS = 45;
337     private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
338     private static final int CMD_HANDLE_USSD_REQUEST = 47;
339     private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
340     private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
341     private static final int CMD_SWITCH_SLOTS = 50;
342     private static final int EVENT_SWITCH_SLOTS_DONE = 51;
343     private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
344     private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
345     private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
346     private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
347     private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
348     private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
349     private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
350     private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
351     private static final int CMD_GET_ALL_CELL_INFO = 60;
352     private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
353     private static final int CMD_GET_CELL_LOCATION = 62;
354     private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
355     private static final int CMD_MODEM_REBOOT = 64;
356     private static final int EVENT_CMD_MODEM_REBOOT_DONE = 65;
357     private static final int CMD_REQUEST_CELL_INFO_UPDATE = 66;
358     private static final int EVENT_REQUEST_CELL_INFO_UPDATE_DONE = 67;
359     private static final int CMD_REQUEST_ENABLE_MODEM = 68;
360     private static final int EVENT_ENABLE_MODEM_DONE = 69;
361     private static final int CMD_GET_MODEM_STATUS = 70;
362     private static final int EVENT_GET_MODEM_STATUS_DONE = 71;
363     private static final int CMD_SET_FORBIDDEN_PLMNS = 72;
364     private static final int EVENT_SET_FORBIDDEN_PLMNS_DONE = 73;
365     private static final int CMD_ERASE_MODEM_CONFIG = 74;
366     private static final int EVENT_ERASE_MODEM_CONFIG_DONE = 75;
367     private static final int CMD_CHANGE_ICC_LOCK_PASSWORD = 76;
368     private static final int EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE = 77;
369     private static final int CMD_SET_ICC_LOCK_ENABLED = 78;
370     private static final int EVENT_SET_ICC_LOCK_ENABLED_DONE = 79;
371     private static final int CMD_SET_SYSTEM_SELECTION_CHANNELS = 80;
372     private static final int EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE = 81;
373     private static final int MSG_NOTIFY_USER_ACTIVITY = 82;
374     private static final int CMD_GET_CALL_FORWARDING = 83;
375     private static final int EVENT_GET_CALL_FORWARDING_DONE = 84;
376     private static final int CMD_SET_CALL_FORWARDING = 85;
377     private static final int EVENT_SET_CALL_FORWARDING_DONE = 86;
378     private static final int CMD_GET_CALL_WAITING = 87;
379     private static final int EVENT_GET_CALL_WAITING_DONE = 88;
380     private static final int CMD_SET_CALL_WAITING = 89;
381     private static final int EVENT_SET_CALL_WAITING_DONE = 90;
382     private static final int CMD_ENABLE_NR_DUAL_CONNECTIVITY = 91;
383     private static final int EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE = 92;
384     private static final int CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED = 93;
385     private static final int EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE = 94;
386     private static final int CMD_GET_CDMA_SUBSCRIPTION_MODE = 95;
387     private static final int EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE = 96;
388     private static final int CMD_GET_SYSTEM_SELECTION_CHANNELS = 97;
389     private static final int EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE = 98;
390     private static final int CMD_SET_DATA_THROTTLING = 99;
391     private static final int EVENT_SET_DATA_THROTTLING_DONE = 100;
392     private static final int CMD_SET_SIM_POWER = 101;
393     private static final int EVENT_SET_SIM_POWER_DONE = 102;
394     private static final int CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST = 103;
395     private static final int EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE = 104;
396     private static final int CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST = 105;
397     private static final int EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE = 106;
398     private static final int CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON = 107;
399     private static final int EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE = 108;
400     private static final int CMD_PREPARE_UNATTENDED_REBOOT = 109;
401     private static final int CMD_GET_SLICING_CONFIG = 110;
402     private static final int EVENT_GET_SLICING_CONFIG_DONE = 111;
403     private static final int CMD_ERASE_DATA_SHARED_PREFERENCES = 112;
404     private static final int CMD_ENABLE_VONR = 113;
405     private static final int EVENT_ENABLE_VONR_DONE = 114;
406     private static final int CMD_IS_VONR_ENABLED = 115;
407     private static final int EVENT_IS_VONR_ENABLED_DONE = 116;
408     private static final int CMD_PURCHASE_PREMIUM_CAPABILITY = 117;
409     private static final int EVENT_PURCHASE_PREMIUM_CAPABILITY_DONE = 118;
410 
411     // Parameters of select command.
412     private static final int SELECT_COMMAND = 0xA4;
413     private static final int SELECT_P1 = 0x04;
414     private static final int SELECT_P2 = 0;
415     private static final int SELECT_P3 = 0x10;
416 
417     // Toggling null cipher and integrity support was added in IRadioNetwork 2.1
418     private static final int MIN_NULL_CIPHER_AND_INTEGRITY_VERSION = 201;
419     // Cellular identifier disclosure transparency was added in IRadioNetwork 2.2
420     private static final int MIN_IDENTIFIER_DISCLOSURE_VERSION = 202;
421     // Null cipher notification support was added in IRadioNetwork 2.2
422     private static final int MIN_NULL_CIPHER_NOTIFICATION_VERSION = 202;
423 
424     /** The singleton instance. */
425     private static PhoneInterfaceManager sInstance;
426     private static List<String> sThermalMitigationAllowlistedPackages = new ArrayList<>();
427 
428     private final PhoneGlobals mApp;
429     private FeatureFlags mFeatureFlags;
430     private com.android.server.telecom.flags.FeatureFlags mTelecomFeatureFlags;
431     private final CallManager mCM;
432     private final ImsResolver mImsResolver;
433 
434     private final SatelliteController mSatelliteController;
435     private final SatelliteAccessController mSatelliteAccessController;
436     private final UserManager mUserManager;
437     private final MainThreadHandler mMainThreadHandler;
438     private final SharedPreferences mTelephonySharedPreferences;
439     private final PhoneConfigurationManager mPhoneConfigurationManager;
440     private final RadioInterfaceCapabilityController mRadioInterfaceCapabilities;
441     private AppOpsManager mAppOps;
442     private PackageManager mPackageManager;
443     private final int mVendorApiLevel;
444 
445     /** User Activity */
446     private final AtomicBoolean mNotifyUserActivity;
447     private static final int USER_ACTIVITY_NOTIFICATION_DELAY = 200;
448     private final Set<Integer> mCarrierPrivilegeTestOverrideSubIds = new ArraySet<>();
449 
450     private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
451     private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
452     private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
453     private static final String PREF_PROVISION_IMS_MMTEL_PREFIX = "provision_ims_mmtel_";
454 
455     // String to store multi SIM allowed
456     private static final String PREF_MULTI_SIM_RESTRICTED = "multisim_restricted";
457 
458     // The AID of ISD-R.
459     private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
460 
461     private NetworkScanRequestTracker mNetworkScanRequestTracker;
462 
463     private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
464     private static final int MANUFACTURER_CODE_LENGTH = 8;
465 
466     private static final int SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS = -1;
467     private static final int MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE = -2;
468 
469     private static final String PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID =
470             "24bf97a6-e8a6-44d8-a6a4-255d7548733c";
471 
472     /**
473      * Experiment flag to enable erase modem config on reset network, default value is false
474      */
475     public static final String RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED =
476             "reset_network_erase_modem_config_enabled";
477 
478     private static final int SET_NETWORK_SELECTION_MODE_AUTOMATIC_TIMEOUT_MS = 2000; // 2 seconds
479 
480     private static final int MODEM_ACTIVITY_TIME_OFFSET_CORRECTION_MS = 50;
481 
482     /**
483      * With support for MEP(multiple enabled profile) in Android T, a SIM card can have more than
484      * one ICCID active at the same time.
485      * Apps should use below API signatures if targeting SDK is T and beyond.
486      *
487      * @hide
488      */
489     @ChangeId
490     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
491     public static final long GET_API_SIGNATURES_FROM_UICC_PORT_INFO = 202110963L;
492 
493     /**
494      * Apps targeting on Android T and beyond will get exception whenever icc close channel
495      * operation fails.
496      */
497     @ChangeId
498     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
499     public static final long ICC_CLOSE_CHANNEL_EXCEPTION_ON_FAILURE = 208739934L;
500 
501     /**
502      * A request object to use for transmitting data to an ICC.
503      */
504     private static final class IccAPDUArgument {
505         public int channel, cla, command, p1, p2, p3;
506         public String data;
507 
IccAPDUArgument(int channel, int cla, int command, int p1, int p2, int p3, String data)508         public IccAPDUArgument(int channel, int cla, int command,
509                 int p1, int p2, int p3, String data) {
510             this.channel = channel;
511             this.cla = cla;
512             this.command = command;
513             this.p1 = p1;
514             this.p2 = p2;
515             this.p3 = p3;
516             this.data = data;
517         }
518     }
519 
520     /**
521      * A request object to use for transmitting data to an ICC.
522      */
523     private static final class ManualNetworkSelectionArgument {
524         public OperatorInfo operatorInfo;
525         public boolean persistSelection;
526 
ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection)527         public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
528             this.operatorInfo = operatorInfo;
529             this.persistSelection = persistSelection;
530         }
531     }
532 
533     private static final class PurchasePremiumCapabilityArgument {
534         public @TelephonyManager.PremiumCapability int capability;
535         public @NonNull IIntegerConsumer callback;
536 
PurchasePremiumCapabilityArgument(@elephonyManager.PremiumCapability int capability, @NonNull IIntegerConsumer callback)537         PurchasePremiumCapabilityArgument(@TelephonyManager.PremiumCapability int capability,
538                 @NonNull IIntegerConsumer callback) {
539             this.capability = capability;
540             this.callback = callback;
541         }
542     }
543 
544     /**
545      * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
546      * request after sending. The main thread will notify the request when it is complete.
547      */
548     private static final class MainThreadRequest {
549         /** The argument to use for the request */
550         public Object argument;
551         /** The result of the request that is run on the main thread */
552         public Object result;
553         // The subscriber id that this request applies to. Defaults to
554         // SubscriptionManager.INVALID_SUBSCRIPTION_ID
555         public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
556 
557         // In cases where subId is unavailable, the caller needs to specify the phone.
558         public Phone phone;
559 
560         public WorkSource workSource;
561 
MainThreadRequest(Object argument)562         public MainThreadRequest(Object argument) {
563             this.argument = argument;
564         }
565 
MainThreadRequest(Object argument, Phone phone, WorkSource workSource)566         MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
567             this.argument = argument;
568             if (phone != null) {
569                 this.phone = phone;
570             }
571             this.workSource = workSource;
572         }
573 
MainThreadRequest(Object argument, Integer subId, WorkSource workSource)574         MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
575             this.argument = argument;
576             if (subId != null) {
577                 this.subId = subId;
578             }
579             this.workSource = workSource;
580         }
581     }
582 
583     private static final class IncomingThirdPartyCallArgs {
584         public final ComponentName component;
585         public final String callId;
586         public final String callerDisplayName;
587 
IncomingThirdPartyCallArgs(ComponentName component, String callId, String callerDisplayName)588         public IncomingThirdPartyCallArgs(ComponentName component, String callId,
589                 String callerDisplayName) {
590             this.component = component;
591             this.callId = callId;
592             this.callerDisplayName = callerDisplayName;
593         }
594     }
595 
596     /**
597      * A handler that processes messages on the main thread in the phone process. Since many
598      * of the Phone calls are not thread safe this is needed to shuttle the requests from the
599      * inbound binder threads to the main thread in the phone process.  The Binder thread
600      * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
601      * on, which will be notified when the operation completes and will contain the result of the
602      * request.
603      *
604      * <p>If a MainThreadRequest object is provided in the msg.obj field,
605      * note that request.result must be set to something non-null for the calling thread to
606      * unblock.
607      */
608     private final class MainThreadHandler extends Handler {
609         @Override
handleMessage(Message msg)610         public void handleMessage(Message msg) {
611             MainThreadRequest request;
612             Message onCompleted;
613             AsyncResult ar;
614             UiccPort uiccPort;
615             IccAPDUArgument iccArgument;
616             final Phone defaultPhone = getDefaultPhone();
617 
618             switch (msg.what) {
619                 case CMD_HANDLE_USSD_REQUEST: {
620                     request = (MainThreadRequest) msg.obj;
621                     final Phone phone = getPhoneFromRequest(request);
622                     Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
623                     String ussdRequest = ussdObject.first;
624                     ResultReceiver wrappedCallback = ussdObject.second;
625 
626                     if (!isUssdApiAllowed(request.subId)) {
627                         // Carrier does not support use of this API, return failure.
628                         Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
629                         UssdResponse response = new UssdResponse(ussdRequest, null);
630                         Bundle returnData = new Bundle();
631                         returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
632                         wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
633 
634                         request.result = true;
635                         notifyRequester(request);
636                         return;
637                     }
638 
639                     try {
640                         request.result = phone != null
641                                 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
642                     } catch (CallStateException cse) {
643                         request.result = false;
644                     }
645                     // Wake up the requesting thread
646                     notifyRequester(request);
647                     break;
648                 }
649 
650                 case CMD_HANDLE_PIN_MMI: {
651                     request = (MainThreadRequest) msg.obj;
652                     final Phone phone = getPhoneFromRequest(request);
653                     request.result = phone != null ?
654                             getPhoneFromRequest(request).handlePinMmi((String) request.argument)
655                             : false;
656                     // Wake up the requesting thread
657                     notifyRequester(request);
658                     break;
659                 }
660 
661                 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
662                     request = (MainThreadRequest) msg.obj;
663                     iccArgument = (IccAPDUArgument) request.argument;
664                     uiccPort = getUiccPortFromRequest(request);
665                     if (uiccPort == null) {
666                         loge("iccTransmitApduLogicalChannel: No UICC");
667                         request.result = new IccIoResult(0x6F, 0, (byte[]) null);
668                         notifyRequester(request);
669                     } else {
670                         onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
671                                 request);
672                         uiccPort.iccTransmitApduLogicalChannel(
673                                 iccArgument.channel, iccArgument.cla, iccArgument.command,
674                                 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
675                                 onCompleted);
676                     }
677                     break;
678 
679                 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
680                     ar = (AsyncResult) msg.obj;
681                     request = (MainThreadRequest) ar.userObj;
682                     if (ar.exception == null && ar.result != null) {
683                         request.result = ar.result;
684                     } else {
685                         request.result = new IccIoResult(0x6F, 0, (byte[]) null);
686                         if (ar.result == null) {
687                             loge("iccTransmitApduLogicalChannel: Empty response");
688                         } else if (ar.exception instanceof CommandException) {
689                             loge("iccTransmitApduLogicalChannel: CommandException: " +
690                                     ar.exception);
691                         } else {
692                             loge("iccTransmitApduLogicalChannel: Unknown exception");
693                         }
694                     }
695                     notifyRequester(request);
696                     break;
697 
698                 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
699                     request = (MainThreadRequest) msg.obj;
700                     iccArgument = (IccAPDUArgument) request.argument;
701                     uiccPort = getUiccPortFromRequest(request);
702                     if (uiccPort == null) {
703                         loge("iccTransmitApduBasicChannel: No UICC");
704                         request.result = new IccIoResult(0x6F, 0, (byte[]) null);
705                         notifyRequester(request);
706                     } else {
707                         onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
708                                 request);
709                         uiccPort.iccTransmitApduBasicChannel(
710                                 iccArgument.cla, iccArgument.command, iccArgument.p1,
711                                 iccArgument.p2,
712                                 iccArgument.p3, iccArgument.data, onCompleted);
713                     }
714                     break;
715 
716                 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
717                     ar = (AsyncResult) msg.obj;
718                     request = (MainThreadRequest) ar.userObj;
719                     if (ar.exception == null && ar.result != null) {
720                         request.result = ar.result;
721                     } else {
722                         request.result = new IccIoResult(0x6F, 0, (byte[]) null);
723                         if (ar.result == null) {
724                             loge("iccTransmitApduBasicChannel: Empty response");
725                         } else if (ar.exception instanceof CommandException) {
726                             loge("iccTransmitApduBasicChannel: CommandException: " +
727                                     ar.exception);
728                         } else {
729                             loge("iccTransmitApduBasicChannel: Unknown exception");
730                         }
731                     }
732                     notifyRequester(request);
733                     break;
734 
735                 case CMD_EXCHANGE_SIM_IO:
736                     request = (MainThreadRequest) msg.obj;
737                     iccArgument = (IccAPDUArgument) request.argument;
738                     uiccPort = getUiccPortFromRequest(request);
739                     if (uiccPort == null) {
740                         loge("iccExchangeSimIO: No UICC");
741                         request.result = new IccIoResult(0x6F, 0, (byte[]) null);
742                         notifyRequester(request);
743                     } else {
744                         onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
745                                 request);
746                         uiccPort.iccExchangeSimIO(iccArgument.cla, /* fileID */
747                                 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
748                                 iccArgument.data, onCompleted);
749                     }
750                     break;
751 
752                 case EVENT_EXCHANGE_SIM_IO_DONE:
753                     ar = (AsyncResult) msg.obj;
754                     request = (MainThreadRequest) ar.userObj;
755                     if (ar.exception == null && ar.result != null) {
756                         request.result = ar.result;
757                     } else {
758                         request.result = new IccIoResult(0x6f, 0, (byte[]) null);
759                     }
760                     notifyRequester(request);
761                     break;
762 
763                 case CMD_SEND_ENVELOPE:
764                     request = (MainThreadRequest) msg.obj;
765                     uiccPort = getUiccPortFromRequest(request);
766                     if (uiccPort == null) {
767                         loge("sendEnvelopeWithStatus: No UICC");
768                         request.result = new IccIoResult(0x6F, 0, (byte[]) null);
769                         notifyRequester(request);
770                     } else {
771                         onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
772                         uiccPort.sendEnvelopeWithStatus((String) request.argument, onCompleted);
773                     }
774                     break;
775 
776                 case EVENT_SEND_ENVELOPE_DONE:
777                     ar = (AsyncResult) msg.obj;
778                     request = (MainThreadRequest) ar.userObj;
779                     if (ar.exception == null && ar.result != null) {
780                         request.result = ar.result;
781                     } else {
782                         request.result = new IccIoResult(0x6F, 0, (byte[]) null);
783                         if (ar.result == null) {
784                             loge("sendEnvelopeWithStatus: Empty response");
785                         } else if (ar.exception instanceof CommandException) {
786                             loge("sendEnvelopeWithStatus: CommandException: " +
787                                     ar.exception);
788                         } else {
789                             loge("sendEnvelopeWithStatus: exception:" + ar.exception);
790                         }
791                     }
792                     notifyRequester(request);
793                     break;
794 
795                 case CMD_OPEN_CHANNEL:
796                     request = (MainThreadRequest) msg.obj;
797                     uiccPort = getUiccPortFromRequest(request);
798                     IccLogicalChannelRequest openChannelRequest =
799                             (IccLogicalChannelRequest) request.argument;
800                     if (uiccPort == null) {
801                         loge("iccOpenLogicalChannel: No UICC");
802                         request.result = new IccOpenLogicalChannelResponse(-1,
803                                 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
804                         notifyRequester(request);
805                     } else {
806                         onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
807                         uiccPort.iccOpenLogicalChannel(openChannelRequest.aid,
808                                 openChannelRequest.p2, onCompleted);
809                     }
810                     break;
811 
812                 case EVENT_OPEN_CHANNEL_DONE:
813                     ar = (AsyncResult) msg.obj;
814                     request = (MainThreadRequest) ar.userObj;
815                     IccOpenLogicalChannelResponse openChannelResp;
816                     if (ar.exception == null && ar.result != null) {
817                         int[] result = (int[]) ar.result;
818                         int channelId = result[0];
819                         byte[] selectResponse = null;
820                         if (result.length > 1) {
821                             selectResponse = new byte[result.length - 1];
822                             for (int i = 1; i < result.length; ++i) {
823                                 selectResponse[i - 1] = (byte) result[i];
824                             }
825                         }
826                         openChannelResp = new IccOpenLogicalChannelResponse(channelId,
827                                 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
828 
829                         uiccPort = getUiccPortFromRequest(request);
830                         if (uiccPort == null) {
831                             loge("EVENT_OPEN_CHANNEL_DONE: UiccPort is null");
832                         } else {
833                             IccLogicalChannelRequest channelRequest =
834                                     (IccLogicalChannelRequest) request.argument;
835                             channelRequest.channel = channelId;
836                             uiccPort.onLogicalChannelOpened(channelRequest);
837                         }
838                     } else {
839                         if (ar.result == null) {
840                             loge("iccOpenLogicalChannel: Empty response");
841                         }
842                         if (ar.exception != null) {
843                             loge("iccOpenLogicalChannel: Exception: " + ar.exception);
844                         }
845 
846                         int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
847                         if (ar.exception instanceof CommandException) {
848                             CommandException.Error error =
849                                     ((CommandException) (ar.exception)).getCommandError();
850                             if (error == CommandException.Error.MISSING_RESOURCE) {
851                                 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
852                             } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
853                                 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
854                             }
855                         }
856                         openChannelResp = new IccOpenLogicalChannelResponse(
857                                 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
858                     }
859                     request.result = openChannelResp;
860                     notifyRequester(request);
861                     break;
862 
863                 case CMD_CLOSE_CHANNEL:
864                     request = (MainThreadRequest) msg.obj;
865                     uiccPort = getUiccPortFromRequest(request);
866                     if (uiccPort == null) {
867                         loge("iccCloseLogicalChannel: No UICC");
868                         request.result = new IllegalArgumentException(
869                                 "iccCloseLogicalChannel: No UICC");
870                         notifyRequester(request);
871                     } else {
872                         onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
873                         uiccPort.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
874                     }
875                     break;
876 
877                 case EVENT_CLOSE_CHANNEL_DONE:
878                     ar = (AsyncResult) msg.obj;
879                     request = (MainThreadRequest) ar.userObj;
880                     if (ar.exception == null) {
881                         request.result = true;
882                         uiccPort = getUiccPortFromRequest(request);
883                         if (uiccPort == null) {
884                             loge("EVENT_CLOSE_CHANNEL_DONE: UiccPort is null");
885                         } else {
886                             final int channelId = (Integer) request.argument;
887                             uiccPort.onLogicalChannelClosed(channelId);
888                         }
889                     } else {
890                         request.result = false;
891                         Exception exception = null;
892                         if (ar.exception instanceof CommandException) {
893                             loge("iccCloseLogicalChannel: CommandException: " + ar.exception);
894                             CommandException.Error error =
895                                     ((CommandException) (ar.exception)).getCommandError();
896                             if (error == CommandException.Error.INVALID_ARGUMENTS) {
897                                 // should only throw exceptions from the binder threads.
898                                 exception = new IllegalArgumentException(
899                                         "iccCloseLogicalChannel: invalid argument ");
900                             }
901                         } else {
902                             loge("iccCloseLogicalChannel: Unknown exception");
903                         }
904                         request.result = (exception != null) ? exception :
905                                 new IllegalStateException(
906                                         "exception from modem to close iccLogical Channel");
907                     }
908                     notifyRequester(request);
909                     break;
910 
911                 case CMD_NV_READ_ITEM:
912                     request = (MainThreadRequest) msg.obj;
913                     onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
914                     defaultPhone.nvReadItem((Integer) request.argument, onCompleted,
915                             request.workSource);
916                     break;
917 
918                 case EVENT_NV_READ_ITEM_DONE:
919                     ar = (AsyncResult) msg.obj;
920                     request = (MainThreadRequest) ar.userObj;
921                     if (ar.exception == null && ar.result != null) {
922                         request.result = ar.result;     // String
923                     } else {
924                         request.result = "";
925                         if (ar.result == null) {
926                             loge("nvReadItem: Empty response");
927                         } else if (ar.exception instanceof CommandException) {
928                             loge("nvReadItem: CommandException: " +
929                                     ar.exception);
930                         } else {
931                             loge("nvReadItem: Unknown exception");
932                         }
933                     }
934                     notifyRequester(request);
935                     break;
936 
937                 case CMD_NV_WRITE_ITEM:
938                     request = (MainThreadRequest) msg.obj;
939                     onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
940                     Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
941                     defaultPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
942                             request.workSource);
943                     break;
944 
945                 case EVENT_NV_WRITE_ITEM_DONE:
946                     handleNullReturnEvent(msg, "nvWriteItem");
947                     break;
948 
949                 case CMD_NV_WRITE_CDMA_PRL:
950                     request = (MainThreadRequest) msg.obj;
951                     onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
952                     defaultPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
953                     break;
954 
955                 case EVENT_NV_WRITE_CDMA_PRL_DONE:
956                     handleNullReturnEvent(msg, "nvWriteCdmaPrl");
957                     break;
958 
959                 case CMD_RESET_MODEM_CONFIG:
960                     request = (MainThreadRequest) msg.obj;
961                     onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
962                     defaultPhone.resetModemConfig(onCompleted);
963                     break;
964 
965                 case EVENT_RESET_MODEM_CONFIG_DONE:
966                     handleNullReturnEvent(msg, "resetModemConfig");
967                     break;
968 
969                 case CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED: {
970                     request = (MainThreadRequest) msg.obj;
971                     onCompleted = obtainMessage(EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE,
972                             request);
973                     Phone phone = getPhoneFromRequest(request);
974                     if (phone != null) {
975                         phone.isNrDualConnectivityEnabled(onCompleted, request.workSource);
976                     } else {
977                         loge("isNRDualConnectivityEnabled: No phone object");
978                         request.result = false;
979                         notifyRequester(request);
980                     }
981                     break;
982                 }
983 
984                 case EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE:
985                     ar = (AsyncResult) msg.obj;
986                     request = (MainThreadRequest) ar.userObj;
987                     if (ar.exception == null && ar.result != null) {
988                         request.result = ar.result;
989                     } else {
990                         // request.result must be set to something non-null
991                         // for the calling thread to unblock
992                         if (ar.result != null) {
993                             request.result = ar.result;
994                         } else {
995                             request.result = false;
996                         }
997                         if (ar.result == null) {
998                             loge("isNRDualConnectivityEnabled: Empty response");
999                         } else if (ar.exception instanceof CommandException) {
1000                             loge("isNRDualConnectivityEnabled: CommandException: "
1001                                     + ar.exception);
1002                         } else {
1003                             loge("isNRDualConnectivityEnabled: Unknown exception");
1004                         }
1005                     }
1006                     notifyRequester(request);
1007                     break;
1008 
1009                 case CMD_IS_VONR_ENABLED: {
1010                     request = (MainThreadRequest) msg.obj;
1011                     onCompleted = obtainMessage(EVENT_IS_VONR_ENABLED_DONE,
1012                             request);
1013                     Phone phone = getPhoneFromRequest(request);
1014                     if (phone != null) {
1015                         phone.isVoNrEnabled(onCompleted, request.workSource);
1016                     } else {
1017                         loge("isVoNrEnabled: No phone object");
1018                         request.result = false;
1019                         notifyRequester(request);
1020                     }
1021                     break;
1022                 }
1023 
1024                 case EVENT_IS_VONR_ENABLED_DONE:
1025                     ar = (AsyncResult) msg.obj;
1026                     request = (MainThreadRequest) ar.userObj;
1027                     if (ar.exception == null && ar.result != null) {
1028                         request.result = ar.result;
1029                     } else {
1030                         // request.result must be set to something non-null
1031                         // for the calling thread to unblock
1032                         if (ar.result != null) {
1033                             request.result = ar.result;
1034                         } else {
1035                             request.result = false;
1036                         }
1037                         if (ar.result == null) {
1038                             loge("isVoNrEnabled: Empty response");
1039                         } else if (ar.exception instanceof CommandException) {
1040                             loge("isVoNrEnabled: CommandException: "
1041                                     + ar.exception);
1042                         } else {
1043                             loge("isVoNrEnabled: Unknown exception");
1044                         }
1045                     }
1046                     notifyRequester(request);
1047                     break;
1048 
1049                 case CMD_ENABLE_NR_DUAL_CONNECTIVITY: {
1050                     request = (MainThreadRequest) msg.obj;
1051                     onCompleted = obtainMessage(EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE, request);
1052                     Phone phone = getPhoneFromRequest(request);
1053                     if (phone != null) {
1054                         phone.setNrDualConnectivityState((int) request.argument, onCompleted,
1055                                 request.workSource);
1056                     } else {
1057                         loge("enableNrDualConnectivity: No phone object");
1058                         request.result =
1059                                 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
1060                         notifyRequester(request);
1061                     }
1062                     break;
1063                 }
1064 
1065                 case EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE: {
1066                     ar = (AsyncResult) msg.obj;
1067                     request = (MainThreadRequest) ar.userObj;
1068                     if (ar.exception == null) {
1069                         request.result =
1070                                 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS;
1071                     } else {
1072                         request.result =
1073                                 TelephonyManager
1074                                         .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR;
1075                         if (ar.exception instanceof CommandException) {
1076                             CommandException.Error error =
1077                                     ((CommandException) (ar.exception)).getCommandError();
1078                             if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1079                                 request.result =
1080                                         TelephonyManager
1081                                                 .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
1082                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1083                                 request.result =
1084                                         TelephonyManager
1085                                                 .ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED;
1086                             }
1087                             loge("enableNrDualConnectivity" + ": CommandException: "
1088                                     + ar.exception);
1089                         } else {
1090                             loge("enableNrDualConnectivity" + ": Unknown exception");
1091                         }
1092                     }
1093                     notifyRequester(request);
1094                     break;
1095                 }
1096 
1097                 case CMD_ENABLE_VONR: {
1098                     request = (MainThreadRequest) msg.obj;
1099                     onCompleted = obtainMessage(EVENT_ENABLE_VONR_DONE, request);
1100                     Phone phone = getPhoneFromRequest(request);
1101                     if (phone != null) {
1102                         phone.setVoNrEnabled((boolean) request.argument, onCompleted,
1103                                 request.workSource);
1104                     } else {
1105                         loge("setVoNrEnabled: No phone object");
1106                         request.result =
1107                                 TelephonyManager.ENABLE_VONR_RADIO_NOT_AVAILABLE;
1108                         notifyRequester(request);
1109                     }
1110                     break;
1111                 }
1112 
1113                 case EVENT_ENABLE_VONR_DONE: {
1114                     ar = (AsyncResult) msg.obj;
1115                     request = (MainThreadRequest) ar.userObj;
1116                     if (ar.exception == null) {
1117                         request.result = TelephonyManager.ENABLE_VONR_SUCCESS;
1118                     } else {
1119                         request.result = TelephonyManager.ENABLE_VONR_RADIO_ERROR;
1120                         if (ar.exception instanceof CommandException) {
1121                             CommandException.Error error =
1122                                     ((CommandException) (ar.exception)).getCommandError();
1123                             if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1124                                 request.result = TelephonyManager.ENABLE_VONR_RADIO_NOT_AVAILABLE;
1125                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1126                                 request.result = TelephonyManager.ENABLE_VONR_REQUEST_NOT_SUPPORTED;
1127                             } else {
1128                                 request.result = TelephonyManager.ENABLE_VONR_RADIO_ERROR;
1129                             }
1130                             loge("setVoNrEnabled" + ": CommandException: "
1131                                     + ar.exception);
1132                         } else {
1133                             loge("setVoNrEnabled" + ": Unknown exception");
1134                         }
1135                     }
1136                     notifyRequester(request);
1137                     break;
1138                 }
1139 
1140                 case CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK:
1141                     request = (MainThreadRequest) msg.obj;
1142                     onCompleted = obtainMessage(EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE,
1143                             request);
1144                     getPhoneFromRequest(request).getAllowedNetworkTypesBitmask(onCompleted);
1145                     break;
1146 
1147                 case EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE:
1148                     ar = (AsyncResult) msg.obj;
1149                     request = (MainThreadRequest) ar.userObj;
1150                     if (ar.exception == null && ar.result != null) {
1151                         request.result = ar.result;     // Integer
1152                     } else {
1153                         // request.result must be set to something non-null
1154                         // for the calling thread to unblock
1155                         request.result = new int[]{-1};
1156                         if (ar.result == null) {
1157                             loge("getAllowedNetworkTypesBitmask: Empty response");
1158                         } else if (ar.exception instanceof CommandException) {
1159                             loge("getAllowedNetworkTypesBitmask: CommandException: "
1160                                     + ar.exception);
1161                         } else {
1162                             loge("getAllowedNetworkTypesBitmask: Unknown exception");
1163                         }
1164                     }
1165                     notifyRequester(request);
1166                     break;
1167 
1168                 case CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON:
1169                     request = (MainThreadRequest) msg.obj;
1170                     onCompleted = obtainMessage(EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE,
1171                             request);
1172                     Pair<Integer, Long> reasonWithNetworkTypes =
1173                             (Pair<Integer, Long>) request.argument;
1174                     getPhoneFromRequest(request).setAllowedNetworkTypes(
1175                             reasonWithNetworkTypes.first,
1176                             reasonWithNetworkTypes.second,
1177                             onCompleted);
1178                     break;
1179 
1180                 case EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE:
1181                     handleNullReturnEvent(msg, "setAllowedNetworkTypesForReason");
1182                     break;
1183 
1184                 case CMD_SET_VOICEMAIL_NUMBER:
1185                     request = (MainThreadRequest) msg.obj;
1186                     onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
1187                     Pair<String, String> tagNum = (Pair<String, String>) request.argument;
1188                     getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
1189                             onCompleted);
1190                     break;
1191 
1192                 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
1193                     handleNullReturnEvent(msg, "setVoicemailNumber");
1194                     break;
1195 
1196                 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
1197                     request = (MainThreadRequest) msg.obj;
1198                     onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
1199                             request);
1200                     getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
1201                     break;
1202 
1203                 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
1204                     handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
1205                     break;
1206 
1207                 case CMD_PERFORM_NETWORK_SCAN:
1208                     request = (MainThreadRequest) msg.obj;
1209                     onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
1210                     getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
1211                     break;
1212 
1213                 case CMD_GET_CALL_FORWARDING: {
1214                     request = (MainThreadRequest) msg.obj;
1215                     onCompleted = obtainMessage(EVENT_GET_CALL_FORWARDING_DONE, request);
1216                     Pair<Integer, TelephonyManager.CallForwardingInfoCallback> args =
1217                             (Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
1218                                     request.argument;
1219                     int callForwardingReason = args.first;
1220                     request.phone.getCallForwardingOption(callForwardingReason, onCompleted);
1221                     break;
1222                 }
1223                 case EVENT_GET_CALL_FORWARDING_DONE: {
1224                     ar = (AsyncResult) msg.obj;
1225                     request = (MainThreadRequest) ar.userObj;
1226                     TelephonyManager.CallForwardingInfoCallback callback =
1227                             ((Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
1228                                     request.argument).second;
1229                     if (ar.exception == null && ar.result != null) {
1230                         CallForwardingInfo callForwardingInfo = null;
1231                         CallForwardInfo[] callForwardInfos = (CallForwardInfo[]) ar.result;
1232                         for (CallForwardInfo callForwardInfo : callForwardInfos) {
1233                             // Service Class is a bit mask per 3gpp 27.007. Search for
1234                             // any service for voice call.
1235                             if ((callForwardInfo.serviceClass
1236                                     & CommandsInterface.SERVICE_CLASS_VOICE) > 0) {
1237                                 callForwardingInfo = new CallForwardingInfo(
1238                                         callForwardInfo.status
1239                                                 == CommandsInterface.CF_ACTION_ENABLE,
1240                                         callForwardInfo.reason,
1241                                         callForwardInfo.number,
1242                                         callForwardInfo.timeSeconds);
1243                                 break;
1244                             }
1245                         }
1246                         // Didn't find a call forward info for voice call.
1247                         if (callForwardingInfo == null) {
1248                             callForwardingInfo = new CallForwardingInfo(false /* enabled */,
1249                                     0 /* reason */, null /* number */, 0 /* timeout */);
1250                         }
1251                         callback.onCallForwardingInfoAvailable(callForwardingInfo);
1252                     } else {
1253                         if (ar.result == null) {
1254                             loge("EVENT_GET_CALL_FORWARDING_DONE: Empty response");
1255                         }
1256                         if (ar.exception != null) {
1257                             loge("EVENT_GET_CALL_FORWARDING_DONE: Exception: " + ar.exception);
1258                         }
1259                         int errorCode = TelephonyManager
1260                                 .CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN;
1261                         if (ar.exception instanceof CommandException) {
1262                             CommandException.Error error =
1263                                     ((CommandException) (ar.exception)).getCommandError();
1264                             if (error == CommandException.Error.FDN_CHECK_FAILURE) {
1265                                 errorCode = TelephonyManager
1266                                         .CallForwardingInfoCallback.RESULT_ERROR_FDN_CHECK_FAILURE;
1267                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1268                                 errorCode = TelephonyManager
1269                                         .CallForwardingInfoCallback.RESULT_ERROR_NOT_SUPPORTED;
1270                             }
1271                         }
1272                         callback.onError(errorCode);
1273                     }
1274                     break;
1275                 }
1276 
1277                 case CMD_SET_CALL_FORWARDING: {
1278                     request = (MainThreadRequest) msg.obj;
1279                     onCompleted = obtainMessage(EVENT_SET_CALL_FORWARDING_DONE, request);
1280                     request = (MainThreadRequest) msg.obj;
1281                     CallForwardingInfo callForwardingInfoToSet =
1282                             ((Pair<CallForwardingInfo, Consumer<Integer>>)
1283                                     request.argument).first;
1284                     request.phone.setCallForwardingOption(
1285                             callForwardingInfoToSet.isEnabled()
1286                                     ? CommandsInterface.CF_ACTION_REGISTRATION
1287                                     : CommandsInterface.CF_ACTION_DISABLE,
1288                             callForwardingInfoToSet.getReason(),
1289                             callForwardingInfoToSet.getNumber(),
1290                             callForwardingInfoToSet.getTimeoutSeconds(), onCompleted);
1291                     break;
1292                 }
1293 
1294                 case EVENT_SET_CALL_FORWARDING_DONE: {
1295                     ar = (AsyncResult) msg.obj;
1296                     request = (MainThreadRequest) ar.userObj;
1297                     Consumer<Integer> callback =
1298                             ((Pair<CallForwardingInfo, Consumer<Integer>>)
1299                                     request.argument).second;
1300                     if (ar.exception != null) {
1301                         loge("setCallForwarding exception: " + ar.exception);
1302                         int errorCode = TelephonyManager.CallForwardingInfoCallback
1303                                 .RESULT_ERROR_UNKNOWN;
1304                         if (ar.exception instanceof CommandException) {
1305                             CommandException.Error error =
1306                                     ((CommandException) (ar.exception)).getCommandError();
1307                             if (error == CommandException.Error.FDN_CHECK_FAILURE) {
1308                                 errorCode = TelephonyManager.CallForwardingInfoCallback
1309                                         .RESULT_ERROR_FDN_CHECK_FAILURE;
1310                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1311                                 errorCode = TelephonyManager.CallForwardingInfoCallback
1312                                         .RESULT_ERROR_NOT_SUPPORTED;
1313                             }
1314                         }
1315                         callback.accept(errorCode);
1316                     } else {
1317                         callback.accept(TelephonyManager.CallForwardingInfoCallback.RESULT_SUCCESS);
1318                     }
1319                     break;
1320                 }
1321 
1322                 case CMD_GET_CALL_WAITING: {
1323                     request = (MainThreadRequest) msg.obj;
1324                     onCompleted = obtainMessage(EVENT_GET_CALL_WAITING_DONE, request);
1325                     getPhoneFromRequest(request).getCallWaiting(onCompleted);
1326                     break;
1327                 }
1328 
1329                 case EVENT_GET_CALL_WAITING_DONE: {
1330                     ar = (AsyncResult) msg.obj;
1331                     request = (MainThreadRequest) ar.userObj;
1332                     Consumer<Integer> callback = (Consumer<Integer>) request.argument;
1333                     int callWaitingStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
1334                     if (ar.exception == null && ar.result != null) {
1335                         int[] callForwardResults = (int[]) ar.result;
1336                         // Service Class is a bit mask per 3gpp 27.007.
1337                         // Search for any service for voice call.
1338                         if (callForwardResults.length > 1
1339                                 && ((callForwardResults[1]
1340                                 & CommandsInterface.SERVICE_CLASS_VOICE) > 0)) {
1341                             callWaitingStatus = callForwardResults[0] == 0
1342                                     ? TelephonyManager.CALL_WAITING_STATUS_DISABLED
1343                                     : TelephonyManager.CALL_WAITING_STATUS_ENABLED;
1344                         } else {
1345                             callWaitingStatus = TelephonyManager.CALL_WAITING_STATUS_DISABLED;
1346                         }
1347                     } else {
1348                         if (ar.result == null) {
1349                             loge("EVENT_GET_CALL_WAITING_DONE: Empty response");
1350                         }
1351                         if (ar.exception != null) {
1352                             loge("EVENT_GET_CALL_WAITING_DONE: Exception: " + ar.exception);
1353                         }
1354                         if (ar.exception instanceof CommandException) {
1355                             CommandException.Error error =
1356                                     ((CommandException) (ar.exception)).getCommandError();
1357                             if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1358                                 callWaitingStatus =
1359                                         TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED;
1360                             } else if (error == CommandException.Error.FDN_CHECK_FAILURE) {
1361                                 callWaitingStatus =
1362                                         TelephonyManager.CALL_WAITING_STATUS_FDN_CHECK_FAILURE;
1363                             }
1364                         }
1365                     }
1366                     callback.accept(callWaitingStatus);
1367                     break;
1368                 }
1369 
1370                 case CMD_SET_CALL_WAITING: {
1371                     request = (MainThreadRequest) msg.obj;
1372                     onCompleted = obtainMessage(EVENT_SET_CALL_WAITING_DONE, request);
1373                     boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1374                     getPhoneFromRequest(request).setCallWaiting(enable, onCompleted);
1375                     break;
1376                 }
1377 
1378                 case EVENT_SET_CALL_WAITING_DONE: {
1379                     ar = (AsyncResult) msg.obj;
1380                     request = (MainThreadRequest) ar.userObj;
1381                     boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1382                     Consumer<Integer> callback =
1383                             ((Pair<Boolean, Consumer<Integer>>) request.argument).second;
1384                     if (ar.exception != null) {
1385                         loge("setCallWaiting exception: " + ar.exception);
1386                         if (ar.exception instanceof CommandException) {
1387                             CommandException.Error error =
1388                                     ((CommandException) (ar.exception)).getCommandError();
1389                             if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1390                                 callback.accept(TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED);
1391                             } else if (error == CommandException.Error.FDN_CHECK_FAILURE) {
1392                                 callback.accept(
1393                                         TelephonyManager.CALL_WAITING_STATUS_FDN_CHECK_FAILURE);
1394                             } else {
1395                                 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1396                             }
1397                         } else {
1398                             callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1399                         }
1400                     } else {
1401                         callback.accept(enable ? TelephonyManager.CALL_WAITING_STATUS_ENABLED
1402                                 : TelephonyManager.CALL_WAITING_STATUS_DISABLED);
1403                     }
1404                     break;
1405                 }
1406                 case EVENT_PERFORM_NETWORK_SCAN_DONE:
1407                     ar = (AsyncResult) msg.obj;
1408                     request = (MainThreadRequest) ar.userObj;
1409                     CellNetworkScanResult cellScanResult;
1410                     if (ar.exception == null && ar.result != null) {
1411                         cellScanResult = new CellNetworkScanResult(
1412                                 CellNetworkScanResult.STATUS_SUCCESS,
1413                                 (List<OperatorInfo>) ar.result);
1414                     } else {
1415                         if (ar.result == null) {
1416                             loge("getCellNetworkScanResults: Empty response");
1417                         }
1418                         if (ar.exception != null) {
1419                             loge("getCellNetworkScanResults: Exception: " + ar.exception);
1420                         }
1421                         int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
1422                         if (ar.exception instanceof CommandException) {
1423                             CommandException.Error error =
1424                                     ((CommandException) (ar.exception)).getCommandError();
1425                             if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1426                                 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
1427                             } else if (error == CommandException.Error.GENERIC_FAILURE) {
1428                                 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
1429                             }
1430                         }
1431                         cellScanResult = new CellNetworkScanResult(errorCode, null);
1432                     }
1433                     request.result = cellScanResult;
1434                     notifyRequester(request);
1435                     break;
1436 
1437                 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
1438                     request = (MainThreadRequest) msg.obj;
1439                     ManualNetworkSelectionArgument selArg =
1440                             (ManualNetworkSelectionArgument) request.argument;
1441                     onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
1442                             request);
1443                     getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
1444                             selArg.persistSelection, onCompleted);
1445                     break;
1446 
1447                 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
1448                     ar = (AsyncResult) msg.obj;
1449                     request = (MainThreadRequest) ar.userObj;
1450                     if (ar.exception == null) {
1451                         request.result = true;
1452                     } else {
1453                         request.result = false;
1454                         loge("setNetworkSelectionModeManual " + ar.exception);
1455                     }
1456                     notifyRequester(request);
1457                     mApp.onNetworkSelectionChanged(request.subId);
1458                     break;
1459 
1460                 case CMD_GET_MODEM_ACTIVITY_INFO:
1461                     request = (MainThreadRequest) msg.obj;
1462                     onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
1463                     if (defaultPhone != null) {
1464                         defaultPhone.getModemActivityInfo(onCompleted, request.workSource);
1465                     } else {
1466                         ResultReceiver result = (ResultReceiver) request.argument;
1467                         Bundle bundle = new Bundle();
1468                         bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY,
1469                                 new ModemActivityInfo(0, 0, 0,
1470                                         new int[ModemActivityInfo.getNumTxPowerLevels()], 0));
1471                         result.send(0, bundle);
1472                     }
1473                     break;
1474 
1475                 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE: {
1476                     ar = (AsyncResult) msg.obj;
1477                     request = (MainThreadRequest) ar.userObj;
1478                     ResultReceiver result = (ResultReceiver) request.argument;
1479                     int error = 0;
1480                     ModemActivityInfo ret = null;
1481                     if (mLastModemActivityInfo == null) {
1482                         mLastModemActivitySpecificInfo = new ActivityStatsTechSpecificInfo[1];
1483                         mLastModemActivitySpecificInfo[0] =
1484                                 new ActivityStatsTechSpecificInfo(
1485                                         0,
1486                                         0,
1487                                         new int[ModemActivityInfo.getNumTxPowerLevels()],
1488                                         0);
1489                         mLastModemActivityInfo =
1490                                 new ModemActivityInfo(0, 0, 0, mLastModemActivitySpecificInfo);
1491                     }
1492 
1493                     if (ar.exception == null && ar.result != null) {
1494                         // Update the last modem activity info and the result of the request.
1495                         ModemActivityInfo info = (ModemActivityInfo) ar.result;
1496                         if (isModemActivityInfoValid(info)) {
1497                             mergeModemActivityInfo(info);
1498                         } else {
1499                             loge("queryModemActivityInfo: invalid response");
1500                         }
1501                         // This is needed to decouple ret from mLastModemActivityInfo
1502                         // We don't want to return mLastModemActivityInfo which is updated
1503                         // inside mergeModemActivityInfo()
1504                         ret = new ModemActivityInfo(
1505                                 mLastModemActivityInfo.getTimestampMillis(),
1506                                 mLastModemActivityInfo.getSleepTimeMillis(),
1507                                 mLastModemActivityInfo.getIdleTimeMillis(),
1508                                 deepCopyModemActivitySpecificInfo(mLastModemActivitySpecificInfo));
1509 
1510                     } else {
1511                         if (ar.result == null) {
1512                             loge("queryModemActivityInfo: Empty response");
1513                             error = TelephonyManager.ModemActivityInfoException
1514                                     .ERROR_INVALID_INFO_RECEIVED;
1515                         } else if (ar.exception instanceof CommandException) {
1516                             loge("queryModemActivityInfo: CommandException: " + ar.exception);
1517                             error = TelephonyManager.ModemActivityInfoException
1518                                     .ERROR_MODEM_RESPONSE_ERROR;
1519                         } else {
1520                             loge("queryModemActivityInfo: Unknown exception");
1521                             error = TelephonyManager.ModemActivityInfoException
1522                                     .ERROR_UNKNOWN;
1523                         }
1524                     }
1525                     Bundle bundle = new Bundle();
1526                     if (ret != null) {
1527                         bundle.putParcelable(
1528                                 TelephonyManager.MODEM_ACTIVITY_RESULT_KEY,
1529                                 ret);
1530                     } else {
1531                         bundle.putInt(TelephonyManager.EXCEPTION_RESULT_KEY, error);
1532                     }
1533                     result.send(0, bundle);
1534                     notifyRequester(request);
1535                     break;
1536                 }
1537 
1538                 case CMD_SET_ALLOWED_CARRIERS: {
1539                     request = (MainThreadRequest) msg.obj;
1540                     CarrierRestrictionRules argument =
1541                             (CarrierRestrictionRules) request.argument;
1542                     onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
1543                     defaultPhone.setAllowedCarriers(argument, onCompleted, request.workSource);
1544                     break;
1545                 }
1546 
1547                 case EVENT_SET_ALLOWED_CARRIERS_DONE:
1548                     ar = (AsyncResult) msg.obj;
1549                     request = (MainThreadRequest) ar.userObj;
1550                     if (ar.exception == null && ar.result != null) {
1551                         request.result = ar.result;
1552                     } else {
1553                         request.result = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
1554                         if (ar.exception instanceof CommandException) {
1555                             loge("setAllowedCarriers: CommandException: " + ar.exception);
1556                             CommandException.Error error =
1557                                     ((CommandException) (ar.exception)).getCommandError();
1558                             if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1559                                 request.result =
1560                                         TelephonyManager.SET_CARRIER_RESTRICTION_NOT_SUPPORTED;
1561                             }
1562                         } else {
1563                             loge("setAllowedCarriers: Unknown exception");
1564                         }
1565                     }
1566                     notifyRequester(request);
1567                     break;
1568 
1569                 case CMD_GET_ALLOWED_CARRIERS:
1570                     request = (MainThreadRequest) msg.obj;
1571                     onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
1572                     defaultPhone.getAllowedCarriers(onCompleted, request.workSource);
1573                     break;
1574 
1575                 case EVENT_GET_ALLOWED_CARRIERS_DONE:
1576                     ar = (AsyncResult) msg.obj;
1577                     request = (MainThreadRequest) ar.userObj;
1578                     if (ar.exception == null && ar.result != null) {
1579                         request.result = ar.result;
1580                     } else {
1581                         request.result = new IllegalStateException(
1582                                 "Failed to get carrier restrictions");
1583                         if (ar.result == null) {
1584                             loge("getAllowedCarriers: Empty response");
1585                         } else if (ar.exception instanceof CommandException) {
1586                             loge("getAllowedCarriers: CommandException: " +
1587                                     ar.exception);
1588                         } else {
1589                             loge("getAllowedCarriers: Unknown exception");
1590                         }
1591                     }
1592                     if (request.argument != null) {
1593                         // This is for the implementation of carrierRestrictionStatus.
1594                         CallerCallbackInfo callbackInfo = (CallerCallbackInfo) request.argument;
1595                         Consumer<Integer> callback = callbackInfo.getConsumer();
1596                         Set<Integer> callerCarrierIds = callbackInfo.getCarrierIds();
1597                         int lockStatus = TelephonyManager.CARRIER_RESTRICTION_STATUS_UNKNOWN;
1598                         if (ar.exception == null && ar.result instanceof CarrierRestrictionRules) {
1599                             CarrierRestrictionRules carrierRestrictionRules =
1600                                     (CarrierRestrictionRules) ar.result;
1601                             int carrierId = -1;
1602                             try {
1603                                 CarrierIdentifier carrierIdentifier =
1604                                         carrierRestrictionRules.getAllowedCarriers().get(0);
1605                                 carrierId = CarrierResolver.getCarrierIdFromIdentifier(mApp,
1606                                         carrierIdentifier);
1607                             } catch (NullPointerException | IndexOutOfBoundsException ex) {
1608                                 Rlog.e(LOG_TAG, "CarrierIdentifier exception = " + ex);
1609                             }
1610                             lockStatus = carrierRestrictionRules.getCarrierRestrictionStatus();
1611                             int restrictedStatus =
1612                                     TelephonyManager.CARRIER_RESTRICTION_STATUS_RESTRICTED;
1613                             if (carrierId != -1 && callerCarrierIds.contains(carrierId) &&
1614                                     lockStatus == restrictedStatus) {
1615                                 lockStatus = TelephonyManager
1616                                         .CARRIER_RESTRICTION_STATUS_RESTRICTED_TO_CALLER;
1617                             }
1618                         } else {
1619                             Rlog.e(LOG_TAG,
1620                                     "getCarrierRestrictionStatus: exception ex = " + ar.exception);
1621                         }
1622                         callback.accept(lockStatus);
1623                     } else {
1624                         // This is for the implementation of getAllowedCarriers.
1625                         notifyRequester(request);
1626                     }
1627                     break;
1628 
1629                 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
1630                     ar = (AsyncResult) msg.obj;
1631                     request = (MainThreadRequest) ar.userObj;
1632                     if (ar.exception == null && ar.result != null) {
1633                         request.result = ar.result;
1634                     } else {
1635                         request.result = new IllegalArgumentException(
1636                                 "Failed to retrieve Forbidden Plmns");
1637                         if (ar.result == null) {
1638                             loge("getForbiddenPlmns: Empty response");
1639                         } else {
1640                             loge("getForbiddenPlmns: Unknown exception");
1641                         }
1642                     }
1643                     notifyRequester(request);
1644                     break;
1645 
1646                 case CMD_GET_FORBIDDEN_PLMNS:
1647                     request = (MainThreadRequest) msg.obj;
1648                     uiccPort = getUiccPortFromRequest(request);
1649                     if (uiccPort == null) {
1650                         loge("getForbiddenPlmns() UiccPort is null");
1651                         request.result = new IllegalArgumentException(
1652                                 "getForbiddenPlmns() UiccPort is null");
1653                         notifyRequester(request);
1654                         break;
1655                     }
1656                     Integer appType = (Integer) request.argument;
1657                     UiccCardApplication uiccApp = uiccPort.getApplicationByType(appType);
1658                     if (uiccApp == null) {
1659                         loge("getForbiddenPlmns() no app with specified type -- "
1660                                 + appType);
1661                         request.result = new IllegalArgumentException("Failed to get UICC App");
1662                         notifyRequester(request);
1663                         break;
1664                     } else {
1665                         if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
1666                                 + " specified type -- " + appType);
1667                     }
1668                     onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
1669                     ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
1670                             onCompleted);
1671                     break;
1672 
1673                 case CMD_SWITCH_SLOTS:
1674                     request = (MainThreadRequest) msg.obj;
1675                     List<UiccSlotMapping> slotMapping = (List<UiccSlotMapping>) request.argument;
1676                     onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
1677                     UiccController.getInstance().switchSlots(slotMapping, onCompleted);
1678                     break;
1679 
1680                 case EVENT_SWITCH_SLOTS_DONE:
1681                     ar = (AsyncResult) msg.obj;
1682                     request = (MainThreadRequest) ar.userObj;
1683                     request.result = (ar.exception == null);
1684                     notifyRequester(request);
1685                     break;
1686                 case CMD_GET_NETWORK_SELECTION_MODE:
1687                     request = (MainThreadRequest) msg.obj;
1688                     onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
1689                     getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
1690                     break;
1691 
1692                 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
1693                     ar = (AsyncResult) msg.obj;
1694                     request = (MainThreadRequest) ar.userObj;
1695                     if (ar.exception != null) {
1696                         request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
1697                     } else {
1698                         int mode = ((int[]) ar.result)[0];
1699                         if (mode == 0) {
1700                             request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
1701                         } else {
1702                             request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
1703                         }
1704                     }
1705                     notifyRequester(request);
1706                     break;
1707                 case CMD_GET_CDMA_ROAMING_MODE:
1708                     request = (MainThreadRequest) msg.obj;
1709                     onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
1710                     getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
1711                     break;
1712                 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
1713                     ar = (AsyncResult) msg.obj;
1714                     request = (MainThreadRequest) ar.userObj;
1715                     if (ar.exception != null) {
1716                         request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
1717                     } else {
1718                         request.result = ((int[]) ar.result)[0];
1719                     }
1720                     notifyRequester(request);
1721                     break;
1722                 case CMD_SET_CDMA_ROAMING_MODE:
1723                     request = (MainThreadRequest) msg.obj;
1724                     onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
1725                     int mode = (int) request.argument;
1726                     getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
1727                     break;
1728                 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
1729                     ar = (AsyncResult) msg.obj;
1730                     request = (MainThreadRequest) ar.userObj;
1731                     request.result = ar.exception == null;
1732                     notifyRequester(request);
1733                     break;
1734                 case CMD_GET_CDMA_SUBSCRIPTION_MODE:
1735                     request = (MainThreadRequest) msg.obj;
1736                     onCompleted = obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1737                     getPhoneFromRequest(request).queryCdmaSubscriptionMode(onCompleted);
1738                     break;
1739                 case EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE:
1740                     ar = (AsyncResult) msg.obj;
1741                     request = (MainThreadRequest) ar.userObj;
1742                     if (ar.exception != null) {
1743                         request.result = TelephonyManager.CDMA_SUBSCRIPTION_RUIM_SIM;
1744                     } else {
1745                         request.result = ((int[]) ar.result)[0];
1746                     }
1747                     notifyRequester(request);
1748                     break;
1749                 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
1750                     request = (MainThreadRequest) msg.obj;
1751                     onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1752                     int subscriptionMode = (int) request.argument;
1753                     getPhoneFromRequest(request).setCdmaSubscriptionMode(
1754                             subscriptionMode, onCompleted);
1755                     break;
1756                 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
1757                     ar = (AsyncResult) msg.obj;
1758                     request = (MainThreadRequest) ar.userObj;
1759                     request.result = ar.exception == null;
1760                     notifyRequester(request);
1761                     break;
1762                 case CMD_GET_ALL_CELL_INFO:
1763                     request = (MainThreadRequest) msg.obj;
1764                     onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
1765                     request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
1766                     break;
1767                 case EVENT_GET_ALL_CELL_INFO_DONE:
1768                     ar = (AsyncResult) msg.obj;
1769                     request = (MainThreadRequest) ar.userObj;
1770                     // If a timeout occurs, the response will be null
1771                     request.result = (ar.exception == null && ar.result != null)
1772                             ? ar.result : new ArrayList<CellInfo>();
1773                     synchronized (request) {
1774                         request.notifyAll();
1775                     }
1776                     break;
1777                 case CMD_REQUEST_CELL_INFO_UPDATE:
1778                     request = (MainThreadRequest) msg.obj;
1779                     request.phone.requestCellInfoUpdate(request.workSource,
1780                             obtainMessage(EVENT_REQUEST_CELL_INFO_UPDATE_DONE, request));
1781                     break;
1782                 case EVENT_REQUEST_CELL_INFO_UPDATE_DONE:
1783                     ar = (AsyncResult) msg.obj;
1784                     request = (MainThreadRequest) ar.userObj;
1785                     ICellInfoCallback cb = (ICellInfoCallback) request.argument;
1786                     try {
1787                         if (ar.exception != null) {
1788                             Log.e(LOG_TAG, "Exception retrieving CellInfo=" + ar.exception);
1789                             cb.onError(
1790                                     TelephonyManager.CellInfoCallback.ERROR_MODEM_ERROR,
1791                                     ar.exception.getClass().getName(),
1792                                     ar.exception.toString());
1793                         } else if (ar.result == null) {
1794                             Log.w(LOG_TAG, "Timeout Waiting for CellInfo!");
1795                             cb.onError(TelephonyManager.CellInfoCallback.ERROR_TIMEOUT, null, null);
1796                         } else {
1797                             // use the result as returned
1798                             cb.onCellInfo((List<CellInfo>) ar.result);
1799                         }
1800                     } catch (RemoteException re) {
1801                         Log.w(LOG_TAG, "Discarded CellInfo due to Callback RemoteException");
1802                     }
1803                     break;
1804                 case CMD_GET_CELL_LOCATION: {
1805                     request = (MainThreadRequest) msg.obj;
1806                     WorkSource ws = (WorkSource) request.argument;
1807                     Phone phone = getPhoneFromRequest(request);
1808                     phone.getCellIdentity(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
1809                     break;
1810                 }
1811                 case EVENT_GET_CELL_LOCATION_DONE: {
1812                     ar = (AsyncResult) msg.obj;
1813                     request = (MainThreadRequest) ar.userObj;
1814                     if (ar.exception == null) {
1815                         request.result = ar.result;
1816                     } else {
1817                         Phone phone = getPhoneFromRequest(request);
1818                         request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
1819                                 ? new CellIdentityCdma() : new CellIdentityGsm();
1820                     }
1821 
1822                     synchronized (request) {
1823                         request.notifyAll();
1824                     }
1825                     break;
1826                 }
1827                 case CMD_MODEM_REBOOT:
1828                     request = (MainThreadRequest) msg.obj;
1829                     onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
1830                     defaultPhone.rebootModem(onCompleted);
1831                     break;
1832                 case EVENT_CMD_MODEM_REBOOT_DONE:
1833                     handleNullReturnEvent(msg, "rebootModem");
1834                     break;
1835                 case CMD_REQUEST_ENABLE_MODEM: {
1836                     request = (MainThreadRequest) msg.obj;
1837                     boolean enable = (boolean) request.argument;
1838                     onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
1839                     onCompleted.arg1 = enable ? 1 : 0;
1840                     PhoneConfigurationManager.getInstance()
1841                             .enablePhone(request.phone, enable, onCompleted);
1842                     break;
1843                 }
1844                 case EVENT_ENABLE_MODEM_DONE: {
1845                     ar = (AsyncResult) msg.obj;
1846                     request = (MainThreadRequest) ar.userObj;
1847                     request.result = (ar.exception == null);
1848                     int phoneId = request.phone.getPhoneId();
1849                     //update the cache as modem status has changed
1850                     if ((boolean) request.result) {
1851                         mPhoneConfigurationManager.addToPhoneStatusCache(phoneId, msg.arg1 == 1);
1852                         updateModemStateMetrics();
1853                     } else {
1854                         Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1855                                 + ar.exception);
1856                     }
1857                     notifyRequester(request);
1858                     break;
1859                 }
1860                 case CMD_GET_MODEM_STATUS:
1861                     request = (MainThreadRequest) msg.obj;
1862                     onCompleted = obtainMessage(EVENT_GET_MODEM_STATUS_DONE, request);
1863                     PhoneConfigurationManager.getInstance()
1864                             .getPhoneStatusFromModem(request.phone, onCompleted);
1865                     break;
1866                 case EVENT_GET_MODEM_STATUS_DONE:
1867                     ar = (AsyncResult) msg.obj;
1868                     request = (MainThreadRequest) ar.userObj;
1869                     int id = request.phone.getPhoneId();
1870                     if (ar.exception == null && ar.result != null) {
1871                         request.result = ar.result;
1872                         //update the cache as modem status has changed
1873                         mPhoneConfigurationManager.addToPhoneStatusCache(id,
1874                                 (boolean) request.result);
1875                     } else {
1876                         // Return true if modem status cannot be retrieved. For most cases,
1877                         // modem status is on. And for older version modems, GET_MODEM_STATUS
1878                         // and disable modem are not supported. Modem is always on.
1879                         // TODO: this should be fixed in R to support a third
1880                         // status UNKNOWN b/131631629
1881                         request.result = true;
1882                         Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1883                                 + ar.exception);
1884                     }
1885                     notifyRequester(request);
1886                     break;
1887                 case CMD_SET_SYSTEM_SELECTION_CHANNELS: {
1888                     request = (MainThreadRequest) msg.obj;
1889                     onCompleted = obtainMessage(EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1890                     Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1891                             (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1892                     request.phone.setSystemSelectionChannels(args.first, onCompleted);
1893                     break;
1894                 }
1895                 case EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE: {
1896                     ar = (AsyncResult) msg.obj;
1897                     request = (MainThreadRequest) ar.userObj;
1898                     Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1899                             (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1900                     args.second.accept(ar.exception == null);
1901                     notifyRequester(request);
1902                     break;
1903                 }
1904                 case CMD_GET_SYSTEM_SELECTION_CHANNELS: {
1905                     request = (MainThreadRequest) msg.obj;
1906                     onCompleted = obtainMessage(EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1907                     Phone phone = getPhoneFromRequest(request);
1908                     if (phone != null) {
1909                         phone.getSystemSelectionChannels(onCompleted);
1910                     } else {
1911                         loge("getSystemSelectionChannels: No phone object");
1912                         request.result = new ArrayList<RadioAccessSpecifier>();
1913                         notifyRequester(request);
1914                     }
1915                     break;
1916                 }
1917                 case EVENT_GET_SYSTEM_SELECTION_CHANNELS_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 = new IllegalStateException(
1924                                 "Failed to retrieve system selecton channels");
1925                         if (ar.result == null) {
1926                             loge("getSystemSelectionChannels: Empty response");
1927                         } else {
1928                             loge("getSystemSelectionChannels: Unknown exception");
1929                         }
1930                     }
1931                     notifyRequester(request);
1932                     break;
1933                 case EVENT_SET_FORBIDDEN_PLMNS_DONE:
1934                     ar = (AsyncResult) msg.obj;
1935                     request = (MainThreadRequest) ar.userObj;
1936                     if (ar.exception == null && ar.result != null) {
1937                         request.result = ar.result;
1938                     } else {
1939                         request.result = -1;
1940                         loge("Failed to set Forbidden Plmns");
1941                         if (ar.result == null) {
1942                             loge("setForbidenPlmns: Empty response");
1943                         } else if (ar.exception != null) {
1944                             loge("setForbiddenPlmns: Exception: " + ar.exception);
1945                             request.result = -1;
1946                         } else {
1947                             loge("setForbiddenPlmns: Unknown exception");
1948                         }
1949                     }
1950                     notifyRequester(request);
1951                     break;
1952                 case CMD_SET_FORBIDDEN_PLMNS:
1953                     request = (MainThreadRequest) msg.obj;
1954                     uiccPort = getUiccPortFromRequest(request);
1955                     if (uiccPort == null) {
1956                         loge("setForbiddenPlmns: UiccPort is null");
1957                         request.result = -1;
1958                         notifyRequester(request);
1959                         break;
1960                     }
1961                     Pair<Integer, List<String>> setFplmnsArgs =
1962                             (Pair<Integer, List<String>>) request.argument;
1963                     appType = setFplmnsArgs.first;
1964                     List<String> fplmns = setFplmnsArgs.second;
1965                     uiccApp = uiccPort.getApplicationByType(appType);
1966                     if (uiccApp == null) {
1967                         loge("setForbiddenPlmns: no app with specified type -- " + appType);
1968                         request.result = -1;
1969                         loge("Failed to get UICC App");
1970                         notifyRequester(request);
1971                     } else {
1972                         onCompleted = obtainMessage(EVENT_SET_FORBIDDEN_PLMNS_DONE, request);
1973                         ((SIMRecords) uiccApp.getIccRecords())
1974                                 .setForbiddenPlmns(onCompleted, fplmns);
1975                     }
1976                     break;
1977                 case CMD_ERASE_MODEM_CONFIG:
1978                     request = (MainThreadRequest) msg.obj;
1979                     onCompleted = obtainMessage(EVENT_ERASE_MODEM_CONFIG_DONE, request);
1980                     defaultPhone.eraseModemConfig(onCompleted);
1981                     break;
1982                 case EVENT_ERASE_MODEM_CONFIG_DONE:
1983                     handleNullReturnEvent(msg, "eraseModemConfig");
1984                     break;
1985 
1986                 case CMD_ERASE_DATA_SHARED_PREFERENCES:
1987                     request = (MainThreadRequest) msg.obj;
1988                     request.result = defaultPhone.eraseDataInSharedPreferences();
1989                     notifyRequester(request);
1990                     break;
1991 
1992                 case CMD_CHANGE_ICC_LOCK_PASSWORD:
1993                     request = (MainThreadRequest) msg.obj;
1994                     onCompleted = obtainMessage(EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE, request);
1995                     Pair<String, String> changed = (Pair<String, String>) request.argument;
1996                     getPhoneFromRequest(request).getIccCard().changeIccLockPassword(
1997                             changed.first, changed.second, onCompleted);
1998                     break;
1999                 case EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE:
2000                     ar = (AsyncResult) msg.obj;
2001                     request = (MainThreadRequest) ar.userObj;
2002                     if (ar.exception == null) {
2003                         request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
2004                         // If the operation is successful, update the PIN storage
2005                         Pair<String, String> passwords = (Pair<String, String>) request.argument;
2006                         int phoneId = getPhoneFromRequest(request).getPhoneId();
2007                         UiccController.getInstance().getPinStorage()
2008                                 .storePin(passwords.second, phoneId);
2009                     } else {
2010                         request.result = msg.arg1;
2011                     }
2012                     notifyRequester(request);
2013                     break;
2014 
2015                 case CMD_SET_ICC_LOCK_ENABLED: {
2016                     request = (MainThreadRequest) msg.obj;
2017                     onCompleted = obtainMessage(EVENT_SET_ICC_LOCK_ENABLED_DONE, request);
2018                     Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
2019                     getPhoneFromRequest(request).getIccCard().setIccLockEnabled(
2020                             enabled.first, enabled.second, onCompleted);
2021                     break;
2022                 }
2023                 case EVENT_SET_ICC_LOCK_ENABLED_DONE:
2024                     ar = (AsyncResult) msg.obj;
2025                     request = (MainThreadRequest) ar.userObj;
2026                     if (ar.exception == null) {
2027                         request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
2028                         // If the operation is successful, update the PIN storage
2029                         Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
2030                         int phoneId = getPhoneFromRequest(request).getPhoneId();
2031                         if (enabled.first) {
2032                             UiccController.getInstance().getPinStorage()
2033                                     .storePin(enabled.second, phoneId);
2034                         } else {
2035                             UiccController.getInstance().getPinStorage().clearPin(phoneId);
2036                         }
2037                     } else {
2038                         request.result = msg.arg1;
2039                     }
2040 
2041 
2042                     notifyRequester(request);
2043                     break;
2044 
2045                 case MSG_NOTIFY_USER_ACTIVITY:
2046                     removeMessages(MSG_NOTIFY_USER_ACTIVITY);
2047                     Intent intent = new Intent(TelephonyIntents.ACTION_USER_ACTIVITY_NOTIFICATION);
2048                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
2049                     getDefaultPhone().getContext().sendBroadcastAsUser(
2050                             intent, UserHandle.ALL, permission.USER_ACTIVITY);
2051                     break;
2052 
2053                 case CMD_SET_DATA_THROTTLING: {
2054                     request = (MainThreadRequest) msg.obj;
2055                     onCompleted = obtainMessage(EVENT_SET_DATA_THROTTLING_DONE, request);
2056                     DataThrottlingRequest dataThrottlingRequest =
2057                             (DataThrottlingRequest) request.argument;
2058                     Phone phone = getPhoneFromRequest(request);
2059                     if (phone != null) {
2060                         phone.setDataThrottling(onCompleted,
2061                                 request.workSource, dataThrottlingRequest.getDataThrottlingAction(),
2062                                 dataThrottlingRequest.getCompletionDurationMillis());
2063                     } else {
2064                         loge("setDataThrottling: No phone object");
2065                         request.result =
2066                                 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
2067                         notifyRequester(request);
2068                     }
2069 
2070                     break;
2071                 }
2072                 case EVENT_SET_DATA_THROTTLING_DONE:
2073                     ar = (AsyncResult) msg.obj;
2074                     request = (MainThreadRequest) ar.userObj;
2075 
2076                     if (ar.exception == null) {
2077                         request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
2078                     } else if (ar.exception instanceof CommandException) {
2079                         loge("setDataThrottling: CommandException: " + ar.exception);
2080                         CommandException.Error error =
2081                                 ((CommandException) (ar.exception)).getCommandError();
2082 
2083                         if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
2084                             request.result = TelephonyManager
2085                                     .THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
2086                         } else if (error == CommandException.Error.INVALID_ARGUMENTS) {
2087                             request.result = SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS;
2088                         } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
2089                             request.result = MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE;
2090                         } else {
2091                             request.result =
2092                                     TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
2093                         }
2094                     } else {
2095                         request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
2096                     }
2097                     Log.w(LOG_TAG, "DataThrottlingResult = " + request.result);
2098                     notifyRequester(request);
2099                     break;
2100 
2101                 case CMD_SET_SIM_POWER: {
2102                     request = (MainThreadRequest) msg.obj;
2103                     onCompleted = obtainMessage(EVENT_SET_SIM_POWER_DONE, request);
2104                     request = (MainThreadRequest) msg.obj;
2105                     int stateToSet =
2106                             ((Pair<Integer, IIntegerConsumer>)
2107                                     request.argument).first;
2108                     request.phone.setSimPowerState(stateToSet, onCompleted, request.workSource);
2109                     break;
2110                 }
2111                 case EVENT_SET_SIM_POWER_DONE: {
2112                     ar = (AsyncResult) msg.obj;
2113                     request = (MainThreadRequest) ar.userObj;
2114                     IIntegerConsumer callback =
2115                             ((Pair<Integer, IIntegerConsumer>) request.argument).second;
2116                     if (ar.exception != null) {
2117                         loge("setSimPower exception: " + ar.exception);
2118                         int errorCode = TelephonyManager.CallForwardingInfoCallback
2119                                 .RESULT_ERROR_UNKNOWN;
2120                         if (ar.exception instanceof CommandException) {
2121                             CommandException.Error error =
2122                                     ((CommandException) (ar.exception)).getCommandError();
2123                             if (error == CommandException.Error.SIM_ERR) {
2124                                 errorCode = TelephonyManager.SET_SIM_POWER_STATE_SIM_ERROR;
2125                             } else if (error == CommandException.Error.INVALID_ARGUMENTS) {
2126                                 errorCode = TelephonyManager.SET_SIM_POWER_STATE_ALREADY_IN_STATE;
2127                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
2128                                 errorCode = TelephonyManager.SET_SIM_POWER_STATE_NOT_SUPPORTED;
2129                             } else {
2130                                 errorCode = TelephonyManager.SET_SIM_POWER_STATE_MODEM_ERROR;
2131                             }
2132                         }
2133                         try {
2134                             callback.accept(errorCode);
2135                         } catch (RemoteException e) {
2136                             // Ignore if the remote process is no longer available to call back.
2137                             Log.w(LOG_TAG, "setSimPower: callback not available.");
2138                         }
2139                     } else {
2140                         try {
2141                             callback.accept(TelephonyManager.SET_SIM_POWER_STATE_SUCCESS);
2142                         } catch (RemoteException e) {
2143                             // Ignore if the remote process is no longer available to call back.
2144                             Log.w(LOG_TAG, "setSimPower: callback not available.");
2145                         }
2146                     }
2147                     break;
2148                 }
2149                 case CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST: {
2150                     request = (MainThreadRequest) msg.obj;
2151 
2152                     final Phone phone = getPhoneFromRequest(request);
2153                     if (phone == null || phone.getServiceStateTracker() == null) {
2154                         request.result = new IllegalStateException("Phone or SST is null");
2155                         notifyRequester(request);
2156                         break;
2157                     }
2158 
2159                     Pair<Integer, SignalStrengthUpdateRequest> pair =
2160                             (Pair<Integer, SignalStrengthUpdateRequest>) request.argument;
2161                     onCompleted = obtainMessage(EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE,
2162                             request);
2163                     phone.getSignalStrengthController().setSignalStrengthUpdateRequest(
2164                             request.subId, pair.first /*callingUid*/,
2165                             pair.second /*request*/, onCompleted);
2166                     break;
2167                 }
2168                 case EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE: {
2169                     ar = (AsyncResult) msg.obj;
2170                     request = (MainThreadRequest) ar.userObj;
2171                     // request.result will be the exception of ar if present, true otherwise.
2172                     // Be cautious not to leave result null which will wait() forever
2173                     request.result = ar.exception != null ? ar.exception : true;
2174                     notifyRequester(request);
2175                     break;
2176                 }
2177                 case CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST: {
2178                     request = (MainThreadRequest) msg.obj;
2179 
2180                     Phone phone = getPhoneFromRequest(request);
2181                     if (phone == null || phone.getServiceStateTracker() == null) {
2182                         request.result = new IllegalStateException("Phone or SST is null");
2183                         notifyRequester(request);
2184                         break;
2185                     }
2186 
2187                     Pair<Integer, SignalStrengthUpdateRequest> pair =
2188                             (Pair<Integer, SignalStrengthUpdateRequest>) request.argument;
2189                     onCompleted = obtainMessage(EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE,
2190                             request);
2191                     phone.getSignalStrengthController().clearSignalStrengthUpdateRequest(
2192                             request.subId, pair.first /*callingUid*/,
2193                             pair.second /*request*/, onCompleted);
2194                     break;
2195                 }
2196                 case EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE: {
2197                     ar = (AsyncResult) msg.obj;
2198                     request = (MainThreadRequest) ar.userObj;
2199                     request.result = ar.exception != null ? ar.exception : true;
2200                     notifyRequester(request);
2201                     break;
2202                 }
2203 
2204                 case CMD_GET_SLICING_CONFIG: {
2205                     request = (MainThreadRequest) msg.obj;
2206                     onCompleted = obtainMessage(EVENT_GET_SLICING_CONFIG_DONE, request);
2207                     request.phone.getSlicingConfig(onCompleted);
2208                     break;
2209                 }
2210                 case EVENT_GET_SLICING_CONFIG_DONE: {
2211                     ar = (AsyncResult) msg.obj;
2212                     request = (MainThreadRequest) ar.userObj;
2213                     ResultReceiver result = (ResultReceiver) request.argument;
2214 
2215                     NetworkSlicingConfig slicingConfig = null;
2216                     Bundle bundle = new Bundle();
2217                     int resultCode = 0;
2218                     if (ar.exception != null) {
2219                         Log.e(LOG_TAG, "Exception retrieving slicing configuration="
2220                                 + ar.exception);
2221                         resultCode = TelephonyManager.NetworkSlicingException.ERROR_MODEM_ERROR;
2222                     } else if (ar.result == null) {
2223                         Log.w(LOG_TAG, "Timeout Waiting for slicing configuration!");
2224                         resultCode = TelephonyManager.NetworkSlicingException.ERROR_TIMEOUT;
2225                     } else {
2226                         // use the result as returned
2227                         resultCode = TelephonyManager.NetworkSlicingException.SUCCESS;
2228                         slicingConfig = (NetworkSlicingConfig) ar.result;
2229                     }
2230 
2231                     if (slicingConfig == null) {
2232                         slicingConfig = new NetworkSlicingConfig();
2233                     }
2234                     bundle.putParcelable(TelephonyManager.KEY_SLICING_CONFIG_HANDLE, slicingConfig);
2235                     result.send(resultCode, bundle);
2236                     notifyRequester(request);
2237                     break;
2238                 }
2239 
2240                 case CMD_PURCHASE_PREMIUM_CAPABILITY: {
2241                     request = (MainThreadRequest) msg.obj;
2242                     onCompleted = obtainMessage(EVENT_PURCHASE_PREMIUM_CAPABILITY_DONE, request);
2243                     PurchasePremiumCapabilityArgument arg =
2244                             (PurchasePremiumCapabilityArgument) request.argument;
2245                     SlicePurchaseController.getInstance(request.phone, mFeatureFlags)
2246                             .purchasePremiumCapability(arg.capability, onCompleted);
2247                     break;
2248                 }
2249 
2250                 case EVENT_PURCHASE_PREMIUM_CAPABILITY_DONE: {
2251                     ar = (AsyncResult) msg.obj;
2252                     request = (MainThreadRequest) ar.userObj;
2253                     PurchasePremiumCapabilityArgument arg =
2254                             (PurchasePremiumCapabilityArgument) request.argument;
2255                     try {
2256                         int result = (int) ar.result;
2257                         arg.callback.accept(result);
2258                         log("purchasePremiumCapability: capability="
2259                                 + TelephonyManager.convertPremiumCapabilityToString(arg.capability)
2260                                 + ", result="
2261                                 + TelephonyManager.convertPurchaseResultToString(result));
2262                     } catch (RemoteException e) {
2263                         String logStr = "Purchase premium capability "
2264                                 + TelephonyManager.convertPremiumCapabilityToString(arg.capability)
2265                                 + " failed: " + e;
2266                         if (DBG) log(logStr);
2267                         AnomalyReporter.reportAnomaly(
2268                                 UUID.fromString(PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID), logStr);
2269                     }
2270                     break;
2271                 }
2272 
2273                 case CMD_PREPARE_UNATTENDED_REBOOT:
2274                     request = (MainThreadRequest) msg.obj;
2275                     request.result =
2276                             UiccController.getInstance().getPinStorage()
2277                                     .prepareUnattendedReboot(request.workSource);
2278                     notifyRequester(request);
2279                     break;
2280 
2281                 default:
2282                     Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
2283                     break;
2284             }
2285         }
2286 
notifyRequester(MainThreadRequest request)2287         private void notifyRequester(MainThreadRequest request) {
2288             synchronized (request) {
2289                 request.notifyAll();
2290             }
2291         }
2292 
handleNullReturnEvent(Message msg, String command)2293         private void handleNullReturnEvent(Message msg, String command) {
2294             AsyncResult ar = (AsyncResult) msg.obj;
2295             MainThreadRequest request = (MainThreadRequest) ar.userObj;
2296             if (ar.exception == null) {
2297                 request.result = true;
2298             } else {
2299                 request.result = false;
2300                 if (ar.exception instanceof CommandException) {
2301                     loge(command + ": CommandException: " + ar.exception);
2302                 } else {
2303                     loge(command + ": Unknown exception");
2304                 }
2305             }
2306             notifyRequester(request);
2307         }
2308     }
2309 
2310     /**
2311      * Posts the specified command to be executed on the main thread,
2312      * waits for the request to complete, and returns the result.
2313      * @see #sendRequestAsync
2314      */
sendRequest(int command, Object argument)2315     private Object sendRequest(int command, Object argument) {
2316         return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null,
2317                 null, -1 /*timeoutInMs*/);
2318     }
2319 
2320     /**
2321      * Posts the specified command to be executed on the main thread,
2322      * waits for the request to complete, and returns the result.
2323      * @see #sendRequestAsync
2324      */
sendRequest(int command, Object argument, WorkSource workSource)2325     private Object sendRequest(int command, Object argument, WorkSource workSource) {
2326         return sendRequest(command, argument,  SubscriptionManager.INVALID_SUBSCRIPTION_ID,
2327                 null, workSource, -1 /*timeoutInMs*/);
2328     }
2329 
2330     /**
2331      * Posts the specified command to be executed on the main thread,
2332      * waits for the request to complete, and returns the result.
2333      * @see #sendRequestAsync
2334      */
sendRequest(int command, Object argument, Integer subId)2335     private Object sendRequest(int command, Object argument, Integer subId) {
2336         return sendRequest(command, argument, subId, null, null, -1 /*timeoutInMs*/);
2337     }
2338 
2339     /**
2340      * Posts the specified command to be executed on the main thread,
2341      * waits for the request to complete for at most {@code timeoutInMs}, and returns the result
2342      * if not timeout or null otherwise.
2343      * @see #sendRequestAsync
2344      */
sendRequest(int command, Object argument, Integer subId, long timeoutInMs)2345     private @Nullable Object sendRequest(int command, Object argument, Integer subId,
2346             long timeoutInMs) {
2347         return sendRequest(command, argument, subId, null, null, timeoutInMs);
2348     }
2349 
2350     /**
2351      * Posts the specified command to be executed on the main thread,
2352      * waits for the request to complete, and returns the result.
2353      * @see #sendRequestAsync
2354      */
sendRequest(int command, Object argument, int subId, WorkSource workSource)2355     private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
2356         return sendRequest(command, argument, subId, null, workSource, -1 /*timeoutInMs*/);
2357     }
2358 
2359     /**
2360      * Posts the specified command to be executed on the main thread,
2361      * waits for the request to complete, and returns the result.
2362      * @see #sendRequestAsync
2363      */
sendRequest(int command, Object argument, Phone phone, WorkSource workSource)2364     private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
2365         return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone,
2366                 workSource, -1 /*timeoutInMs*/);
2367     }
2368 
2369     /**
2370      * Posts the specified command to be executed on the main thread. If {@code timeoutInMs} is
2371      * negative, waits for the request to complete, and returns the result. Otherwise, wait for
2372      * maximum of {@code timeoutInMs} milliseconds, interrupt and return null.
2373      * @see #sendRequestAsync
2374      */
sendRequest(int command, Object argument, Integer subId, Phone phone, WorkSource workSource, long timeoutInMs)2375     private @Nullable Object sendRequest(int command, Object argument, Integer subId, Phone phone,
2376             WorkSource workSource, long timeoutInMs) {
2377         if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
2378             throw new RuntimeException("This method will deadlock if called from the main thread.");
2379         }
2380 
2381         MainThreadRequest request = null;
2382         if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
2383             throw new IllegalArgumentException("subId and phone cannot both be specified!");
2384         } else if (phone != null) {
2385             request = new MainThreadRequest(argument, phone, workSource);
2386         } else {
2387             request = new MainThreadRequest(argument, subId, workSource);
2388         }
2389 
2390         Message msg = mMainThreadHandler.obtainMessage(command, request);
2391         msg.sendToTarget();
2392 
2393 
2394         synchronized (request) {
2395             if (timeoutInMs >= 0) {
2396                 // Wait for at least timeoutInMs before returning null request result
2397                 long now = SystemClock.elapsedRealtime();
2398                 long deadline = now + timeoutInMs;
2399                 while (request.result == null && now < deadline) {
2400                     try {
2401                         request.wait(deadline - now);
2402                     } catch (InterruptedException e) {
2403                         // Do nothing, go back and check if request is completed or timeout
2404                     } finally {
2405                         now = SystemClock.elapsedRealtime();
2406                     }
2407                 }
2408             } else {
2409                 // Wait for the request to complete
2410                 while (request.result == null) {
2411                     try {
2412                         request.wait();
2413                     } catch (InterruptedException e) {
2414                         // Do nothing, go back and wait until the request is complete
2415                     }
2416                 }
2417             }
2418         }
2419         if (request.result == null) {
2420             Log.wtf(LOG_TAG,
2421                     "sendRequest: Blocking command timed out. Something has gone terribly wrong.");
2422         }
2423         return request.result;
2424     }
2425 
2426     /**
2427      * Asynchronous ("fire and forget") version of sendRequest():
2428      * Posts the specified command to be executed on the main thread, and
2429      * returns immediately.
2430      * @see #sendRequest
2431      */
sendRequestAsync(int command)2432     private void sendRequestAsync(int command) {
2433         mMainThreadHandler.sendEmptyMessage(command);
2434     }
2435 
2436     /**
2437      * Same as {@link #sendRequestAsync(int)} except it takes an argument.
2438      * @see {@link #sendRequest(int)}
2439      */
sendRequestAsync(int command, Object argument)2440     private void sendRequestAsync(int command, Object argument) {
2441         sendRequestAsync(command, argument, null, null);
2442     }
2443 
2444     /**
2445      * Same as {@link #sendRequestAsync(int,Object)} except it takes a Phone and WorkSource.
2446      * @see {@link #sendRequest(int,Object)}
2447      */
sendRequestAsync( int command, Object argument, Phone phone, WorkSource workSource)2448     private void sendRequestAsync(
2449             int command, Object argument, Phone phone, WorkSource workSource) {
2450         MainThreadRequest request = new MainThreadRequest(argument, phone, workSource);
2451         Message msg = mMainThreadHandler.obtainMessage(command, request);
2452         msg.sendToTarget();
2453     }
2454 
2455     /**
2456      * Initialize the singleton PhoneInterfaceManager instance.
2457      * This is only done once, at startup, from PhoneApp.onCreate().
2458      */
init(PhoneGlobals app, FeatureFlags featureFlags)2459     /* package */ static PhoneInterfaceManager init(PhoneGlobals app, FeatureFlags featureFlags) {
2460         synchronized (PhoneInterfaceManager.class) {
2461             if (sInstance == null) {
2462                 sInstance = new PhoneInterfaceManager(app, featureFlags);
2463             } else {
2464                 Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
2465             }
2466             return sInstance;
2467         }
2468     }
2469 
2470     /** Private constructor; @see init() */
PhoneInterfaceManager(PhoneGlobals app, FeatureFlags featureFlags)2471     private PhoneInterfaceManager(PhoneGlobals app, FeatureFlags featureFlags) {
2472         mApp = app;
2473         mFeatureFlags = featureFlags;
2474         mTelecomFeatureFlags = new com.android.server.telecom.flags.FeatureFlagsImpl();
2475         mCM = PhoneGlobals.getInstance().mCM;
2476         mImsResolver = ImsResolver.getInstance();
2477         mSatelliteController = SatelliteController.getInstance();
2478         mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
2479         mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
2480         mMainThreadHandler = new MainThreadHandler();
2481         mTelephonySharedPreferences = PreferenceManager.getDefaultSharedPreferences(mApp);
2482         mNetworkScanRequestTracker = new NetworkScanRequestTracker();
2483         mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
2484         mRadioInterfaceCapabilities = RadioInterfaceCapabilityController.getInstance();
2485         mNotifyUserActivity = new AtomicBoolean(false);
2486         mPackageManager = app.getPackageManager();
2487         mSatelliteAccessController = SatelliteAccessController.getOrCreateInstance(
2488                 getDefaultPhone().getContext(), featureFlags);
2489         mVendorApiLevel = SystemProperties.getInt(
2490                 "ro.vendor.api_level", Build.VERSION.DEVICE_INITIAL_SDK_INT);
2491 
2492         PropertyInvalidatedCache.invalidateCache(TelephonyManager.CACHE_KEY_PHONE_ACCOUNT_TO_SUBID);
2493         publish();
2494         CarrierAllowListInfo.loadInstance(mApp);
2495 
2496         // Create the SatelliteEntitlementController singleton, for using the get the
2497         // entitlementStatus for satellite service.
2498         SatelliteEntitlementController.make(mApp, mFeatureFlags);
2499     }
2500 
2501     @VisibleForTesting
getSharedPreferences()2502     public SharedPreferences getSharedPreferences() {
2503         return mTelephonySharedPreferences;
2504     }
2505 
2506     /**
2507      * Get the default phone for this device.
2508      */
2509     @VisibleForTesting
getDefaultPhone()2510     public Phone getDefaultPhone() {
2511         Phone thePhone = getPhone(getDefaultSubscription());
2512         return (thePhone != null) ? thePhone : PhoneFactory.getDefaultPhone();
2513     }
2514 
publish()2515     private void publish() {
2516         if (DBG) log("publish: " + this);
2517 
2518         TelephonyFrameworkInitializer
2519                 .getTelephonyServiceManager()
2520                 .getTelephonyServiceRegisterer()
2521                 .register(this);
2522     }
2523 
getPhoneFromRequest(MainThreadRequest request)2524     private Phone getPhoneFromRequest(MainThreadRequest request) {
2525         if (request.phone != null) {
2526             return request.phone;
2527         } else {
2528             return getPhoneFromSubId(request.subId);
2529         }
2530     }
2531 
getPhoneFromSubId(int subId)2532     private Phone getPhoneFromSubId(int subId) {
2533         return (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
2534                 ? getDefaultPhone() : getPhone(subId);
2535     }
2536 
2537     /**
2538      * Get phone object associated with a subscription.
2539      * Return default phone if phone object associated with subscription is null
2540      * @param subId - subscriptionId
2541      * @return phone object associated with a subscription or default phone if null.
2542      */
getPhoneFromSubIdOrDefault(int subId)2543     private @NonNull Phone getPhoneFromSubIdOrDefault(int subId) {
2544         Phone phone = getPhoneFromSubId(subId);
2545         if (phone == null) {
2546             loge("Called with invalid subId: " + subId + ". Retrying with default phone.");
2547             phone = getDefaultPhone();
2548         }
2549         return phone;
2550     }
2551 
2552     @Nullable
getUiccPortFromRequest(@onNull MainThreadRequest request)2553     private UiccPort getUiccPortFromRequest(@NonNull MainThreadRequest request) {
2554         Phone phone = getPhoneFromRequest(request);
2555         return phone == null ? null :
2556                 UiccController.getInstance().getUiccPort(phone.getPhoneId());
2557     }
2558 
2559     /**
2560      * @param subId The sub Id that associates the phone. If the device has no active SIM, passing
2561      *              in {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} or any sub <=
2562      *              {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} will return {@code null}.
2563      * @return The Phone associated the sub Id
2564      */
getPhone(int subId)2565     private @Nullable Phone getPhone(int subId) {
2566         return PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId));
2567     }
2568 
sendEraseModemConfig(@onNull Phone phone)2569     private void sendEraseModemConfig(@NonNull Phone phone) {
2570         Boolean success = (Boolean) sendRequest(CMD_ERASE_MODEM_CONFIG, null);
2571         if (DBG) log("eraseModemConfig:" + ' ' + (success ? "ok" : "fail"));
2572     }
2573 
sendEraseDataInSharedPreferences(@onNull Phone phone)2574     private void sendEraseDataInSharedPreferences(@NonNull Phone phone) {
2575         Boolean success = (Boolean) sendRequest(CMD_ERASE_DATA_SHARED_PREFERENCES, null);
2576         if (DBG) log("eraseDataInSharedPreferences:" + ' ' + (success ? "ok" : "fail"));
2577     }
2578 
isImsAvailableOnDevice()2579     private boolean isImsAvailableOnDevice() {
2580         PackageManager pm = getDefaultPhone().getContext().getPackageManager();
2581         if (pm == null) {
2582             // For some reason package manger is not available.. This will fail internally anyway,
2583             // so do not throw error and allow.
2584             return true;
2585         }
2586         return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS, 0);
2587     }
2588 
dial(String number)2589     public void dial(String number) {
2590         enforceTelephonyFeatureWithException(getCurrentPackageName(),
2591                 PackageManager.FEATURE_TELEPHONY_CALLING, "dial");
2592 
2593         dialForSubscriber(getPreferredVoiceSubscription(), number);
2594     }
2595 
dialForSubscriber(int subId, String number)2596     public void dialForSubscriber(int subId, String number) {
2597         if (DBG) log("dial: " + number);
2598         // No permission check needed here: This is just a wrapper around the
2599         // ACTION_DIAL intent, which is available to any app since it puts up
2600         // the UI before it does anything.
2601 
2602         final long identity = Binder.clearCallingIdentity();
2603         try {
2604             String url = createTelUrl(number);
2605             if (url == null) {
2606                 return;
2607             }
2608 
2609             // PENDING: should we just silently fail if phone is offhook or ringing?
2610             PhoneConstants.State state = mCM.getState(subId);
2611             if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
2612                 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
2613                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2614                 mApp.startActivity(intent);
2615             }
2616         } finally {
2617             Binder.restoreCallingIdentity(identity);
2618         }
2619     }
2620 
call(String callingPackage, String number)2621     public void call(String callingPackage, String number) {
2622         callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
2623     }
2624 
callForSubscriber(int subId, String callingPackage, String number)2625     public void callForSubscriber(int subId, String callingPackage, String number) {
2626         if (DBG) log("call: " + number);
2627 
2628         // This is just a wrapper around the ACTION_CALL intent, but we still
2629         // need to do a permission check since we're calling startActivity()
2630         // from the context of the phone app.
2631         enforceCallPermission();
2632 
2633         if (mAppOps.noteOp(AppOpsManager.OPSTR_CALL_PHONE, Binder.getCallingUid(), callingPackage)
2634                 != AppOpsManager.MODE_ALLOWED) {
2635             return;
2636         }
2637 
2638         enforceTelephonyFeatureWithException(callingPackage,
2639                 PackageManager.FEATURE_TELEPHONY_CALLING, "call");
2640 
2641         final long identity = Binder.clearCallingIdentity();
2642         try {
2643             String url = createTelUrl(number);
2644             if (url == null) {
2645                 return;
2646             }
2647 
2648             boolean isValid = false;
2649             final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
2650             if (slist != null) {
2651                 for (SubscriptionInfo subInfoRecord : slist) {
2652                     if (subInfoRecord.getSubscriptionId() == subId) {
2653                         isValid = true;
2654                         break;
2655                     }
2656                 }
2657             }
2658             if (!isValid) {
2659                 return;
2660             }
2661 
2662             Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
2663             intent.putExtra(SUBSCRIPTION_KEY, subId);
2664             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2665             mApp.startActivity(intent);
2666         } finally {
2667             Binder.restoreCallingIdentity(identity);
2668         }
2669     }
2670 
supplyPinForSubscriber(int subId, String pin)2671     public boolean supplyPinForSubscriber(int subId, String pin) {
2672         int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
2673         return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
2674     }
2675 
supplyPukForSubscriber(int subId, String puk, String pin)2676     public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
2677         int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
2678         return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
2679     }
2680 
supplyPinReportResultForSubscriber(int subId, String pin)2681     public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
2682         enforceModifyPermission();
2683 
2684         enforceTelephonyFeatureWithException(getCurrentPackageName(),
2685                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
2686                 "supplyPinReportResultForSubscriber");
2687 
2688         final long identity = Binder.clearCallingIdentity();
2689         try {
2690             Phone phone = getPhone(subId);
2691             final UnlockSim checkSimPin = new UnlockSim(phone.getPhoneId(), phone.getIccCard());
2692             checkSimPin.start();
2693             return checkSimPin.unlockSim(null, pin);
2694         } finally {
2695             Binder.restoreCallingIdentity(identity);
2696         }
2697     }
2698 
supplyPukReportResultForSubscriber(int subId, String puk, String pin)2699     public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
2700         enforceModifyPermission();
2701 
2702         enforceTelephonyFeatureWithException(getCurrentPackageName(),
2703                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "supplyPukForSubscriber");
2704 
2705         final long identity = Binder.clearCallingIdentity();
2706         try {
2707             Phone phone = getPhone(subId);
2708             final UnlockSim checkSimPuk = new UnlockSim(phone.getPhoneId(), phone.getIccCard());
2709             checkSimPuk.start();
2710             return checkSimPuk.unlockSim(puk, pin);
2711         } finally {
2712             Binder.restoreCallingIdentity(identity);
2713         }
2714     }
2715 
2716     /**
2717      * Helper thread to turn async call to SimCard#supplyPin into
2718      * a synchronous one.
2719      */
2720     private static class UnlockSim extends Thread {
2721 
2722         private final IccCard mSimCard;
2723         private final int mPhoneId;
2724 
2725         private boolean mDone = false;
2726         private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
2727         private int mRetryCount = -1;
2728 
2729         // For replies from SimCard interface
2730         private Handler mHandler;
2731 
2732         // For async handler to identify request type
2733         private static final int SUPPLY_PIN_COMPLETE = 100;
2734         private static final int SUPPLY_PIN_DELAYED  = 101;
2735         private static final int SUPPLY_PIN_DELAYED_TIMER_IN_MILLIS = 10000;
2736         private static final UUID SUPPLY_PIN_UUID = UUID.fromString(
2737                 "d3768135-4323-491d-a6c8-bda01fc89040");
2738 
UnlockSim(int phoneId, IccCard simCard)2739         UnlockSim(int phoneId, IccCard simCard) {
2740             mPhoneId = phoneId;
2741             mSimCard = simCard;
2742         }
2743 
2744         @Override
run()2745         public void run() {
2746             Looper.prepare();
2747             synchronized (UnlockSim.this) {
2748                 mHandler = new Handler() {
2749                     @Override
2750                     public void handleMessage(Message msg) {
2751                         AsyncResult ar = (AsyncResult) msg.obj;
2752                         switch (msg.what) {
2753                             case SUPPLY_PIN_COMPLETE:
2754                                 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
2755                                 synchronized (UnlockSim.this) {
2756                                     mRetryCount = msg.arg1;
2757                                     if (ar.exception != null) {
2758                                         CommandException.Error error = null;
2759                                         if (ar.exception instanceof CommandException) {
2760                                             error = ((CommandException) (ar.exception))
2761                                                     .getCommandError();
2762                                         }
2763                                         if (error == CommandException.Error.PASSWORD_INCORRECT) {
2764                                             mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
2765                                         } else if (error == CommandException.Error.ABORTED) {
2766                                             /* When UiccCardApp dispose, handle message and return
2767                                              exception */
2768                                             mResult = PhoneConstants.PIN_OPERATION_ABORTED;
2769                                         } else {
2770                                             mResult = PhoneConstants.PIN_GENERAL_FAILURE;
2771                                         }
2772                                     } else {
2773                                         mResult = PhoneConstants.PIN_RESULT_SUCCESS;
2774                                     }
2775                                     mDone = true;
2776                                     removeMessages(SUPPLY_PIN_DELAYED);
2777                                     UnlockSim.this.notifyAll();
2778                                 }
2779                                 break;
2780                             case SUPPLY_PIN_DELAYED:
2781                                 if(!mDone) {
2782                                     String logStr = "Delay in receiving SIM PIN response ";
2783                                     if (DBG) log(logStr);
2784                                     AnomalyReporter.reportAnomaly(SUPPLY_PIN_UUID, logStr);
2785                                 }
2786                                 break;
2787                         }
2788                     }
2789                 };
2790                 UnlockSim.this.notifyAll();
2791             }
2792             Looper.loop();
2793         }
2794 
2795         /*
2796          * Use PIN or PUK to unlock SIM card
2797          *
2798          * If PUK is null, unlock SIM card with PIN
2799          *
2800          * If PUK is not null, unlock SIM card with PUK and set PIN code
2801          *
2802          * Besides, since it is reused in class level, the thread's looper will be stopped to avoid
2803          * its thread leak.
2804          */
unlockSim(String puk, String pin)2805         synchronized int[] unlockSim(String puk, String pin) {
2806 
2807             while (mHandler == null) {
2808                 try {
2809                     wait();
2810                 } catch (InterruptedException e) {
2811                     Thread.currentThread().interrupt();
2812                 }
2813             }
2814             Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
2815 
2816             if (puk == null) {
2817                 mSimCard.supplyPin(pin, callback);
2818             } else {
2819                 mSimCard.supplyPuk(puk, pin, callback);
2820             }
2821 
2822             while (!mDone) {
2823                 try {
2824                     Log.d(LOG_TAG, "wait for done");
2825                     mHandler.sendEmptyMessageDelayed(SUPPLY_PIN_DELAYED,
2826                             SUPPLY_PIN_DELAYED_TIMER_IN_MILLIS);
2827                     wait();
2828                 } catch (InterruptedException e) {
2829                     // Restore the interrupted status
2830                     Thread.currentThread().interrupt();
2831                 }
2832             }
2833             Log.d(LOG_TAG, "done");
2834             int[] resultArray = new int[2];
2835             resultArray[0] = mResult;
2836             resultArray[1] = mRetryCount;
2837 
2838             if (mResult == PhoneConstants.PIN_RESULT_SUCCESS && pin.length() > 0) {
2839                 UiccController.getInstance().getPinStorage().storePin(pin, mPhoneId);
2840             }
2841             // This instance is no longer reused, so quit its thread's looper.
2842             mHandler.getLooper().quitSafely();
2843 
2844             return resultArray;
2845         }
2846     }
2847 
2848     /**
2849      * This method has been removed due to privacy and stability concerns.
2850      */
2851     @Override
updateServiceLocation()2852     public void updateServiceLocation() {
2853         Log.e(LOG_TAG, "Call to unsupported method updateServiceLocation()");
2854         return;
2855     }
2856 
2857     @Override
updateServiceLocationWithPackageName(String callingPackage)2858     public void updateServiceLocationWithPackageName(String callingPackage) {
2859         mApp.getSystemService(AppOpsManager.class)
2860                 .checkPackage(Binder.getCallingUid(), callingPackage);
2861 
2862         final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
2863         if (targetSdk > android.os.Build.VERSION_CODES.R) {
2864             // Callers targeting S have no business invoking this method.
2865             return;
2866         }
2867 
2868         LocationAccessPolicy.LocationPermissionResult locationResult =
2869                 LocationAccessPolicy.checkLocationPermission(mApp,
2870                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
2871                                 .setCallingPackage(callingPackage)
2872                                 .setCallingFeatureId(null)
2873                                 .setCallingPid(Binder.getCallingPid())
2874                                 .setCallingUid(Binder.getCallingUid())
2875                                 .setMethod("updateServiceLocation")
2876                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2877                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2878                                 .build());
2879         // Apps that lack location permission have no business calling this method;
2880         // however, because no permission was declared in the public API, denials must
2881         // all be "soft".
2882         switch (locationResult) {
2883             case DENIED_HARD: /* fall through */
2884             case DENIED_SOFT:
2885                 return;
2886         }
2887 
2888         WorkSource workSource = getWorkSource(Binder.getCallingUid());
2889         final long identity = Binder.clearCallingIdentity();
2890         try {
2891             getPhoneFromSubIdOrDefault(getDefaultSubscription()).updateServiceLocation(workSource);
2892         } finally {
2893             Binder.restoreCallingIdentity(identity);
2894         }
2895     }
2896 
2897     @Deprecated
2898     @Override
isRadioOn(String callingPackage)2899     public boolean isRadioOn(String callingPackage) {
2900         return isRadioOnWithFeature(callingPackage, null);
2901     }
2902 
2903 
2904     @Override
isRadioOnWithFeature(String callingPackage, String callingFeatureId)2905     public boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId) {
2906         return isRadioOnForSubscriberWithFeature(getDefaultSubscription(), callingPackage,
2907                 callingFeatureId);
2908     }
2909 
2910     @Deprecated
2911     @Override
isRadioOnForSubscriber(int subId, String callingPackage)2912     public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
2913         return isRadioOnForSubscriberWithFeature(subId, callingPackage, null);
2914     }
2915 
2916     @Override
isRadioOnForSubscriberWithFeature(int subId, String callingPackage, String callingFeatureId)2917     public boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage,
2918             String callingFeatureId) {
2919         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2920                 mApp, subId, callingPackage, callingFeatureId, "isRadioOnForSubscriber")) {
2921             return false;
2922         }
2923 
2924         enforceTelephonyFeatureWithException(callingPackage,
2925                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "isRadioOnWithFeature");
2926 
2927         final long identity = Binder.clearCallingIdentity();
2928         try {
2929             return isRadioOnForSubscriber(subId);
2930         } finally {
2931             Binder.restoreCallingIdentity(identity);
2932         }
2933     }
2934 
isRadioOnForSubscriber(int subId)2935     private boolean isRadioOnForSubscriber(int subId) {
2936         final long identity = Binder.clearCallingIdentity();
2937         try {
2938             final Phone phone = getPhone(subId);
2939             if (phone != null) {
2940                 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
2941             } else {
2942                 return false;
2943             }
2944         } finally {
2945             Binder.restoreCallingIdentity(identity);
2946         }
2947     }
2948 
toggleRadioOnOff()2949     public void toggleRadioOnOff() {
2950         toggleRadioOnOffForSubscriber(getDefaultSubscription());
2951     }
2952 
toggleRadioOnOffForSubscriber(int subId)2953     public void toggleRadioOnOffForSubscriber(int subId) {
2954         enforceModifyPermission();
2955 
2956         enforceTelephonyFeatureWithException(getCurrentPackageName(),
2957                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "toggleRadioOnOffForSubscriber");
2958 
2959         final long identity = Binder.clearCallingIdentity();
2960         try {
2961             final Phone phone = getPhone(subId);
2962             if (phone != null) {
2963                 phone.setRadioPower(!isRadioOnForSubscriber(subId));
2964             }
2965         } finally {
2966             Binder.restoreCallingIdentity(identity);
2967         }
2968     }
2969 
setRadio(boolean turnOn)2970     public boolean setRadio(boolean turnOn) {
2971         return setRadioForSubscriber(getDefaultSubscription(), turnOn);
2972     }
2973 
setRadioForSubscriber(int subId, boolean turnOn)2974     public boolean setRadioForSubscriber(int subId, boolean turnOn) {
2975         enforceModifyPermission();
2976 
2977         final long identity = Binder.clearCallingIdentity();
2978         try {
2979             final Phone phone = getPhone(subId);
2980             if (phone == null) {
2981                 return false;
2982             }
2983             if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
2984                 toggleRadioOnOffForSubscriber(subId);
2985             }
2986             return true;
2987         } finally {
2988             Binder.restoreCallingIdentity(identity);
2989         }
2990     }
2991 
needMobileRadioShutdown()2992     public boolean needMobileRadioShutdown() {
2993         enforceReadPrivilegedPermission("needMobileRadioShutdown");
2994 
2995         enforceTelephonyFeatureWithException(getCurrentPackageName(),
2996                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "needMobileRadioShutdown");
2997 
2998         /*
2999          * If any of the Radios are available, it will need to be
3000          * shutdown. So return true if any Radio is available.
3001          */
3002         final long identity = Binder.clearCallingIdentity();
3003         try {
3004             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3005                 Phone phone = PhoneFactory.getPhone(i);
3006                 if (phone != null && phone.isRadioAvailable()) return true;
3007             }
3008             logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
3009             return false;
3010         } finally {
3011             Binder.restoreCallingIdentity(identity);
3012         }
3013     }
3014 
3015     @Override
shutdownMobileRadios()3016     public void shutdownMobileRadios() {
3017         enforceModifyPermission();
3018 
3019         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3020                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "shutdownMobileRadios");
3021 
3022         final long identity = Binder.clearCallingIdentity();
3023         try {
3024             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3025                 logv("Shutting down Phone " + i);
3026                 shutdownRadioUsingPhoneId(i);
3027             }
3028         } finally {
3029             Binder.restoreCallingIdentity(identity);
3030         }
3031     }
3032 
shutdownRadioUsingPhoneId(int phoneId)3033     private void shutdownRadioUsingPhoneId(int phoneId) {
3034         Phone phone = PhoneFactory.getPhone(phoneId);
3035         if (phone != null && phone.isRadioAvailable()) {
3036             phone.shutdownRadio();
3037         }
3038     }
3039 
setRadioPower(boolean turnOn)3040     public boolean setRadioPower(boolean turnOn) {
3041         enforceModifyPermission();
3042 
3043         if (!turnOn) {
3044             log("setRadioPower off: callingPackage=" + getCurrentPackageName());
3045         }
3046 
3047         final long identity = Binder.clearCallingIdentity();
3048         try {
3049             final Phone defaultPhone = PhoneFactory.getDefaultPhone();
3050             if (defaultPhone != null) {
3051                 defaultPhone.setRadioPower(turnOn);
3052                 return true;
3053             } else {
3054                 loge("There's no default phone.");
3055                 return false;
3056             }
3057         } finally {
3058             Binder.restoreCallingIdentity(identity);
3059         }
3060     }
3061 
setRadioPowerForSubscriber(int subId, boolean turnOn)3062     public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
3063         enforceModifyPermission();
3064 
3065         if (!turnOn) {
3066             log("setRadioPowerForSubscriber off: subId=" + subId
3067                     + ",callingPackage=" + getCurrentPackageName());
3068         }
3069         final long identity = Binder.clearCallingIdentity();
3070         try {
3071             final Phone phone = getPhone(subId);
3072             if (phone != null) {
3073                 phone.setRadioPower(turnOn);
3074                 return true;
3075             } else {
3076                 return false;
3077             }
3078         } finally {
3079             Binder.restoreCallingIdentity(identity);
3080         }
3081     }
3082 
3083     /**
3084      * Vote on powering off the radio for a reason. The radio will be turned on only when there is
3085      * no reason to power it off. When any of the voters want to power it off, it will be turned
3086      * off. In case of emergency, the radio will be turned on even if there are some reasons for
3087      * powering it off, and these radio off votes will be cleared.
3088      * Multiple apps can vote for the same reason and the last vote will take effect. Each app is
3089      * responsible for its vote. A powering-off vote of a reason will be maintained until it is
3090      * cleared by calling {@link clearRadioPowerOffForReason} for that reason, or an emergency call
3091      * is made, or the device is rebooted. When an app comes backup from a crash, it needs to make
3092      * sure if its vote is as expected. An app can use the API {@link getRadioPowerOffReasons} to
3093      * check its vote.
3094      *
3095      * @param subId The subscription ID.
3096      * @param reason The reason for powering off radio.
3097      * @return true on success and false on failure.
3098      */
requestRadioPowerOffForReason(int subId, @TelephonyManager.RadioPowerReason int reason)3099     public boolean requestRadioPowerOffForReason(int subId,
3100             @TelephonyManager.RadioPowerReason int reason) {
3101         enforceModifyPermission();
3102 
3103         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3104                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "requestRadioPowerOffForReason");
3105 
3106         log("requestRadioPowerOffForReason: subId=" + subId
3107                 + ",reason=" + reason + ",callingPackage=" + getCurrentPackageName());
3108         final long identity = Binder.clearCallingIdentity();
3109         try {
3110             boolean result = false;
3111             for (Phone phone : PhoneFactory.getPhones()) {
3112                 result = true;
3113                 phone.setRadioPowerForReason(false, reason);
3114             }
3115             if (!result) {
3116                 loge("requestRadioPowerOffForReason: no phone exists");
3117             }
3118             return result;
3119         } finally {
3120             Binder.restoreCallingIdentity(identity);
3121         }
3122     }
3123 
3124     /**
3125      * Remove the vote on powering off the radio for a reason, as requested by
3126      * {@link requestRadioPowerOffForReason}.
3127      *
3128      * @param subId The subscription ID.
3129      * @param reason The reason for powering off radio.
3130      * @return true on success and false on failure.
3131      */
clearRadioPowerOffForReason(int subId, @TelephonyManager.RadioPowerReason int reason)3132     public boolean clearRadioPowerOffForReason(int subId,
3133             @TelephonyManager.RadioPowerReason int reason) {
3134         enforceModifyPermission();
3135 
3136         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3137                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "clearRadioPowerOffForReason");
3138 
3139         final long identity = Binder.clearCallingIdentity();
3140         try {
3141             boolean result = false;
3142             for (Phone phone : PhoneFactory.getPhones()) {
3143                 result = true;
3144                 phone.setRadioPowerForReason(true, reason);
3145             }
3146             if (!result) {
3147                 loge("clearRadioPowerOffForReason: no phone exists");
3148             }
3149             return result;
3150         } finally {
3151             Binder.restoreCallingIdentity(identity);
3152         }
3153     }
3154 
3155     /**
3156      * Get reasons for powering off radio, as requested by {@link requestRadioPowerOffForReason}.
3157      *
3158      * @param subId The subscription ID.
3159      * @param callingPackage The package making the call.
3160      * @param callingFeatureId The feature in the package.
3161      * @return List of reasons for powering off radio.
3162      */
getRadioPowerOffReasons(int subId, String callingPackage, String callingFeatureId)3163     public List getRadioPowerOffReasons(int subId, String callingPackage, String callingFeatureId) {
3164         enforceReadPrivilegedPermission("getRadioPowerOffReasons");
3165 
3166         enforceTelephonyFeatureWithException(callingPackage,
3167                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getRadioPowerOffReasons");
3168 
3169         final long identity = Binder.clearCallingIdentity();
3170         List result = new ArrayList();
3171         try {
3172             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId,
3173                     callingPackage, callingFeatureId, "getRadioPowerOffReasons")) {
3174                 return result;
3175             }
3176 
3177             final Phone phone = getPhoneFromSubIdOrDefault(subId);
3178             if (phone != null) {
3179                 result.addAll(phone.getRadioPowerOffReasons());
3180             } else {
3181                 loge("getRadioPowerOffReasons: phone is null");
3182             }
3183         } finally {
3184             Binder.restoreCallingIdentity(identity);
3185         }
3186         return result;
3187     }
3188 
3189     // FIXME: subId version needed
3190     @Override
enableDataConnectivity(String callingPackage)3191     public boolean enableDataConnectivity(String callingPackage) {
3192         enforceModifyPermission();
3193 
3194         enforceTelephonyFeatureWithException(callingPackage,
3195                 PackageManager.FEATURE_TELEPHONY_DATA, "enableDataConnectivity");
3196 
3197         final long identity = Binder.clearCallingIdentity();
3198         try {
3199             int subId = SubscriptionManager.getDefaultDataSubscriptionId();
3200             final Phone phone = getPhone(subId);
3201             if (phone != null) {
3202                 phone.getDataSettingsManager().setDataEnabled(
3203                         TelephonyManager.DATA_ENABLED_REASON_USER, true, callingPackage);
3204                 return true;
3205             } else {
3206                 return false;
3207             }
3208         } finally {
3209             Binder.restoreCallingIdentity(identity);
3210         }
3211     }
3212 
3213     // FIXME: subId version needed
3214     @Override
disableDataConnectivity(String callingPackage)3215     public boolean disableDataConnectivity(String callingPackage) {
3216         enforceModifyPermission();
3217 
3218         enforceTelephonyFeatureWithException(callingPackage,
3219                 PackageManager.FEATURE_TELEPHONY_DATA, "disableDataConnectivity");
3220 
3221         final long identity = Binder.clearCallingIdentity();
3222         try {
3223             int subId = SubscriptionManager.getDefaultDataSubscriptionId();
3224             final Phone phone = getPhone(subId);
3225             if (phone != null) {
3226                 phone.getDataSettingsManager().setDataEnabled(
3227                         TelephonyManager.DATA_ENABLED_REASON_USER, false, callingPackage);
3228                 return true;
3229             } else {
3230                 return false;
3231             }
3232         } finally {
3233             Binder.restoreCallingIdentity(identity);
3234         }
3235     }
3236 
3237     @Override
isDataConnectivityPossible(int subId)3238     public boolean isDataConnectivityPossible(int subId) {
3239         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3240                 PackageManager.FEATURE_TELEPHONY_DATA, "isDataConnectivityPossible");
3241 
3242         final long identity = Binder.clearCallingIdentity();
3243         try {
3244             final Phone phone = getPhone(subId);
3245             if (phone != null) {
3246                 return phone.isDataAllowed();
3247             } else {
3248                 return false;
3249             }
3250         } finally {
3251             Binder.restoreCallingIdentity(identity);
3252         }
3253     }
3254 
handlePinMmi(String dialString)3255     public boolean handlePinMmi(String dialString) {
3256         return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
3257     }
3258 
handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback)3259     public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
3260         enforceCallPermission();
3261 
3262         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3263                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "handleUssdRequest");
3264 
3265         final long identity = Binder.clearCallingIdentity();
3266         try {
3267             if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3268                 return;
3269             }
3270             Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
3271             sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
3272         } finally {
3273             Binder.restoreCallingIdentity(identity);
3274         }
3275     };
3276 
handlePinMmiForSubscriber(int subId, String dialString)3277     public boolean handlePinMmiForSubscriber(int subId, String dialString) {
3278         enforceModifyPermission();
3279 
3280         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3281                 PackageManager.FEATURE_TELEPHONY_CALLING, "handlePinMmiForSubscriber");
3282 
3283         final long identity = Binder.clearCallingIdentity();
3284         try {
3285             if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3286                 return false;
3287             }
3288             return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
3289         } finally {
3290             Binder.restoreCallingIdentity(identity);
3291         }
3292     }
3293 
3294     /**
3295      * @deprecated  This method is deprecated and is only being kept due to an UnsupportedAppUsage
3296      * tag on getCallState Binder call.
3297      */
3298     @Deprecated
3299     @Override
getCallState()3300     public int getCallState() {
3301         if (CompatChanges.isChangeEnabled(
3302                 TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION,
3303                 Binder.getCallingUid())) {
3304             // Do not allow this API to be called on API version 31+, it should only be
3305             // called on old apps using this Binder call directly.
3306             throw new SecurityException("This method can only be used for applications "
3307                     + "targeting API version 30 or less.");
3308         }
3309         final long identity = Binder.clearCallingIdentity();
3310         try {
3311             Phone phone = getPhoneFromSubIdOrDefault(getDefaultSubscription());
3312             return PhoneConstantConversions.convertCallState(phone.getState());
3313         } finally {
3314             Binder.restoreCallingIdentity(identity);
3315         }
3316     }
3317 
3318     @Override
getCallStateForSubscription(int subId, String callingPackage, String featureId)3319     public int getCallStateForSubscription(int subId, String callingPackage, String featureId) {
3320         if (CompatChanges.isChangeEnabled(
3321                 TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION,
3322                 Binder.getCallingUid())) {
3323             // Check READ_PHONE_STATE for API version 31+
3324             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
3325                     featureId, "getCallStateForSubscription")) {
3326                 throw new SecurityException("getCallState requires READ_PHONE_STATE for apps "
3327                         + "targeting API level 31+.");
3328             }
3329         }
3330 
3331         enforceTelephonyFeatureWithException(callingPackage,
3332                 PackageManager.FEATURE_TELEPHONY_CALLING, "getCallStateForSubscription");
3333 
3334         final long identity = Binder.clearCallingIdentity();
3335         try {
3336             Phone phone = getPhone(subId);
3337             return phone == null ? TelephonyManager.CALL_STATE_IDLE :
3338                     PhoneConstantConversions.convertCallState(phone.getState());
3339         } finally {
3340             Binder.restoreCallingIdentity(identity);
3341         }
3342     }
3343 
3344     @Override
getDataState()3345     public int getDataState() {
3346         return getDataStateForSubId(SubscriptionManager.getDefaultDataSubscriptionId());
3347     }
3348 
3349     @Override
getDataStateForSubId(int subId)3350     public int getDataStateForSubId(int subId) {
3351         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3352                 PackageManager.FEATURE_TELEPHONY_DATA, "getDataStateForSubId");
3353 
3354         final long identity = Binder.clearCallingIdentity();
3355         try {
3356             final Phone phone = getPhone(subId);
3357             if (phone != null) {
3358                 return phone.getDataNetworkController().getInternetDataNetworkState();
3359             } else {
3360                 return PhoneConstantConversions.convertDataState(
3361                         PhoneConstants.DataState.DISCONNECTED);
3362             }
3363         } finally {
3364             Binder.restoreCallingIdentity(identity);
3365         }
3366     }
3367 
3368     @Override
getDataActivity()3369     public @DataActivityType int getDataActivity() {
3370         return getDataActivityForSubId(SubscriptionManager.getDefaultDataSubscriptionId());
3371     }
3372 
3373     @Override
getDataActivityForSubId(int subId)3374     public @DataActivityType int getDataActivityForSubId(int subId) {
3375         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3376                 PackageManager.FEATURE_TELEPHONY_DATA, "getDataActivityForSubId");
3377 
3378         final long identity = Binder.clearCallingIdentity();
3379         try {
3380             final Phone phone = getPhone(subId);
3381             if (phone != null) {
3382                 return phone.getDataActivityState();
3383             } else {
3384                 return TelephonyManager.DATA_ACTIVITY_NONE;
3385             }
3386         } finally {
3387             Binder.restoreCallingIdentity(identity);
3388         }
3389     }
3390 
3391     @Override
getCellLocation(String callingPackage, String callingFeatureId)3392     public CellIdentity getCellLocation(String callingPackage, String callingFeatureId) {
3393         mApp.getSystemService(AppOpsManager.class)
3394                 .checkPackage(Binder.getCallingUid(), callingPackage);
3395 
3396         LocationAccessPolicy.LocationPermissionResult locationResult =
3397                 LocationAccessPolicy.checkLocationPermission(mApp,
3398                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
3399                                 .setCallingPackage(callingPackage)
3400                                 .setCallingFeatureId(callingFeatureId)
3401                                 .setCallingPid(Binder.getCallingPid())
3402                                 .setCallingUid(Binder.getCallingUid())
3403                                 .setMethod("getCellLocation")
3404                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
3405                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
3406                                 .build());
3407         switch (locationResult) {
3408             case DENIED_HARD:
3409                 throw new SecurityException("Not allowed to access cell location");
3410             case DENIED_SOFT:
3411                 return (getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
3412                         ? new CellIdentityCdma() : new CellIdentityGsm();
3413         }
3414 
3415         enforceTelephonyFeatureWithException(callingPackage,
3416                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getCellLocation");
3417 
3418         WorkSource workSource = getWorkSource(Binder.getCallingUid());
3419         final long identity = Binder.clearCallingIdentity();
3420         try {
3421             if (DBG_LOC) log("getCellLocation: is active user");
3422             int subId = SubscriptionManager.getDefaultDataSubscriptionId();
3423             return (CellIdentity) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
3424         } finally {
3425             Binder.restoreCallingIdentity(identity);
3426         }
3427     }
3428 
3429     @Override
getNetworkCountryIsoForPhone(int phoneId)3430     public String getNetworkCountryIsoForPhone(int phoneId) {
3431         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3432                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getNetworkCountryIsoForPhone");
3433 
3434         // Reporting the correct network country is ambiguous when IWLAN could conflict with
3435         // registered cell info, so return a NULL country instead.
3436         final long identity = Binder.clearCallingIdentity();
3437         try {
3438             if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
3439                 // Get default phone in this case.
3440                 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
3441             }
3442             final int subId = SubscriptionManager.getSubscriptionId(phoneId);
3443             Phone phone = PhoneFactory.getPhone(phoneId);
3444             if (phone == null) return "";
3445             ServiceStateTracker sst = phone.getServiceStateTracker();
3446             if (sst == null) return "";
3447             LocaleTracker lt = sst.getLocaleTracker();
3448             if (lt == null) return "";
3449             return lt.getCurrentCountry();
3450         } finally {
3451             Binder.restoreCallingIdentity(identity);
3452         }
3453     }
3454 
3455     /**
3456      * This method was removed due to potential issues caused by performing partial
3457      * updates of service state, and lack of a credible use case.
3458      *
3459      * This has the ability to break the telephony implementation by disabling notification of
3460      * changes in device connectivity. DO NOT USE THIS!
3461      */
3462     @Override
enableLocationUpdates()3463     public void enableLocationUpdates() {
3464         mApp.enforceCallingOrSelfPermission(
3465                 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
3466     }
3467 
3468     /**
3469      * This method was removed due to potential issues caused by performing partial
3470      * updates of service state, and lack of a credible use case.
3471      *
3472      * This has the ability to break the telephony implementation by disabling notification of
3473      * changes in device connectivity. DO NOT USE THIS!
3474      */
3475     @Override
disableLocationUpdates()3476     public void disableLocationUpdates() {
3477         mApp.enforceCallingOrSelfPermission(
3478                 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
3479     }
3480 
3481     @Override
3482     @SuppressWarnings("unchecked")
getNeighboringCellInfo(String callingPackage, String callingFeatureId)3483     public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage,
3484             String callingFeatureId) {
3485         try {
3486             mApp.getSystemService(AppOpsManager.class)
3487                     .checkPackage(Binder.getCallingUid(), callingPackage);
3488         } catch (SecurityException e) {
3489             EventLog.writeEvent(0x534e4554, "190619791", Binder.getCallingUid());
3490             throw e;
3491         }
3492 
3493         final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
3494         if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
3495             throw new SecurityException(
3496                     "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
3497         }
3498 
3499         if (mAppOps.noteOp(AppOpsManager.OPSTR_NEIGHBORING_CELLS, Binder.getCallingUid(),
3500                 callingPackage) != AppOpsManager.MODE_ALLOWED) {
3501             return null;
3502         }
3503 
3504         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3505                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getNeighboringCellInfo");
3506 
3507         if (DBG_LOC) log("getNeighboringCellInfo: is active user");
3508 
3509         List<CellInfo> info = getAllCellInfo(callingPackage, callingFeatureId);
3510         if (info == null) return null;
3511 
3512         List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
3513         for (CellInfo ci : info) {
3514             if (ci instanceof CellInfoGsm) {
3515                 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
3516             } else if (ci instanceof CellInfoWcdma) {
3517                 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
3518             }
3519         }
3520         return (neighbors.size()) > 0 ? neighbors : null;
3521     }
3522 
getCachedCellInfo()3523     private List<CellInfo> getCachedCellInfo() {
3524         List<CellInfo> cellInfos = new ArrayList<CellInfo>();
3525         for (Phone phone : PhoneFactory.getPhones()) {
3526             List<CellInfo> info = phone.getAllCellInfo();
3527             if (info != null) cellInfos.addAll(info);
3528         }
3529         return cellInfos;
3530     }
3531 
3532     @Override
getAllCellInfo(String callingPackage, String callingFeatureId)3533     public List<CellInfo> getAllCellInfo(String callingPackage, String callingFeatureId) {
3534         mApp.getSystemService(AppOpsManager.class)
3535                 .checkPackage(Binder.getCallingUid(), callingPackage);
3536 
3537         LocationAccessPolicy.LocationPermissionResult locationResult =
3538                 LocationAccessPolicy.checkLocationPermission(mApp,
3539                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
3540                                 .setCallingPackage(callingPackage)
3541                                 .setCallingFeatureId(callingFeatureId)
3542                                 .setCallingPid(Binder.getCallingPid())
3543                                 .setCallingUid(Binder.getCallingUid())
3544                                 .setMethod("getAllCellInfo")
3545                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
3546                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
3547                                 .build());
3548         switch (locationResult) {
3549             case DENIED_HARD:
3550                 throw new SecurityException("Not allowed to access cell info");
3551             case DENIED_SOFT:
3552                 return new ArrayList<>();
3553         }
3554 
3555         final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
3556         if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
3557             return getCachedCellInfo();
3558         }
3559 
3560         enforceTelephonyFeatureWithException(callingPackage,
3561                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getAllCellInfo");
3562 
3563         if (DBG_LOC) log("getAllCellInfo: is active user");
3564         WorkSource workSource = getWorkSource(Binder.getCallingUid());
3565         final long identity = Binder.clearCallingIdentity();
3566         try {
3567             List<CellInfo> cellInfos = new ArrayList<CellInfo>();
3568             for (Phone phone : PhoneFactory.getPhones()) {
3569                 final List<CellInfo> info = (List<CellInfo>) sendRequest(
3570                         CMD_GET_ALL_CELL_INFO, null, phone, workSource);
3571                 if (info != null) cellInfos.addAll(info);
3572             }
3573             return cellInfos;
3574         } finally {
3575             Binder.restoreCallingIdentity(identity);
3576         }
3577     }
3578 
3579     @Override
requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage, String callingFeatureId)3580     public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage,
3581             String callingFeatureId) {
3582         requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId,
3583                 getWorkSource(Binder.getCallingUid()));
3584     }
3585 
3586     @Override
requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb, String callingPackage, String callingFeatureId, WorkSource workSource)3587     public void requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb,
3588             String callingPackage, String callingFeatureId, WorkSource workSource) {
3589         enforceModifyPermission();
3590         requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId, workSource);
3591     }
3592 
requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb, String callingPackage, String callingFeatureId, WorkSource workSource)3593     private void requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb,
3594             String callingPackage, String callingFeatureId, WorkSource workSource) {
3595         mApp.getSystemService(AppOpsManager.class)
3596                 .checkPackage(Binder.getCallingUid(), callingPackage);
3597 
3598         LocationAccessPolicy.LocationPermissionResult locationResult =
3599                 LocationAccessPolicy.checkLocationPermission(mApp,
3600                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
3601                                 .setCallingPackage(callingPackage)
3602                                 .setCallingFeatureId(callingFeatureId)
3603                                 .setCallingPid(Binder.getCallingPid())
3604                                 .setCallingUid(Binder.getCallingUid())
3605                                 .setMethod("requestCellInfoUpdate")
3606                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
3607                                 .setMinSdkVersionForFine(Build.VERSION_CODES.BASE)
3608                                 .build());
3609         switch (locationResult) {
3610             case DENIED_HARD:
3611                 if (TelephonyPermissions
3612                         .getTargetSdk(mApp, callingPackage) < Build.VERSION_CODES.Q) {
3613                     // Safetynet logging for b/154934934
3614                     EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
3615                 }
3616                 throw new SecurityException("Not allowed to access cell info");
3617             case DENIED_SOFT:
3618                 if (TelephonyPermissions
3619                         .getTargetSdk(mApp, callingPackage) < Build.VERSION_CODES.Q) {
3620                     // Safetynet logging for b/154934934
3621                     EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
3622                 }
3623                 try {
3624                     cb.onCellInfo(new ArrayList<CellInfo>());
3625                 } catch (RemoteException re) {
3626                     // Drop without consequences
3627                 }
3628                 return;
3629         }
3630 
3631         enforceTelephonyFeatureWithException(callingPackage,
3632                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "requestCellInfoUpdateInternal");
3633 
3634         final Phone phone = getPhoneFromSubId(subId);
3635         if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
3636 
3637         sendRequestAsync(CMD_REQUEST_CELL_INFO_UPDATE, cb, phone, workSource);
3638     }
3639 
3640     @Override
setCellInfoListRate(int rateInMillis, int subId)3641     public void setCellInfoListRate(int rateInMillis, int subId) {
3642         enforceModifyPermission();
3643         WorkSource workSource = getWorkSource(Binder.getCallingUid());
3644 
3645         final long identity = Binder.clearCallingIdentity();
3646         try {
3647             Phone phone = getPhone(subId);
3648             if (phone == null) {
3649                 getDefaultPhone().setCellInfoListRate(rateInMillis, workSource);
3650             } else {
3651                 phone.setCellInfoListRate(rateInMillis, workSource);
3652             }
3653         } finally {
3654             Binder.restoreCallingIdentity(identity);
3655         }
3656     }
3657 
3658     @Override
getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId)3659     public String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
3660         Phone phone = PhoneFactory.getPhone(slotIndex);
3661         if (phone == null) {
3662             return null;
3663         }
3664         int subId = phone.getSubId();
3665         enforceCallingPackage(callingPackage, Binder.getCallingUid(), "getImeiForSlot");
3666         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
3667                 callingPackage, callingFeatureId, "getImeiForSlot")) {
3668             return null;
3669         }
3670 
3671         enforceTelephonyFeatureWithException(callingPackage,
3672                 PackageManager.FEATURE_TELEPHONY_GSM, "getImeiForSlot");
3673 
3674         final long identity = Binder.clearCallingIdentity();
3675         try {
3676             return phone.getImei();
3677         } finally {
3678             Binder.restoreCallingIdentity(identity);
3679         }
3680     }
3681 
3682     @Override
getPrimaryImei(String callingPackage, String callingFeatureId)3683     public String getPrimaryImei(String callingPackage, String callingFeatureId) {
3684         enforceCallingPackage(callingPackage, Binder.getCallingUid(), "getPrimaryImei");
3685         if (!checkCallingOrSelfReadDeviceIdentifiersForAnySub(mApp, callingPackage,
3686                 callingFeatureId, "getPrimaryImei")) {
3687             throw new SecurityException("Caller does not have permission");
3688         }
3689 
3690         enforceTelephonyFeatureWithException(callingPackage,
3691                 PackageManager.FEATURE_TELEPHONY_GSM, "getPrimaryImei");
3692 
3693         final long identity = Binder.clearCallingIdentity();
3694         try {
3695             for (Phone phone : PhoneFactory.getPhones()) {
3696                 if (phone.getImeiType() == Phone.IMEI_TYPE_PRIMARY) {
3697                     return phone.getImei();
3698                 }
3699             }
3700             throw new UnsupportedOperationException("Operation not supported");
3701         } finally {
3702             Binder.restoreCallingIdentity(identity);
3703         }
3704     }
3705 
3706     @Override
getTypeAllocationCodeForSlot(int slotIndex)3707     public String getTypeAllocationCodeForSlot(int slotIndex) {
3708         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3709                 PackageManager.FEATURE_TELEPHONY_GSM, "getTypeAllocationCodeForSlot");
3710 
3711         Phone phone = PhoneFactory.getPhone(slotIndex);
3712         String tac = null;
3713         if (phone != null) {
3714             String imei = phone.getImei();
3715             try {
3716                 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
3717             } catch (IndexOutOfBoundsException e) {
3718                 Log.e(LOG_TAG, "IMEI length shorter than upper index.");
3719                 return null;
3720             }
3721         }
3722         return tac;
3723     }
3724 
3725     @Override
getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId)3726     public String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
3727         try {
3728             mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3729         } catch (SecurityException se) {
3730             EventLog.writeEvent(0x534e4554, "186530496", Binder.getCallingUid());
3731             throw new SecurityException("Package " + callingPackage + " does not belong to "
3732                     + Binder.getCallingUid());
3733         }
3734         Phone phone = PhoneFactory.getPhone(slotIndex);
3735         if (phone == null) {
3736             return null;
3737         }
3738 
3739         int subId = phone.getSubId();
3740         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
3741                 callingPackage, callingFeatureId, "getMeidForSlot")) {
3742             return null;
3743         }
3744 
3745         enforceTelephonyFeatureWithException(callingPackage,
3746                 PackageManager.FEATURE_TELEPHONY_CDMA, "getMeidForSlot");
3747 
3748         final long identity = Binder.clearCallingIdentity();
3749         try {
3750             return phone.getMeid();
3751         } finally {
3752             Binder.restoreCallingIdentity(identity);
3753         }
3754     }
3755 
3756     @Override
getManufacturerCodeForSlot(int slotIndex)3757     public String getManufacturerCodeForSlot(int slotIndex) {
3758         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3759                 PackageManager.FEATURE_TELEPHONY_CDMA, "getManufacturerCodeForSlot");
3760 
3761         Phone phone = PhoneFactory.getPhone(slotIndex);
3762         String manufacturerCode = null;
3763         if (phone != null) {
3764             String meid = phone.getMeid();
3765             try {
3766                 manufacturerCode =
3767                         meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
3768             } catch (IndexOutOfBoundsException e) {
3769                 Log.e(LOG_TAG, "MEID length shorter than upper index.");
3770                 return null;
3771             }
3772         }
3773         return manufacturerCode;
3774     }
3775 
3776     @Override
getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage, String callingFeatureId)3777     public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage,
3778             String callingFeatureId) {
3779         Phone phone = PhoneFactory.getPhone(slotIndex);
3780         if (phone == null) {
3781             return null;
3782         }
3783         int subId = phone.getSubId();
3784         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3785                 mApp, subId, callingPackage, callingFeatureId,
3786                 "getDeviceSoftwareVersionForSlot")) {
3787             return null;
3788         }
3789 
3790         enforceTelephonyFeatureWithException(callingPackage,
3791                 PackageManager.FEATURE_TELEPHONY, "getDeviceSoftwareVersionForSlot");
3792 
3793         final long identity = Binder.clearCallingIdentity();
3794         try {
3795             return phone.getDeviceSvn();
3796         } finally {
3797             Binder.restoreCallingIdentity(identity);
3798         }
3799     }
3800 
3801     @Override
getSubscriptionCarrierId(int subId)3802     public int getSubscriptionCarrierId(int subId) {
3803         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3804                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSubscriptionCarrierId");
3805 
3806         final long identity = Binder.clearCallingIdentity();
3807         try {
3808             final Phone phone = getPhone(subId);
3809             return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
3810         } finally {
3811             Binder.restoreCallingIdentity(identity);
3812         }
3813     }
3814 
3815     @Override
getSubscriptionCarrierName(int subId)3816     public String getSubscriptionCarrierName(int subId) {
3817         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3818                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSubscriptionCarrierName");
3819 
3820         final long identity = Binder.clearCallingIdentity();
3821         try {
3822             final Phone phone = getPhone(subId);
3823             return phone == null ? null : phone.getCarrierName();
3824         } finally {
3825             Binder.restoreCallingIdentity(identity);
3826         }
3827     }
3828 
3829     @Override
getSubscriptionSpecificCarrierId(int subId)3830     public int getSubscriptionSpecificCarrierId(int subId) {
3831         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3832                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSubscriptionSpecificCarrierId");
3833 
3834         final long identity = Binder.clearCallingIdentity();
3835         try {
3836             final Phone phone = getPhone(subId);
3837             return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
3838                     : phone.getSpecificCarrierId();
3839         } finally {
3840             Binder.restoreCallingIdentity(identity);
3841         }
3842     }
3843 
3844     @Override
getSubscriptionSpecificCarrierName(int subId)3845     public String getSubscriptionSpecificCarrierName(int subId) {
3846         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3847                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
3848                 "getSubscriptionSpecificCarrierName");
3849 
3850         final long identity = Binder.clearCallingIdentity();
3851         try {
3852             final Phone phone = getPhone(subId);
3853             return phone == null ? null : phone.getSpecificCarrierName();
3854         } finally {
3855             Binder.restoreCallingIdentity(identity);
3856         }
3857     }
3858 
3859     @Override
getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc)3860     public int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc) {
3861         if (!isSubscriptionMccMnc) {
3862             enforceReadPrivilegedPermission("getCarrierIdFromMccMnc");
3863         }
3864         final Phone phone = PhoneFactory.getPhone(slotIndex);
3865         if (phone == null) {
3866             return TelephonyManager.UNKNOWN_CARRIER_ID;
3867         }
3868 
3869         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3870                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getCarrierIdFromMccMnc");
3871 
3872         final long identity = Binder.clearCallingIdentity();
3873         try {
3874             return CarrierResolver.getCarrierIdFromMccMnc(phone.getContext(), mccmnc);
3875         } finally {
3876             Binder.restoreCallingIdentity(identity);
3877         }
3878     }
3879 
3880     //
3881     // Internal helper methods.
3882     //
3883 
3884     /**
3885      * Make sure the caller is the calling package itself
3886      *
3887      * @throws SecurityException if the caller is not the calling package
3888      */
enforceCallingPackage(String callingPackage, int callingUid, String message)3889     private void enforceCallingPackage(String callingPackage, int callingUid, String message) {
3890         int packageUid = -1;
3891         PackageManager pm = mApp.getBaseContext().createContextAsUser(
3892                 UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager();
3893         try {
3894             packageUid = pm.getPackageUid(callingPackage, 0);
3895         } catch (PackageManager.NameNotFoundException e) {
3896             // packageUid is -1
3897         }
3898         if (packageUid != callingUid) {
3899             throw new SecurityException(message + ": Package " + callingPackage
3900                     + " does not belong to " + callingUid);
3901         }
3902     }
3903 
3904     /**
3905      * Make sure the caller has the MODIFY_PHONE_STATE permission.
3906      *
3907      * @throws SecurityException if the caller does not have the required permission
3908      */
3909     @VisibleForTesting
enforceModifyPermission()3910     public void enforceModifyPermission() {
3911         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
3912     }
3913 
3914     /**
3915      * Make sure the caller has the READ_PHONE_STATE permission.
3916      *
3917      * @throws SecurityException if the caller does not have the required permission
3918      */
3919     @VisibleForTesting
enforceReadPermission()3920     public void enforceReadPermission() {
3921         enforceReadPermission(null);
3922     }
3923 
3924     /**
3925      * Make sure the caller has the READ_PHONE_STATE permissions.
3926      *
3927      * @throws SecurityException if the caller does not have the READ_PHONE_STATE permission.
3928      */
3929     @VisibleForTesting
enforceReadPermission(String msg)3930     public void enforceReadPermission(String msg) {
3931         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE, msg);
3932     }
3933 
enforceActiveEmergencySessionPermission()3934     private void enforceActiveEmergencySessionPermission() {
3935         mApp.enforceCallingOrSelfPermission(
3936                 android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
3937     }
3938 
3939     /**
3940      * Make sure the caller has the CALL_PHONE permission.
3941      *
3942      * @throws SecurityException if the caller does not have the required permission
3943      */
enforceCallPermission()3944     private void enforceCallPermission() {
3945         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
3946     }
3947 
enforceSettingsPermission()3948     private void enforceSettingsPermission() {
3949         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS, null);
3950     }
3951 
enforceRebootPermission()3952     private void enforceRebootPermission() {
3953         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
3954     }
3955 
3956     /**
3957      * Make sure the caller has SATELLITE_COMMUNICATION permission.
3958      * @param message - log message to print.
3959      * @throws SecurityException if the caller does not have the required permission
3960      */
enforceSatelliteCommunicationPermission(String message)3961     private void enforceSatelliteCommunicationPermission(String message) {
3962         mApp.enforceCallingOrSelfPermission(permission.SATELLITE_COMMUNICATION, message);
3963     }
3964 
3965     /**
3966      * Make sure the caller has PACKAGE_USAGE_STATS permission.
3967      * @param message - log message to print.
3968      * @throws SecurityException if the caller does not have the required permission
3969      */
enforcePackageUsageStatsPermission(String message)3970     private void enforcePackageUsageStatsPermission(String message) {
3971         mApp.enforceCallingOrSelfPermission(permission.PACKAGE_USAGE_STATS, message);
3972     }
3973 
createTelUrl(String number)3974     private String createTelUrl(String number) {
3975         if (TextUtils.isEmpty(number)) {
3976             return null;
3977         }
3978 
3979         return "tel:" + number;
3980     }
3981 
log(String msg)3982     private static void log(String msg) {
3983         Log.d(LOG_TAG, msg);
3984     }
3985 
logv(String msg)3986     private static void logv(String msg) {
3987         Log.v(LOG_TAG, msg);
3988     }
3989 
loge(String msg)3990     private static void loge(String msg) {
3991         Log.e(LOG_TAG, msg);
3992     }
3993 
3994     @Override
getActivePhoneType()3995     public int getActivePhoneType() {
3996         return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
3997     }
3998 
3999     @Override
getActivePhoneTypeForSlot(int slotIndex)4000     public int getActivePhoneTypeForSlot(int slotIndex) {
4001         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4002                 PackageManager.FEATURE_TELEPHONY, "getActivePhoneTypeForSlot");
4003 
4004         final long identity = Binder.clearCallingIdentity();
4005         try {
4006             final Phone phone = PhoneFactory.getPhone(slotIndex);
4007             if (phone == null) {
4008                 return PhoneConstants.PHONE_TYPE_NONE;
4009             } else {
4010                 return phone.getPhoneType();
4011             }
4012         } finally {
4013             Binder.restoreCallingIdentity(identity);
4014         }
4015     }
4016 
4017     /**
4018      * Returns the CDMA ERI icon index to display
4019      */
4020     @Override
getCdmaEriIconIndex(String callingPackage, String callingFeatureId)4021     public int getCdmaEriIconIndex(String callingPackage, String callingFeatureId) {
4022         return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage,
4023                 callingFeatureId);
4024     }
4025 
4026     @Override
getCdmaEriIconIndexForSubscriber(int subId, String callingPackage, String callingFeatureId)4027     public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
4028             String callingFeatureId) {
4029         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4030                 mApp, subId, callingPackage, callingFeatureId,
4031                 "getCdmaEriIconIndexForSubscriber")) {
4032             return -1;
4033         }
4034 
4035         enforceTelephonyFeatureWithException(callingPackage,
4036                 PackageManager.FEATURE_TELEPHONY_CDMA,
4037                 "getCdmaEriIconIndexForSubscriber");
4038 
4039         final long identity = Binder.clearCallingIdentity();
4040         try {
4041             final Phone phone = getPhone(subId);
4042             if (phone != null) {
4043                 return phone.getCdmaEriIconIndex();
4044             } else {
4045                 return -1;
4046             }
4047         } finally {
4048             Binder.restoreCallingIdentity(identity);
4049         }
4050     }
4051 
4052     /**
4053      * Returns the CDMA ERI icon mode,
4054      * 0 - ON
4055      * 1 - FLASHING
4056      */
4057     @Override
getCdmaEriIconMode(String callingPackage, String callingFeatureId)4058     public int getCdmaEriIconMode(String callingPackage, String callingFeatureId) {
4059         return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage,
4060                 callingFeatureId);
4061     }
4062 
4063     @Override
getCdmaEriIconModeForSubscriber(int subId, String callingPackage, String callingFeatureId)4064     public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
4065             String callingFeatureId) {
4066         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4067                 mApp, subId, callingPackage, callingFeatureId,
4068                 "getCdmaEriIconModeForSubscriber")) {
4069             return -1;
4070         }
4071 
4072         final long identity = Binder.clearCallingIdentity();
4073         try {
4074             final Phone phone = getPhone(subId);
4075             if (phone != null) {
4076                 return phone.getCdmaEriIconMode();
4077             } else {
4078                 return -1;
4079             }
4080         } finally {
4081             Binder.restoreCallingIdentity(identity);
4082         }
4083     }
4084 
4085     /**
4086      * Returns the CDMA ERI text,
4087      */
4088     @Override
getCdmaEriText(String callingPackage, String callingFeatureId)4089     public String getCdmaEriText(String callingPackage, String callingFeatureId) {
4090         return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage,
4091                 callingFeatureId);
4092     }
4093 
4094     @Override
getCdmaEriTextForSubscriber(int subId, String callingPackage, String callingFeatureId)4095     public String getCdmaEriTextForSubscriber(int subId, String callingPackage,
4096             String callingFeatureId) {
4097         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4098                 mApp, subId, callingPackage, callingFeatureId,
4099                 "getCdmaEriIconTextForSubscriber")) {
4100             return null;
4101         }
4102 
4103         final long identity = Binder.clearCallingIdentity();
4104         try {
4105             final Phone phone = getPhone(subId);
4106             if (phone != null) {
4107                 return phone.getCdmaEriText();
4108             } else {
4109                 return null;
4110             }
4111         } finally {
4112             Binder.restoreCallingIdentity(identity);
4113         }
4114     }
4115 
4116     /**
4117      * Returns the CDMA MDN.
4118      */
4119     @Override
getCdmaMdn(int subId)4120     public String getCdmaMdn(int subId) {
4121         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4122                 mApp, subId, "getCdmaMdn");
4123 
4124         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4125                 PackageManager.FEATURE_TELEPHONY_CDMA, "getCdmaMdn");
4126 
4127         final long identity = Binder.clearCallingIdentity();
4128         try {
4129             final Phone phone = getPhone(subId);
4130             if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
4131                 return phone.getLine1Number();
4132             } else {
4133                 loge("getCdmaMdn: no phone found. Invalid subId: " + subId);
4134                 return null;
4135             }
4136         } finally {
4137             Binder.restoreCallingIdentity(identity);
4138         }
4139     }
4140 
4141     /**
4142      * Returns the CDMA MIN.
4143      */
4144     @Override
getCdmaMin(int subId)4145     public String getCdmaMin(int subId) {
4146         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4147                 mApp, subId, "getCdmaMin");
4148 
4149         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4150                 PackageManager.FEATURE_TELEPHONY_CDMA, "getCdmaMin");
4151 
4152         final long identity = Binder.clearCallingIdentity();
4153         try {
4154             final Phone phone = getPhone(subId);
4155             if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
4156                 return phone.getCdmaMin();
4157             } else {
4158                 return null;
4159             }
4160         } finally {
4161             Binder.restoreCallingIdentity(identity);
4162         }
4163     }
4164 
4165     @Override
requestNumberVerification(PhoneNumberRange range, long timeoutMillis, INumberVerificationCallback callback, String callingPackage)4166     public void requestNumberVerification(PhoneNumberRange range, long timeoutMillis,
4167             INumberVerificationCallback callback, String callingPackage) {
4168         if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
4169                 != PERMISSION_GRANTED) {
4170             throw new SecurityException("Caller must hold the MODIFY_PHONE_STATE permission");
4171         }
4172         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4173 
4174         String authorizedPackage = NumberVerificationManager.getAuthorizedPackage(mApp);
4175         if (!TextUtils.equals(callingPackage, authorizedPackage)) {
4176             throw new SecurityException("Calling package must be configured in the device config: "
4177                     + "calling package: " + callingPackage
4178                     + ", configured package: " + authorizedPackage);
4179         }
4180 
4181         enforceTelephonyFeatureWithException(callingPackage,
4182                 PackageManager.FEATURE_TELEPHONY_CALLING, "requestNumberVerification");
4183 
4184         if (range == null) {
4185             throw new NullPointerException("Range must be non-null");
4186         }
4187 
4188         timeoutMillis = Math.min(timeoutMillis,
4189                 TelephonyManager.getMaxNumberVerificationTimeoutMillis());
4190 
4191         NumberVerificationManager.getInstance().requestVerification(range, callback, timeoutMillis);
4192     }
4193 
4194     /**
4195      * Returns true if CDMA provisioning needs to run.
4196      */
needsOtaServiceProvisioning()4197     public boolean needsOtaServiceProvisioning() {
4198         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4199                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "needsOtaServiceProvisioning");
4200 
4201         final long identity = Binder.clearCallingIdentity();
4202         try {
4203             return getDefaultPhone().needsOtaServiceProvisioning();
4204         } finally {
4205             Binder.restoreCallingIdentity(identity);
4206         }
4207     }
4208 
4209     /**
4210      * Sets the voice mail number of a given subId.
4211      */
4212     @Override
setVoiceMailNumber(int subId, String alphaTag, String number)4213     public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
4214         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
4215                 mApp, subId, "setVoiceMailNumber");
4216 
4217         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4218                 PackageManager.FEATURE_TELEPHONY_CALLING, "setVoiceMailNumber");
4219 
4220         final long identity = Binder.clearCallingIdentity();
4221         try {
4222             Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
4223                     new Pair<String, String>(alphaTag, number), new Integer(subId));
4224             return success;
4225         } finally {
4226             Binder.restoreCallingIdentity(identity);
4227         }
4228     }
4229 
4230     @Override
getVisualVoicemailSettings(String callingPackage, int subId)4231     public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
4232         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4233         TelecomManager tm = mApp.getSystemService(TelecomManager.class);
4234         String systemDialer = tm.getSystemDialerPackage();
4235         if (!TextUtils.equals(callingPackage, systemDialer)) {
4236             throw new SecurityException("caller must be system dialer");
4237         }
4238 
4239         enforceTelephonyFeatureWithException(callingPackage,
4240                 PackageManager.FEATURE_TELEPHONY_CALLING, "getVisualVoicemailSettings");
4241 
4242         final long identity = Binder.clearCallingIdentity();
4243         try {
4244             PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
4245             if (phoneAccountHandle == null) {
4246                 return null;
4247             }
4248             return VisualVoicemailSettingsUtil.dump(mApp, phoneAccountHandle);
4249         } finally {
4250             Binder.restoreCallingIdentity(identity);
4251         }
4252     }
4253 
4254     @Override
getVisualVoicemailPackageName(String callingPackage, String callingFeatureId, int subId)4255     public String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId,
4256             int subId) {
4257         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4258         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4259                 mApp, subId, callingPackage, callingFeatureId,
4260                 "getVisualVoicemailPackageName")) {
4261             return null;
4262         }
4263 
4264         enforceTelephonyFeatureWithException(callingPackage,
4265                 PackageManager.FEATURE_TELEPHONY_CALLING, "getVisualVoicemailPackageName");
4266 
4267         final long identity = Binder.clearCallingIdentity();
4268         try {
4269             return RemoteVvmTaskManager.getRemotePackage(mApp, subId).getPackageName();
4270         } finally {
4271             Binder.restoreCallingIdentity(identity);
4272         }
4273     }
4274 
4275     @Override
enableVisualVoicemailSmsFilter(String callingPackage, int subId, VisualVoicemailSmsFilterSettings settings)4276     public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
4277             VisualVoicemailSmsFilterSettings settings) {
4278         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4279 
4280         enforceTelephonyFeatureWithException(callingPackage,
4281                 PackageManager.FEATURE_TELEPHONY_CALLING, "enableVisualVoicemailSmsFilter");
4282 
4283         final long identity = Binder.clearCallingIdentity();
4284         try {
4285             VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
4286                     mApp, callingPackage, subId, settings);
4287         } finally {
4288             Binder.restoreCallingIdentity(identity);
4289         }
4290     }
4291 
4292     @Override
disableVisualVoicemailSmsFilter(String callingPackage, int subId)4293     public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
4294         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4295 
4296         enforceTelephonyFeatureWithException(callingPackage,
4297                 PackageManager.FEATURE_TELEPHONY_CALLING, "disableVisualVoicemailSmsFilter");
4298 
4299         final long identity = Binder.clearCallingIdentity();
4300         try {
4301             VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
4302                     mApp, callingPackage, subId);
4303         } finally {
4304             Binder.restoreCallingIdentity(identity);
4305         }
4306     }
4307 
4308     @Override
getVisualVoicemailSmsFilterSettings( String callingPackage, int subId)4309     public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
4310             String callingPackage, int subId) {
4311         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4312 
4313         final long identity = Binder.clearCallingIdentity();
4314         try {
4315             return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
4316                     mApp, callingPackage, subId);
4317         } finally {
4318             Binder.restoreCallingIdentity(identity);
4319         }
4320     }
4321 
4322     @Override
getActiveVisualVoicemailSmsFilterSettings(int subId)4323     public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
4324         enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
4325 
4326         final long identity = Binder.clearCallingIdentity();
4327         try {
4328             return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
4329                     mApp, subId);
4330         } finally {
4331             Binder.restoreCallingIdentity(identity);
4332         }
4333     }
4334 
4335     @Override
sendVisualVoicemailSmsForSubscriber(String callingPackage, String callingAttributionTag, int subId, String number, int port, String text, PendingIntent sentIntent)4336     public void sendVisualVoicemailSmsForSubscriber(String callingPackage,
4337             String callingAttributionTag, int subId, String number, int port, String text,
4338             PendingIntent sentIntent) {
4339         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4340         enforceVisualVoicemailPackage(callingPackage, subId);
4341         enforceSendSmsPermission();
4342 
4343         enforceTelephonyFeatureWithException(callingPackage,
4344                 PackageManager.FEATURE_TELEPHONY_CALLING, "sendVisualVoicemailSmsForSubscriber");
4345 
4346         SmsController smsController = PhoneFactory.getSmsController();
4347         smsController.sendVisualVoicemailSmsForSubscriber(callingPackage, callingAttributionTag,
4348                 subId, number, port, text, sentIntent);
4349     }
4350 
4351     /**
4352      * Sets the voice activation state of a given subId.
4353      */
4354     @Override
setVoiceActivationState(int subId, int activationState)4355     public void setVoiceActivationState(int subId, int activationState) {
4356         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4357                 mApp, subId, "setVoiceActivationState");
4358 
4359         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4360                 PackageManager.FEATURE_TELEPHONY_CALLING, "setVoiceActivationState");
4361 
4362         final long identity = Binder.clearCallingIdentity();
4363         try {
4364             final Phone phone = getPhone(subId);
4365             if (phone != null) {
4366                 phone.setVoiceActivationState(activationState);
4367             } else {
4368                 loge("setVoiceActivationState fails with invalid subId: " + subId);
4369             }
4370         } finally {
4371             Binder.restoreCallingIdentity(identity);
4372         }
4373     }
4374 
4375     /**
4376      * Sets the data activation state of a given subId.
4377      */
4378     @Override
setDataActivationState(int subId, int activationState)4379     public void setDataActivationState(int subId, int activationState) {
4380         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4381                 mApp, subId, "setDataActivationState");
4382 
4383         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4384                 PackageManager.FEATURE_TELEPHONY_DATA, "setDataActivationState");
4385 
4386         final long identity = Binder.clearCallingIdentity();
4387         try {
4388             final Phone phone = getPhone(subId);
4389             if (phone != null) {
4390                 phone.setDataActivationState(activationState);
4391             } else {
4392                 loge("setDataActivationState fails with invalid subId: " + subId);
4393             }
4394         } finally {
4395             Binder.restoreCallingIdentity(identity);
4396         }
4397     }
4398 
4399     /**
4400      * Returns the voice activation state of a given subId.
4401      */
4402     @Override
getVoiceActivationState(int subId, String callingPackage)4403     public int getVoiceActivationState(int subId, String callingPackage) {
4404         enforceReadPrivilegedPermission("getVoiceActivationState");
4405 
4406         enforceTelephonyFeatureWithException(callingPackage,
4407                 PackageManager.FEATURE_TELEPHONY_CALLING, "getVoiceActivationState");
4408 
4409         final Phone phone = getPhone(subId);
4410         final long identity = Binder.clearCallingIdentity();
4411         try {
4412             if (phone != null) {
4413                 return phone.getVoiceActivationState();
4414             } else {
4415                 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
4416             }
4417         } finally {
4418             Binder.restoreCallingIdentity(identity);
4419         }
4420     }
4421 
4422     /**
4423      * Returns the data activation state of a given subId.
4424      */
4425     @Override
getDataActivationState(int subId, String callingPackage)4426     public int getDataActivationState(int subId, String callingPackage) {
4427         enforceReadPrivilegedPermission("getDataActivationState");
4428 
4429         enforceTelephonyFeatureWithException(callingPackage,
4430                 PackageManager.FEATURE_TELEPHONY_DATA, "getDataActivationState");
4431 
4432         final Phone phone = getPhone(subId);
4433         final long identity = Binder.clearCallingIdentity();
4434         try {
4435             if (phone != null) {
4436                 return phone.getDataActivationState();
4437             } else {
4438                 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
4439             }
4440         } finally {
4441             Binder.restoreCallingIdentity(identity);
4442         }
4443     }
4444 
4445     /**
4446      * Returns the unread count of voicemails for a subId
4447      */
4448     @Override
getVoiceMessageCountForSubscriber(int subId, String callingPackage, String callingFeatureId)4449     public int getVoiceMessageCountForSubscriber(int subId, String callingPackage,
4450             String callingFeatureId) {
4451         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4452                 mApp, subId, callingPackage, callingFeatureId,
4453                 "getVoiceMessageCountForSubscriber")) {
4454             return 0;
4455         }
4456         final long identity = Binder.clearCallingIdentity();
4457         try {
4458             final Phone phone = getPhone(subId);
4459             if (phone != null) {
4460                 return phone.getVoiceMessageCount();
4461             } else {
4462                 return 0;
4463             }
4464         } finally {
4465             Binder.restoreCallingIdentity(identity);
4466         }
4467     }
4468 
4469     /**
4470      * returns true, if the device is in a state where both voice and data
4471      * are supported simultaneously. This can change based on location or network condition.
4472      */
4473     @Override
isConcurrentVoiceAndDataAllowed(int subId)4474     public boolean isConcurrentVoiceAndDataAllowed(int subId) {
4475         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4476                 PackageManager.FEATURE_TELEPHONY_DATA, "isConcurrentVoiceAndDataAllowed");
4477 
4478         final long identity = Binder.clearCallingIdentity();
4479         try {
4480             return getPhoneFromSubIdOrDefault(subId).isConcurrentVoiceAndDataAllowed();
4481         } finally {
4482             Binder.restoreCallingIdentity(identity);
4483         }
4484     }
4485 
4486     /**
4487      * Send the dialer code if called from the current default dialer or the caller has
4488      * carrier privilege.
4489      * @param inputCode The dialer code to send
4490      */
4491     @Override
sendDialerSpecialCode(String callingPackage, String inputCode)4492     public void sendDialerSpecialCode(String callingPackage, String inputCode) {
4493         final Phone defaultPhone = getDefaultPhone();
4494         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4495         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
4496         String defaultDialer = tm.getDefaultDialerPackage();
4497         if (!TextUtils.equals(callingPackage, defaultDialer)) {
4498             TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
4499                     getDefaultSubscription(), "sendDialerSpecialCode");
4500         }
4501 
4502         enforceTelephonyFeatureWithException(callingPackage,
4503                 PackageManager.FEATURE_TELEPHONY_CALLING, "sendDialerSpecialCode");
4504 
4505         final long identity = Binder.clearCallingIdentity();
4506         try {
4507             defaultPhone.sendDialerSpecialCode(inputCode);
4508         } finally {
4509             Binder.restoreCallingIdentity(identity);
4510         }
4511     }
4512 
4513     @Override
getNetworkSelectionMode(int subId)4514     public int getNetworkSelectionMode(int subId) {
4515         TelephonyPermissions
4516                 .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4517                         mApp, subId, "getNetworkSelectionMode");
4518 
4519         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4520                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getNetworkSelectionMode");
4521 
4522         final long identity = Binder.clearCallingIdentity();
4523         try {
4524             if (!isActiveSubscription(subId)) {
4525                 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
4526             }
4527             return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
4528         } finally {
4529             Binder.restoreCallingIdentity(identity);
4530         }
4531     }
4532 
4533     @Override
isInEmergencySmsMode()4534     public boolean isInEmergencySmsMode() {
4535         enforceReadPrivilegedPermission("isInEmergencySmsMode");
4536 
4537         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4538                 PackageManager.FEATURE_TELEPHONY_MESSAGING, "isInEmergencySmsMode");
4539 
4540         final long identity = Binder.clearCallingIdentity();
4541         try {
4542             for (Phone phone : PhoneFactory.getPhones()) {
4543                 if (phone.isInEmergencySmsMode()) {
4544                     return true;
4545                 }
4546             }
4547         } finally {
4548             Binder.restoreCallingIdentity(identity);
4549         }
4550         return false;
4551     }
4552 
4553     /**
4554      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4555      * @param subId The subscription to use to check the configuration.
4556      * @param c The callback that will be used to send the result.
4557      */
4558     @Override
registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)4559     public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)
4560             throws RemoteException {
4561         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4562                 mApp, subId, "registerImsRegistrationCallback");
4563 
4564         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4565             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4566                     "IMS not available on device.");
4567         }
4568         final long token = Binder.clearCallingIdentity();
4569         try {
4570             int slotId = getSlotIndexOrException(subId);
4571             verifyImsMmTelConfiguredOrThrow(slotId);
4572 
4573             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4574             if (controller != null) {
4575                 ImsManager imsManager = controller.getImsManager(subId);
4576                 if (imsManager != null) {
4577                     imsManager.addRegistrationCallbackForSubscription(c, subId);
4578                 } else {
4579                     throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
4580                 }
4581             } else {
4582                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
4583             }
4584         } catch (ImsException e) {
4585             throw new ServiceSpecificException(e.getCode());
4586         } finally {
4587             Binder.restoreCallingIdentity(token);
4588         }
4589     }
4590 
4591     /**
4592      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4593      * @param subId The subscription to use to check the configuration.
4594      * @param c The callback that will be used to send the result.
4595      */
4596     @Override
unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c)4597     public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c) {
4598         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4599                 mApp, subId, "unregisterImsRegistrationCallback");
4600         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4601             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
4602         }
4603         final long token = Binder.clearCallingIdentity();
4604 
4605         try {
4606             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4607             if (controller != null) {
4608                 ImsManager imsManager = controller.getImsManager(subId);
4609                 if (imsManager != null) {
4610                     imsManager.removeRegistrationCallbackForSubscription(c, subId);
4611                 } else {
4612                     Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
4613                             + "is inactive, ignoring unregister.");
4614                     // If the ImsManager is not valid, just return, since the callback
4615                     // will already have been removed internally.
4616                 }
4617             }
4618         } finally {
4619             Binder.restoreCallingIdentity(token);
4620         }
4621     }
4622 
4623     /**
4624      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4625      * @param subId The subscription to use to check the configuration.
4626      * @param c The callback that will be used to send the result.
4627      */
4628     @Override
registerImsEmergencyRegistrationCallback(int subId, IImsRegistrationCallback c)4629     public void registerImsEmergencyRegistrationCallback(int subId, IImsRegistrationCallback c)
4630             throws RemoteException {
4631         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4632                 mApp, subId, "registerImsEmergencyRegistrationCallback");
4633 
4634         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4635             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4636                     "IMS not available on device.");
4637         }
4638         final long token = Binder.clearCallingIdentity();
4639         try {
4640             int slotId = getSlotIndexOrException(subId);
4641             verifyImsMmTelConfiguredOrThrow(slotId);
4642 
4643             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4644             if (controller != null) {
4645                 ImsManager imsManager = controller.getImsManager(subId);
4646                 if (imsManager != null) {
4647                     imsManager.addEmergencyRegistrationCallbackForSubscription(c, subId);
4648                 } else {
4649                     throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
4650                 }
4651             } else {
4652                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
4653             }
4654         } catch (ImsException e) {
4655             throw new ServiceSpecificException(e.getCode());
4656         } finally {
4657             Binder.restoreCallingIdentity(token);
4658         }
4659     }
4660 
4661     /**
4662      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4663      * @param subId The subscription to use to check the configuration.
4664      * @param c The callback that will be used to send the result.
4665      */
4666     @Override
unregisterImsEmergencyRegistrationCallback(int subId, IImsRegistrationCallback c)4667     public void unregisterImsEmergencyRegistrationCallback(int subId, IImsRegistrationCallback c) {
4668         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4669                 mApp, subId, "unregisterImsEmergencyRegistrationCallback");
4670         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4671             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
4672         }
4673         final long token = Binder.clearCallingIdentity();
4674 
4675         try {
4676             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4677             if (controller != null) {
4678                 ImsManager imsManager = controller.getImsManager(subId);
4679                 if (imsManager != null) {
4680                     imsManager.removeEmergencyRegistrationCallbackForSubscription(c, subId);
4681                 } else {
4682                     Log.i(LOG_TAG, "unregisterImsEmergencyRegistrationCallback: " + subId
4683                             + "is inactive, ignoring unregister.");
4684                     // If the ImsManager is not valid, just return, since the callback
4685                     // will already have been removed internally.
4686                 }
4687             }
4688         } finally {
4689             Binder.restoreCallingIdentity(token);
4690         }
4691     }
4692 
4693     /**
4694      * Get the IMS service registration state for the MmTelFeature associated with this sub id.
4695      */
4696     @Override
getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer)4697     public void getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer) {
4698         enforceReadPrivilegedPermission("getImsMmTelRegistrationState");
4699         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4700             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4701                     "IMS not available on device.");
4702         }
4703         final long token = Binder.clearCallingIdentity();
4704         try {
4705             Phone phone = getPhone(subId);
4706             if (phone == null) {
4707                 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
4708                         + subId + "'");
4709                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4710             }
4711             phone.getImsRegistrationState(regState -> {
4712                 try {
4713                     consumer.accept((regState == null)
4714                             ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
4715                 } catch (RemoteException e) {
4716                     // Ignore if the remote process is no longer available to call back.
4717                     Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
4718                 }
4719             });
4720         } finally {
4721             Binder.restoreCallingIdentity(token);
4722         }
4723     }
4724 
4725     /**
4726      * Get the transport type for the IMS service registration state.
4727      */
4728     @Override
getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer)4729     public void getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer) {
4730         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4731                 mApp, subId, "getImsMmTelRegistrationTransportType");
4732         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4733             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4734                     "IMS not available on device.");
4735         }
4736         final long token = Binder.clearCallingIdentity();
4737         try {
4738             Phone phone = getPhone(subId);
4739             if (phone == null) {
4740                 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
4741                         + subId + "'");
4742                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4743             }
4744             phone.getImsRegistrationTech(regTech -> {
4745                 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
4746                 int regTechConverted = (regTech == null)
4747                         ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
4748                 regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
4749                         regTechConverted);
4750                 try {
4751                     consumer.accept(regTechConverted);
4752                 } catch (RemoteException e) {
4753                     // Ignore if the remote process is no longer available to call back.
4754                     Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
4755                 }
4756             });
4757         } finally {
4758             Binder.restoreCallingIdentity(token);
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      * @param c The callback that will be used to send the result.
4766      */
4767     @Override
registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)4768     public void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)
4769             throws RemoteException {
4770         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4771                 mApp, subId, "registerMmTelCapabilityCallback");
4772         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4773             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4774                     "IMS not available on device.");
4775         }
4776         final long token = Binder.clearCallingIdentity();
4777         try {
4778             int slotId = getSlotIndexOrException(subId);
4779             verifyImsMmTelConfiguredOrThrow(slotId);
4780 
4781             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4782             if (controller != null) {
4783                 ImsManager imsManager = controller.getImsManager(subId);
4784                 if (imsManager != null) {
4785                     imsManager.addCapabilitiesCallbackForSubscription(c, subId);
4786                 } else {
4787                     throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
4788                 }
4789             } else {
4790                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
4791             }
4792         } catch (ImsException e) {
4793             throw new ServiceSpecificException(e.getCode());
4794         } finally {
4795             Binder.restoreCallingIdentity(token);
4796         }
4797     }
4798 
4799     /**
4800      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4801      * @param subId The subscription to use to check the configuration.
4802      * @param c The callback that will be used to send the result.
4803      */
4804     @Override
unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)4805     public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
4806         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4807                 mApp, subId, "unregisterMmTelCapabilityCallback");
4808         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4809             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
4810         }
4811 
4812         final long token = Binder.clearCallingIdentity();
4813         try {
4814             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4815             if (controller != null) {
4816                 ImsManager imsManager = controller.getImsManager(subId);
4817                 if (imsManager != null) {
4818                     imsManager.removeCapabilitiesCallbackForSubscription(c, subId);
4819                 } else {
4820                     Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
4821                             + " is inactive, ignoring unregister.");
4822                     // If the ImsManager is not valid, just return, since the callback
4823                     // will already have been removed internally.
4824                 }
4825             }
4826         } finally {
4827             Binder.restoreCallingIdentity(token);
4828         }
4829     }
4830 
4831     @Override
isCapable(int subId, int capability, int regTech)4832     public boolean isCapable(int subId, int capability, int regTech) {
4833         enforceReadPrivilegedPermission("isCapable");
4834 
4835         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4836                 FEATURE_TELEPHONY_IMS, "isCapable");
4837 
4838         final long token = Binder.clearCallingIdentity();
4839         try {
4840             int slotId = getSlotIndexOrException(subId);
4841             verifyImsMmTelConfiguredOrThrow(slotId);
4842             return ImsManager.getInstance(mApp, slotId).queryMmTelCapability(capability, regTech);
4843         } catch (com.android.ims.ImsException e) {
4844             Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
4845             return false;
4846         } catch (ImsException e) {
4847             Log.i(LOG_TAG, "isCapable: " + subId + " is inactive, returning false.");
4848             return false;
4849         } finally {
4850             Binder.restoreCallingIdentity(token);
4851         }
4852     }
4853 
4854     @Override
isAvailable(int subId, int capability, int regTech)4855     public boolean isAvailable(int subId, int capability, int regTech) {
4856         enforceReadPrivilegedPermission("isAvailable");
4857 
4858         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4859                 FEATURE_TELEPHONY_IMS, "isAvailable");
4860 
4861         final long token = Binder.clearCallingIdentity();
4862         try {
4863             Phone phone = getPhone(subId);
4864             if (phone == null) return false;
4865             return phone.isImsCapabilityAvailable(capability, regTech);
4866         } catch (com.android.ims.ImsException e) {
4867             Log.w(LOG_TAG, "IMS isAvailable - service unavailable: " + e.getMessage());
4868             return false;
4869         } finally {
4870             Binder.restoreCallingIdentity(token);
4871         }
4872     }
4873 
4874     /**
4875      * Determines if the MmTel feature capability is supported by the carrier configuration for this
4876      * subscription.
4877      * @param subId The subscription to use to check the configuration.
4878      * @param callback The callback that will be used to send the result.
4879      * @param capability The MmTelFeature capability that will be used to send the result.
4880      * @param transportType The transport type of the MmTelFeature capability.
4881      */
4882     @Override
isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability, int transportType)4883     public void isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability,
4884             int transportType) {
4885         enforceReadPrivilegedPermission("isMmTelCapabilitySupported");
4886         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4887             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4888                     "IMS not available on device.");
4889         }
4890         final long token = Binder.clearCallingIdentity();
4891         try {
4892             int slotId = getSlotIndex(subId);
4893             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4894                 Log.w(LOG_TAG, "isMmTelCapabilitySupported: called with an inactive subscription '"
4895                         + subId + "'");
4896                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4897             }
4898             verifyImsMmTelConfiguredOrThrow(slotId);
4899             ImsManager.getInstance(mApp, slotId).isSupported(capability,
4900                     transportType, aBoolean -> {
4901                         try {
4902                             callback.accept((aBoolean == null) ? 0 : (aBoolean ? 1 : 0));
4903                         } catch (RemoteException e) {
4904                             Log.w(LOG_TAG, "isMmTelCapabilitySupported: remote caller is not "
4905                                     + "running. Ignore");
4906                         }
4907                     });
4908         } catch (ImsException e) {
4909             throw new ServiceSpecificException(e.getCode());
4910         } finally {
4911             Binder.restoreCallingIdentity(token);
4912         }
4913     }
4914 
4915     /**
4916      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4917      * @param subId The subscription to use to check the configuration.
4918      */
4919     @Override
isAdvancedCallingSettingEnabled(int subId)4920     public boolean isAdvancedCallingSettingEnabled(int subId) {
4921         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4922                 mApp, subId, "isAdvancedCallingSettingEnabled");
4923 
4924         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4925                 FEATURE_TELEPHONY_IMS, "isAdvancedCallingSettingEnabled");
4926 
4927         final long token = Binder.clearCallingIdentity();
4928         try {
4929             int slotId = getSlotIndexOrException(subId);
4930             // This setting doesn't require an active ImsService connection, so do not verify.
4931             return ImsManager.getInstance(mApp, slotId).isEnhanced4gLteModeSettingEnabledByUser();
4932         } catch (ImsException e) {
4933             throw new ServiceSpecificException(e.getCode());
4934         } finally {
4935             Binder.restoreCallingIdentity(token);
4936         }
4937     }
4938 
4939     @Override
setAdvancedCallingSettingEnabled(int subId, boolean isEnabled)4940     public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
4941         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4942                 "setAdvancedCallingSettingEnabled");
4943 
4944         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4945                 FEATURE_TELEPHONY_IMS, "setAdvancedCallingSettingEnabled");
4946 
4947         final long identity = Binder.clearCallingIdentity();
4948         try {
4949             int slotId = getSlotIndexOrException(subId);
4950             // This setting doesn't require an active ImsService connection, so do not verify. The
4951             // new setting will be picked up when the ImsService comes up next if it isn't up.
4952             ImsManager.getInstance(mApp, slotId).setEnhanced4gLteModeSetting(isEnabled);
4953         } catch (ImsException e) {
4954             throw new ServiceSpecificException(e.getCode());
4955         } finally {
4956             Binder.restoreCallingIdentity(identity);
4957         }
4958     }
4959 
4960     /**
4961      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4962      * @param subId The subscription to use to check the configuration.
4963      */
4964     @Override
isVtSettingEnabled(int subId)4965     public boolean isVtSettingEnabled(int subId) {
4966         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4967                 mApp, subId, "isVtSettingEnabled");
4968 
4969         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4970                 FEATURE_TELEPHONY_IMS, "isVtSettingEnabled");
4971 
4972         final long identity = Binder.clearCallingIdentity();
4973         try {
4974             int slotId = getSlotIndexOrException(subId);
4975             // This setting doesn't require an active ImsService connection, so do not verify.
4976             return ImsManager.getInstance(mApp, slotId).isVtEnabledByUser();
4977         } catch (ImsException e) {
4978             throw new ServiceSpecificException(e.getCode());
4979         } finally {
4980             Binder.restoreCallingIdentity(identity);
4981         }
4982     }
4983 
4984     @Override
setVtSettingEnabled(int subId, boolean isEnabled)4985     public void setVtSettingEnabled(int subId, boolean isEnabled) {
4986         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4987                 "setVtSettingEnabled");
4988 
4989         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4990                 FEATURE_TELEPHONY_IMS, "setVtSettingEnabled");
4991 
4992         final long identity = Binder.clearCallingIdentity();
4993         try {
4994             int slotId = getSlotIndexOrException(subId);
4995             // This setting doesn't require an active ImsService connection, so do not verify. The
4996             // new setting will be picked up when the ImsService comes up next if it isn't up.
4997             ImsManager.getInstance(mApp, slotId).setVtSetting(isEnabled);
4998         } catch (ImsException e) {
4999             throw new ServiceSpecificException(e.getCode());
5000         } finally {
5001             Binder.restoreCallingIdentity(identity);
5002         }
5003     }
5004 
5005     /**
5006      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5007      * @param subId The subscription to use to check the configuration.
5008      */
5009     @Override
isVoWiFiSettingEnabled(int subId)5010     public boolean isVoWiFiSettingEnabled(int subId) {
5011         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5012                 mApp, subId, "isVoWiFiSettingEnabled");
5013 
5014         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5015                 FEATURE_TELEPHONY_IMS, "isVoWiFiSettingEnabled");
5016 
5017         final long identity = Binder.clearCallingIdentity();
5018         try {
5019             int slotId = getSlotIndexOrException(subId);
5020             // This setting doesn't require an active ImsService connection, so do not verify.
5021             return ImsManager.getInstance(mApp, slotId).isWfcEnabledByUser();
5022         } catch (ImsException e) {
5023             throw new ServiceSpecificException(e.getCode());
5024         } finally {
5025             Binder.restoreCallingIdentity(identity);
5026         }
5027     }
5028 
5029     @Override
setVoWiFiSettingEnabled(int subId, boolean isEnabled)5030     public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
5031         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5032                 "setVoWiFiSettingEnabled");
5033 
5034         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5035                 FEATURE_TELEPHONY_IMS, "setVoWiFiSettingEnabled");
5036 
5037         final long identity = Binder.clearCallingIdentity();
5038         try {
5039             int slotId = getSlotIndexOrException(subId);
5040             // This setting doesn't require an active ImsService connection, so do not verify. The
5041             // new setting will be picked up when the ImsService comes up next if it isn't up.
5042             ImsManager.getInstance(mApp, slotId).setWfcSetting(isEnabled);
5043         } catch (ImsException e) {
5044             throw new ServiceSpecificException(e.getCode());
5045         } finally {
5046             Binder.restoreCallingIdentity(identity);
5047         }
5048     }
5049 
5050     /**
5051      * @return true if the user's setting for Voice over Cross SIM is enabled and false if it is not
5052      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5053      * @param subId The subscription to use to check the configuration.
5054      */
5055     @Override
isCrossSimCallingEnabledByUser(int subId)5056     public boolean isCrossSimCallingEnabledByUser(int subId) {
5057         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5058                 mApp, subId, "isCrossSimCallingEnabledByUser");
5059 
5060         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5061                 FEATURE_TELEPHONY_IMS, "isCrossSimCallingEnabledByUser");
5062 
5063         final long identity = Binder.clearCallingIdentity();
5064         try {
5065             int slotId = getSlotIndexOrException(subId);
5066             // This setting doesn't require an active ImsService connection, so do not verify.
5067             return ImsManager.getInstance(mApp, slotId).isCrossSimCallingEnabledByUser();
5068         } catch (ImsException e) {
5069             throw new ServiceSpecificException(e.getCode());
5070         } finally {
5071             Binder.restoreCallingIdentity(identity);
5072         }
5073     }
5074 
5075     /**
5076      * Sets the user's setting for whether or not Voice over Cross SIM is enabled.
5077      * Requires MODIFY_PHONE_STATE permission.
5078      * @param subId The subscription to use to check the configuration.
5079      * @param isEnabled true if the user's setting for Voice over Cross SIM is enabled,
5080      *                 false otherwise
5081      */
5082     @Override
setCrossSimCallingEnabled(int subId, boolean isEnabled)5083     public void setCrossSimCallingEnabled(int subId, boolean isEnabled) {
5084         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5085                 "setCrossSimCallingEnabled");
5086 
5087         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5088                 FEATURE_TELEPHONY_IMS, "setCrossSimCallingEnabled");
5089 
5090         final long identity = Binder.clearCallingIdentity();
5091         try {
5092             int slotId = getSlotIndexOrException(subId);
5093             // This setting doesn't require an active ImsService connection, so do not verify. The
5094             // new setting will be picked up when the ImsService comes up next if it isn't up.
5095             ImsManager.getInstance(mApp, slotId).setCrossSimCallingEnabled(isEnabled);
5096         } catch (ImsException e) {
5097             throw new ServiceSpecificException(e.getCode());
5098         } finally {
5099             Binder.restoreCallingIdentity(identity);
5100         }
5101     }
5102 
5103     /**
5104      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5105      * @param subId The subscription to use to check the configuration.
5106      */
5107     @Override
5108 
isVoWiFiRoamingSettingEnabled(int subId)5109     public boolean isVoWiFiRoamingSettingEnabled(int subId) {
5110         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5111                 mApp, subId, "isVoWiFiRoamingSettingEnabled");
5112 
5113         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5114                 FEATURE_TELEPHONY_IMS, "isVoWiFiRoamingSettingEnabled");
5115 
5116         final long identity = Binder.clearCallingIdentity();
5117         try {
5118             int slotId = getSlotIndexOrException(subId);
5119             // This setting doesn't require an active ImsService connection, so do not verify.
5120             return ImsManager.getInstance(mApp, slotId).isWfcRoamingEnabledByUser();
5121         } catch (ImsException e) {
5122             throw new ServiceSpecificException(e.getCode());
5123         } finally {
5124             Binder.restoreCallingIdentity(identity);
5125         }
5126     }
5127 
5128     @Override
setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled)5129     public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
5130         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5131                 "setVoWiFiRoamingSettingEnabled");
5132 
5133         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5134                 FEATURE_TELEPHONY_IMS, "setVoWiFiRoamingSettingEnabled");
5135 
5136         final long identity = Binder.clearCallingIdentity();
5137         try {
5138             int slotId = getSlotIndexOrException(subId);
5139             // This setting doesn't require an active ImsService connection, so do not verify. The
5140             // new setting will be picked up when the ImsService comes up next if it isn't up.
5141             ImsManager.getInstance(mApp, slotId).setWfcRoamingSetting(isEnabled);
5142         } catch (ImsException e) {
5143             throw new ServiceSpecificException(e.getCode());
5144         } finally {
5145             Binder.restoreCallingIdentity(identity);
5146         }
5147     }
5148 
5149     @Override
setVoWiFiNonPersistent(int subId, boolean isCapable, int mode)5150     public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
5151         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5152                 "setVoWiFiNonPersistent");
5153 
5154         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5155                 FEATURE_TELEPHONY_IMS, "setVoWiFiNonPersistent");
5156 
5157         final long identity = Binder.clearCallingIdentity();
5158         try {
5159             int slotId = getSlotIndexOrException(subId);
5160             // This setting will be ignored if the ImsService isn't up.
5161             ImsManager.getInstance(mApp, slotId).setWfcNonPersistent(isCapable, mode);
5162         } catch (ImsException e) {
5163             throw new ServiceSpecificException(e.getCode());
5164         } finally {
5165             Binder.restoreCallingIdentity(identity);
5166         }
5167     }
5168 
5169     /**
5170      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5171      * @param subId The subscription to use to check the configuration.
5172      */
5173     @Override
getVoWiFiModeSetting(int subId)5174     public int getVoWiFiModeSetting(int subId) {
5175         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5176                 mApp, subId, "getVoWiFiModeSetting");
5177 
5178         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5179                 FEATURE_TELEPHONY_IMS, "getVoWiFiModeSetting");
5180 
5181         final long identity = Binder.clearCallingIdentity();
5182         try {
5183             int slotId = getSlotIndexOrException(subId);
5184             // This setting doesn't require an active ImsService connection, so do not verify.
5185             return ImsManager.getInstance(mApp, slotId).getWfcMode(false /*isRoaming*/);
5186         } catch (ImsException e) {
5187             throw new ServiceSpecificException(e.getCode());
5188         } finally {
5189             Binder.restoreCallingIdentity(identity);
5190         }
5191     }
5192 
5193     @Override
setVoWiFiModeSetting(int subId, int mode)5194     public void setVoWiFiModeSetting(int subId, int mode) {
5195         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5196                 "setVoWiFiModeSetting");
5197 
5198         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5199                 FEATURE_TELEPHONY_IMS, "setVoWiFiModeSetting");
5200 
5201         final long identity = Binder.clearCallingIdentity();
5202         try {
5203             int slotId = getSlotIndexOrException(subId);
5204             // This setting doesn't require an active ImsService connection, so do not verify. The
5205             // new setting will be picked up when the ImsService comes up next if it isn't up.
5206             ImsManager.getInstance(mApp, slotId).setWfcMode(mode, false /*isRoaming*/);
5207         } catch (ImsException e) {
5208             throw new ServiceSpecificException(e.getCode());
5209         } finally {
5210             Binder.restoreCallingIdentity(identity);
5211         }
5212     }
5213 
5214     @Override
getVoWiFiRoamingModeSetting(int subId)5215     public int getVoWiFiRoamingModeSetting(int subId) {
5216         enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
5217 
5218         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5219                 FEATURE_TELEPHONY_IMS, "getVoWiFiRoamingModeSetting");
5220 
5221         final long identity = Binder.clearCallingIdentity();
5222         try {
5223             int slotId = getSlotIndexOrException(subId);
5224             // This setting doesn't require an active ImsService connection, so do not verify.
5225             return ImsManager.getInstance(mApp, slotId).getWfcMode(true /*isRoaming*/);
5226         } catch (ImsException e) {
5227             throw new ServiceSpecificException(e.getCode());
5228         } finally {
5229             Binder.restoreCallingIdentity(identity);
5230         }
5231     }
5232 
5233     @Override
setVoWiFiRoamingModeSetting(int subId, int mode)5234     public void setVoWiFiRoamingModeSetting(int subId, int mode) {
5235         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5236                 "setVoWiFiRoamingModeSetting");
5237 
5238         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5239                 FEATURE_TELEPHONY_IMS, "setVoWiFiRoamingModeSetting");
5240 
5241         final long identity = Binder.clearCallingIdentity();
5242         try {
5243             int slotId = getSlotIndexOrException(subId);
5244             // This setting doesn't require an active ImsService connection, so do not verify. The
5245             // new setting will be picked up when the ImsService comes up next if it isn't up.
5246             ImsManager.getInstance(mApp, slotId).setWfcMode(mode, true /*isRoaming*/);
5247         } catch (ImsException e) {
5248             throw new ServiceSpecificException(e.getCode());
5249         } finally {
5250             Binder.restoreCallingIdentity(identity);
5251         }
5252     }
5253 
5254     @Override
setRttCapabilitySetting(int subId, boolean isEnabled)5255     public void setRttCapabilitySetting(int subId, boolean isEnabled) {
5256         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5257                 "setRttCapabilityEnabled");
5258 
5259         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5260                 FEATURE_TELEPHONY_IMS, "setRttCapabilitySetting");
5261 
5262         final long identity = Binder.clearCallingIdentity();
5263         try {
5264             int slotId = getSlotIndexOrException(subId);
5265             // This setting doesn't require an active ImsService connection, so do not verify. The
5266             // new setting will be picked up when the ImsService comes up next if it isn't up.
5267             ImsManager.getInstance(mApp, slotId).setRttEnabled(isEnabled);
5268         } catch (ImsException e) {
5269             throw new ServiceSpecificException(e.getCode());
5270         } finally {
5271             Binder.restoreCallingIdentity(identity);
5272         }
5273     }
5274 
5275     /**
5276      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5277      * @param subId The subscription to use to check the configuration.
5278      */
5279     @Override
isTtyOverVolteEnabled(int subId)5280     public boolean isTtyOverVolteEnabled(int subId) {
5281         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5282                 mApp, subId, "isTtyOverVolteEnabled");
5283 
5284         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5285                 FEATURE_TELEPHONY_IMS, "isTtyOverVolteEnabled");
5286 
5287         final long identity = Binder.clearCallingIdentity();
5288         try {
5289             int slotId = getSlotIndexOrException(subId);
5290             // This setting doesn't require an active ImsService connection, so do not verify.
5291             return ImsManager.getInstance(mApp, slotId).isTtyOnVoLteCapable();
5292         } catch (ImsException e) {
5293             throw new ServiceSpecificException(e.getCode());
5294         } finally {
5295             Binder.restoreCallingIdentity(identity);
5296         }
5297     }
5298 
5299     @Override
registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback)5300     public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
5301         enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
5302 
5303         final long identity = Binder.clearCallingIdentity();
5304         try {
5305             if (!isImsAvailableOnDevice()) {
5306                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5307                         "IMS not available on device.");
5308             }
5309             int slotId = getSlotIndexOrException(subId);
5310             verifyImsMmTelConfiguredOrThrow(slotId);
5311 
5312             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
5313             if (controller != null) {
5314                 ImsManager imsManager = controller.getImsManager(subId);
5315                 if (imsManager != null) {
5316                     imsManager.addProvisioningCallbackForSubscription(callback, subId);
5317                 } else {
5318                     throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
5319                 }
5320             } else {
5321                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
5322             }
5323         } catch (ImsException e) {
5324             throw new ServiceSpecificException(e.getCode());
5325         } finally {
5326             Binder.restoreCallingIdentity(identity);
5327         }
5328     }
5329 
5330     @Override
unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback)5331     public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
5332         enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
5333 
5334         final long identity = Binder.clearCallingIdentity();
5335         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5336             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
5337         }
5338         try {
5339             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
5340             if (controller != null) {
5341                 ImsManager imsManager = controller.getImsManager(subId);
5342                 if (imsManager != null) {
5343                     imsManager.removeProvisioningCallbackForSubscription(callback, subId);
5344                 } else {
5345                     Log.i(LOG_TAG, "unregisterImsProvisioningChangedCallback: " + subId
5346                             + " is inactive, ignoring unregister.");
5347                     // If the ImsManager is not valid, just return, since the callback will already
5348                     // have been removed internally.
5349                 }
5350             }
5351         } finally {
5352             Binder.restoreCallingIdentity(identity);
5353         }
5354     }
5355 
5356     @Override
registerFeatureProvisioningChangedCallback(int subId, IFeatureProvisioningCallback callback)5357     public void registerFeatureProvisioningChangedCallback(int subId,
5358             IFeatureProvisioningCallback callback) {
5359         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5360                 mApp, subId, "registerFeatureProvisioningChangedCallback");
5361 
5362         final long identity = Binder.clearCallingIdentity();
5363         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5364             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
5365         }
5366 
5367         try {
5368             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5369             if (controller == null) {
5370                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5371                         "Device does not support IMS");
5372             }
5373             controller.addFeatureProvisioningChangedCallback(subId, callback);
5374         } finally {
5375             Binder.restoreCallingIdentity(identity);
5376         }
5377     }
5378 
5379     @Override
unregisterFeatureProvisioningChangedCallback(int subId, IFeatureProvisioningCallback callback)5380     public void unregisterFeatureProvisioningChangedCallback(int subId,
5381             IFeatureProvisioningCallback callback) {
5382         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5383                 mApp, subId, "unregisterFeatureProvisioningChangedCallback");
5384 
5385         final long identity = Binder.clearCallingIdentity();
5386         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5387             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
5388         }
5389 
5390         try {
5391             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5392             if (controller == null) {
5393                 loge("unregisterFeatureProvisioningChangedCallback: Device does not support IMS");
5394                 return;
5395             }
5396             controller.removeFeatureProvisioningChangedCallback(subId, callback);
5397         } finally {
5398             Binder.restoreCallingIdentity(identity);
5399         }
5400     }
5401 
checkModifyPhoneStatePermission(int subId, String message)5402     private void checkModifyPhoneStatePermission(int subId, String message) {
5403         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5404                 message);
5405     }
5406 
5407     @Override
setRcsProvisioningStatusForCapability(int subId, int capability, int tech, boolean isProvisioned)5408     public void setRcsProvisioningStatusForCapability(int subId, int capability, int tech,
5409             boolean isProvisioned) {
5410         checkModifyPhoneStatePermission(subId, "setRcsProvisioningStatusForCapability");
5411 
5412         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5413                 FEATURE_TELEPHONY_IMS, "setRcsProvisioningStatusForCapability");
5414 
5415         final long identity = Binder.clearCallingIdentity();
5416         try {
5417             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5418             if (controller == null) {
5419                 loge("setRcsProvisioningStatusForCapability: Device does not support IMS");
5420                 return;
5421             }
5422             controller.setRcsProvisioningStatusForCapability(
5423                     subId, capability, tech, isProvisioned);
5424         } finally {
5425             Binder.restoreCallingIdentity(identity);
5426         }
5427     }
5428 
5429 
5430     @Override
getRcsProvisioningStatusForCapability(int subId, int capability, int tech)5431     public boolean getRcsProvisioningStatusForCapability(int subId, int capability, int tech) {
5432         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5433                 mApp, subId, "getRcsProvisioningStatusForCapability");
5434 
5435         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5436                 FEATURE_TELEPHONY_IMS, "getRcsProvisioningStatusForCapability");
5437 
5438         final long identity = Binder.clearCallingIdentity();
5439         try {
5440             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5441             if (controller == null) {
5442                 loge("getRcsProvisioningStatusForCapability: Device does not support IMS");
5443 
5444                 // device does not support IMS, this method will return true always.
5445                 return true;
5446             }
5447             return controller.getRcsProvisioningStatusForCapability(subId, capability, tech);
5448         } finally {
5449             Binder.restoreCallingIdentity(identity);
5450         }
5451     }
5452 
5453     @Override
setImsProvisioningStatusForCapability(int subId, int capability, int tech, boolean isProvisioned)5454     public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
5455             boolean isProvisioned) {
5456         checkModifyPhoneStatePermission(subId, "setImsProvisioningStatusForCapability");
5457 
5458         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5459                 FEATURE_TELEPHONY_IMS, "setImsProvisioningStatusForCapability");
5460 
5461         final long identity = Binder.clearCallingIdentity();
5462         try {
5463             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5464             if (controller == null) {
5465                 loge("setImsProvisioningStatusForCapability: Device does not support IMS");
5466                 return;
5467             }
5468             controller.setImsProvisioningStatusForCapability(
5469                     subId, capability, tech, isProvisioned);
5470         } finally {
5471             Binder.restoreCallingIdentity(identity);
5472         }
5473     }
5474 
5475     @Override
getImsProvisioningStatusForCapability(int subId, int capability, int tech)5476     public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
5477         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5478                 mApp, subId, "getProvisioningStatusForCapability");
5479 
5480         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5481                 FEATURE_TELEPHONY_IMS, "getImsProvisioningStatusForCapability");
5482 
5483         final long identity = Binder.clearCallingIdentity();
5484         try {
5485             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5486             if (controller == null) {
5487                 loge("getImsProvisioningStatusForCapability: Device does not support IMS");
5488 
5489                 // device does not support IMS, this method will return true always.
5490                 return true;
5491             }
5492             return controller.getImsProvisioningStatusForCapability(subId, capability, tech);
5493         } finally {
5494             Binder.restoreCallingIdentity(identity);
5495         }
5496     }
5497 
5498     @Override
isProvisioningRequiredForCapability(int subId, int capability, int tech)5499     public boolean isProvisioningRequiredForCapability(int subId, int capability, int tech) {
5500         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5501                 mApp, subId, "isProvisioningRequiredForCapability");
5502 
5503         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5504                 FEATURE_TELEPHONY_IMS, "isProvisioningRequiredForCapability");
5505 
5506         final long identity = Binder.clearCallingIdentity();
5507         try {
5508             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5509             if (controller == null) {
5510                 loge("isProvisioningRequiredForCapability: Device does not support IMS");
5511 
5512                 // device does not support IMS, this method will return false
5513                 return false;
5514             }
5515             return controller.isImsProvisioningRequiredForCapability(subId, capability, tech);
5516         } finally {
5517             Binder.restoreCallingIdentity(identity);
5518         }
5519     }
5520 
5521     @Override
isRcsProvisioningRequiredForCapability(int subId, int capability, int tech)5522     public boolean isRcsProvisioningRequiredForCapability(int subId, int capability, int tech) {
5523         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5524                 mApp, subId, "isProvisioningRequiredForCapability");
5525 
5526         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5527                 FEATURE_TELEPHONY_IMS, "isRcsProvisioningRequiredForCapability");
5528 
5529         final long identity = Binder.clearCallingIdentity();
5530         try {
5531             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5532             if (controller == null) {
5533                 loge("isRcsProvisioningRequiredForCapability: Device does not support IMS");
5534 
5535                 // device does not support IMS, this method will return false
5536                 return false;
5537             }
5538             return controller.isRcsProvisioningRequiredForCapability(subId, capability, tech);
5539         } finally {
5540             Binder.restoreCallingIdentity(identity);
5541         }
5542     }
5543 
5544     @Override
getImsProvisioningInt(int subId, int key)5545     public int getImsProvisioningInt(int subId, int key) {
5546         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5547             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5548         }
5549         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5550                 mApp, subId, "getImsProvisioningInt");
5551 
5552         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5553                 FEATURE_TELEPHONY_IMS, "getImsProvisioningInt");
5554 
5555         final long identity = Binder.clearCallingIdentity();
5556         try {
5557             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
5558             int slotId = getSlotIndex(subId);
5559             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5560                 Log.w(LOG_TAG, "getImsProvisioningInt: called with an inactive subscription '"
5561                         + subId + "' for key:" + key);
5562                 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
5563             }
5564 
5565             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5566             if (controller == null) {
5567                 loge("getImsProvisioningInt: Device does not support IMS");
5568 
5569                 // device does not support IMS, this method will return CONFIG_RESULT_UNKNOWN.
5570                 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
5571             }
5572             int retVal = controller.getProvisioningValue(subId, key);
5573             if (retVal != ImsConfigImplBase.CONFIG_RESULT_UNKNOWN) {
5574                 return retVal;
5575             }
5576 
5577             return ImsManager.getInstance(mApp, slotId).getConfigInt(key);
5578         } catch (com.android.ims.ImsException e) {
5579             Log.w(LOG_TAG, "getImsProvisioningInt: ImsService is not available for subscription '"
5580                     + subId + "' for key:" + key);
5581             return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
5582         } finally {
5583             Binder.restoreCallingIdentity(identity);
5584         }
5585     }
5586 
5587     @Override
getImsProvisioningString(int subId, int key)5588     public String getImsProvisioningString(int subId, int key) {
5589         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5590             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5591         }
5592         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5593                 mApp, subId, "getImsProvisioningString");
5594 
5595         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5596                 FEATURE_TELEPHONY_IMS, "getImsProvisioningString");
5597 
5598         final long identity = Binder.clearCallingIdentity();
5599         try {
5600             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
5601             int slotId = getSlotIndex(subId);
5602             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5603                 Log.w(LOG_TAG, "getImsProvisioningString: called for an inactive subscription id '"
5604                         + subId + "' for key:" + key);
5605                 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_GENERIC;
5606             }
5607             return ImsManager.getInstance(mApp, slotId).getConfigString(key);
5608         } catch (com.android.ims.ImsException e) {
5609             Log.w(LOG_TAG, "getImsProvisioningString: ImsService is not available for sub '"
5610                     + subId + "' for key:" + key);
5611             return ProvisioningManager.STRING_QUERY_RESULT_ERROR_NOT_READY;
5612         } finally {
5613             Binder.restoreCallingIdentity(identity);
5614         }
5615     }
5616 
5617     @Override
setImsProvisioningInt(int subId, int key, int value)5618     public int setImsProvisioningInt(int subId, int key, int value) {
5619         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5620             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5621         }
5622         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5623                 "setImsProvisioningInt");
5624 
5625         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5626                 FEATURE_TELEPHONY_IMS, "setImsProvisioningInt");
5627 
5628         final long identity = Binder.clearCallingIdentity();
5629         try {
5630             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
5631             int slotId = getSlotIndex(subId);
5632             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5633                 Log.w(LOG_TAG, "setImsProvisioningInt: called with an inactive subscription id '"
5634                         + subId + "' for key:" + key);
5635                 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5636             }
5637 
5638             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5639             if (controller == null) {
5640                 loge("setImsProvisioningInt: Device does not support IMS");
5641 
5642                 // device does not support IMS, this method will return CONFIG_RESULT_FAILED.
5643                 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5644             }
5645             int retVal = controller.setProvisioningValue(subId, key, value);
5646             if (retVal != ImsConfigImplBase.CONFIG_RESULT_UNKNOWN) {
5647                 return retVal;
5648             }
5649 
5650             return ImsManager.getInstance(mApp, slotId).setConfig(key, value);
5651         } catch (com.android.ims.ImsException | RemoteException e) {
5652             Log.w(LOG_TAG, "setImsProvisioningInt: ImsService unavailable for sub '" + subId
5653                     + "' for key:" + key, e);
5654             return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5655         } finally {
5656             Binder.restoreCallingIdentity(identity);
5657         }
5658     }
5659 
5660     @Override
setImsProvisioningString(int subId, int key, String value)5661     public int setImsProvisioningString(int subId, int key, String value) {
5662         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5663             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5664         }
5665         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5666                 "setImsProvisioningString");
5667 
5668         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5669                 FEATURE_TELEPHONY_IMS, "setImsProvisioningString");
5670 
5671         final long identity = Binder.clearCallingIdentity();
5672         try {
5673             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
5674             int slotId = getSlotIndex(subId);
5675             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5676                 Log.w(LOG_TAG, "setImsProvisioningString: called with an inactive subscription id '"
5677                         + subId + "' for key:" + key);
5678                 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5679             }
5680             return ImsManager.getInstance(mApp, slotId).setConfig(key, value);
5681         } catch (com.android.ims.ImsException | RemoteException e) {
5682             Log.w(LOG_TAG, "setImsProvisioningString: ImsService unavailable for sub '" + subId
5683                     + "' for key:" + key, e);
5684             return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5685         } finally {
5686             Binder.restoreCallingIdentity(identity);
5687         }
5688     }
5689 
5690     /**
5691      * Throw an ImsException if the IMS resolver does not have an ImsService configured for MMTEL
5692      * for the given slot ID or no ImsResolver instance has been created.
5693      * @param slotId The slot ID that the IMS service is created for.
5694      * @throws ImsException If there is no ImsService configured for this slot.
5695      */
verifyImsMmTelConfiguredOrThrow(int slotId)5696     private void verifyImsMmTelConfiguredOrThrow(int slotId) throws ImsException {
5697         if (mImsResolver == null || !mImsResolver.isImsServiceConfiguredForFeature(slotId,
5698                 ImsFeature.FEATURE_MMTEL)) {
5699             throw new ImsException("This subscription does not support MMTEL over IMS",
5700                     ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
5701         }
5702     }
5703 
getSlotIndexOrException(int subId)5704     private int getSlotIndexOrException(int subId) throws ImsException {
5705         int slotId = SubscriptionManager.getSlotIndex(subId);
5706         if (!SubscriptionManager.isValidSlotIndex(slotId)) {
5707             throw new ImsException("Invalid Subscription Id, subId=" + subId,
5708                     ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
5709         }
5710         return slotId;
5711     }
5712 
getSlotIndex(int subId)5713     private int getSlotIndex(int subId) {
5714         int slotId = SubscriptionManager.getSlotIndex(subId);
5715         if (!SubscriptionManager.isValidSlotIndex(slotId)) {
5716             return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
5717         }
5718         return slotId;
5719     }
5720 
5721     /**
5722      * Returns the data network type for a subId; does not throw SecurityException.
5723      */
5724     @Override
getNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId)5725     public int getNetworkTypeForSubscriber(int subId, String callingPackage,
5726             String callingFeatureId) {
5727         try {
5728             mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5729         } catch (SecurityException se) {
5730             EventLog.writeEvent(0x534e4554, "186776740", Binder.getCallingUid());
5731             throw new SecurityException("Package " + callingPackage + " does not belong to "
5732                     + Binder.getCallingUid());
5733         }
5734         final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
5735         if (targetSdk > android.os.Build.VERSION_CODES.Q) {
5736             return getDataNetworkTypeForSubscriber(subId, callingPackage, callingFeatureId);
5737         } else if (targetSdk == android.os.Build.VERSION_CODES.Q
5738                 && !TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
5739                 mApp, subId, callingPackage, callingFeatureId,
5740                 "getNetworkTypeForSubscriber")) {
5741             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5742         }
5743 
5744         enforceTelephonyFeatureWithException(callingPackage,
5745                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getNetworkTypeForSubscriber");
5746 
5747         final long identity = Binder.clearCallingIdentity();
5748         try {
5749             final Phone phone = getPhone(subId);
5750             if (phone != null) {
5751                 return phone.getServiceState().getDataNetworkType();
5752             } else {
5753                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5754             }
5755         } finally {
5756             Binder.restoreCallingIdentity(identity);
5757         }
5758     }
5759 
5760     /**
5761      * Returns the data network type
5762      */
5763     @Override
getDataNetworkType(String callingPackage, String callingFeatureId)5764     public int getDataNetworkType(String callingPackage, String callingFeatureId) {
5765         return getDataNetworkTypeForSubscriber(SubscriptionManager.getDefaultDataSubscriptionId(),
5766                 callingPackage, callingFeatureId);
5767     }
5768 
5769     /**
5770      * Returns the data network type for a subId
5771      */
5772     @Override
getDataNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId)5773     public int getDataNetworkTypeForSubscriber(int subId, String callingPackage,
5774             String callingFeatureId) {
5775         String functionName = "getDataNetworkTypeForSubscriber";
5776         if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
5777                 mApp, functionName)) {
5778             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5779                     mApp, subId, callingPackage, callingFeatureId, functionName)) {
5780                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5781             }
5782         }
5783 
5784         enforceTelephonyFeatureWithException(callingPackage,
5785                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getDataNetworkTypeForSubscriber");
5786 
5787         final long identity = Binder.clearCallingIdentity();
5788         try {
5789             final Phone phone = getPhone(subId);
5790             if (phone != null) {
5791                 return phone.getServiceState().getDataNetworkType();
5792             } else {
5793                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5794             }
5795         } finally {
5796             Binder.restoreCallingIdentity(identity);
5797         }
5798     }
5799 
5800     /**
5801      * Returns the Voice network type for a subId
5802      */
5803     @Override
getVoiceNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId)5804     public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage,
5805             String callingFeatureId) {
5806         String functionName = "getVoiceNetworkTypeForSubscriber";
5807         if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
5808                 mApp, functionName)) {
5809             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5810                     mApp, subId, callingPackage, callingFeatureId, functionName)) {
5811                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5812             }
5813         }
5814 
5815         enforceTelephonyFeatureWithException(callingPackage,
5816                 PackageManager.FEATURE_TELEPHONY_CALLING, "getVoiceNetworkTypeForSubscriber");
5817 
5818         final long identity = Binder.clearCallingIdentity();
5819         try {
5820             final Phone phone = getPhone(subId);
5821             if (phone != null) {
5822                 return phone.getServiceState().getVoiceNetworkType();
5823             } else {
5824                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5825             }
5826         } finally {
5827             Binder.restoreCallingIdentity(identity);
5828         }
5829     }
5830 
5831     /**
5832      * @return true if a ICC card is present
5833      */
hasIccCard()5834     public boolean hasIccCard() {
5835         // FIXME Make changes to pass defaultSimId of type int
5836         return hasIccCardUsingSlotIndex(SubscriptionManager.getSlotIndex(
5837                 getDefaultSubscription()));
5838     }
5839 
5840     /**
5841      * @return true if a ICC card is present for a slotIndex
5842      */
5843     @Override
hasIccCardUsingSlotIndex(int slotIndex)5844     public boolean hasIccCardUsingSlotIndex(int slotIndex) {
5845         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5846                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "hasIccCardUsingSlotIndex");
5847 
5848         final long identity = Binder.clearCallingIdentity();
5849         try {
5850             final Phone phone = PhoneFactory.getPhone(slotIndex);
5851             if (phone != null) {
5852                 return phone.getIccCard().hasIccCard();
5853             } else {
5854                 return false;
5855             }
5856         } finally {
5857             Binder.restoreCallingIdentity(identity);
5858         }
5859     }
5860 
5861     /**
5862      * Return if the current radio is LTE on CDMA. This
5863      * is a tri-state return value as for a period of time
5864      * the mode may be unknown.
5865      *
5866      * @param callingPackage the name of the package making the call.
5867      * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
5868      * or {@link Phone#LTE_ON_CDMA_TRUE}
5869      */
5870     @Override
getLteOnCdmaMode(String callingPackage, String callingFeatureId)5871     public int getLteOnCdmaMode(String callingPackage, String callingFeatureId) {
5872         return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage,
5873                 callingFeatureId);
5874     }
5875 
5876     @Override
getLteOnCdmaModeForSubscriber(int subId, String callingPackage, String callingFeatureId)5877     public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage,
5878             String callingFeatureId) {
5879         try {
5880             enforceReadPrivilegedPermission("getLteOnCdmaModeForSubscriber");
5881         } catch (SecurityException e) {
5882             return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
5883         }
5884 
5885         enforceTelephonyFeatureWithException(callingPackage,
5886                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getLteOnCdmaModeForSubscriber");
5887 
5888         final long identity = Binder.clearCallingIdentity();
5889         try {
5890             final Phone phone = getPhone(subId);
5891             if (phone == null) {
5892                 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
5893             } else {
5894                 return TelephonyProperties.lte_on_cdma_device()
5895                         .orElse(PhoneConstants.LTE_ON_CDMA_FALSE);
5896             }
5897         } finally {
5898             Binder.restoreCallingIdentity(identity);
5899         }
5900     }
5901 
5902     /**
5903      * {@hide}
5904      * Returns Default subId, 0 in the case of single standby.
5905      */
getDefaultSubscription()5906     private int getDefaultSubscription() {
5907         return SubscriptionManager.getDefaultSubscriptionId();
5908     }
5909 
getSlotForDefaultSubscription()5910     private int getSlotForDefaultSubscription() {
5911         return SubscriptionManager.getPhoneId(getDefaultSubscription());
5912     }
5913 
getPreferredVoiceSubscription()5914     private int getPreferredVoiceSubscription() {
5915         return SubscriptionManager.getDefaultVoiceSubscriptionId();
5916     }
5917 
isActiveSubscription(int subId)5918     private boolean isActiveSubscription(int subId) {
5919         return getSubscriptionManagerService().isActiveSubId(subId,
5920                 mApp.getOpPackageName(), mApp.getFeatureId());
5921     }
5922 
5923     /**
5924      * @see android.telephony.TelephonyManager.WifiCallingChoices
5925      */
getWhenToMakeWifiCalls()5926     public int getWhenToMakeWifiCalls() {
5927         final long identity = Binder.clearCallingIdentity();
5928         try {
5929             return Settings.System.getInt(mApp.getContentResolver(),
5930                     Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
5931                     getWhenToMakeWifiCallsDefaultPreference());
5932         } finally {
5933             Binder.restoreCallingIdentity(identity);
5934         }
5935     }
5936 
5937     /**
5938      * @see android.telephony.TelephonyManager.WifiCallingChoices
5939      */
setWhenToMakeWifiCalls(int preference)5940     public void setWhenToMakeWifiCalls(int preference) {
5941         final long identity = Binder.clearCallingIdentity();
5942         try {
5943             if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
5944             Settings.System.putInt(mApp.getContentResolver(),
5945                     Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
5946         } finally {
5947             Binder.restoreCallingIdentity(identity);
5948         }
5949     }
5950 
getWhenToMakeWifiCallsDefaultPreference()5951     private static int getWhenToMakeWifiCallsDefaultPreference() {
5952         // TODO: Use a build property to choose this value.
5953         return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
5954     }
5955 
getPhoneFromSlotPortIndexOrThrowException(int slotIndex, int portIndex)5956     private Phone getPhoneFromSlotPortIndexOrThrowException(int slotIndex, int portIndex) {
5957         int phoneId = UiccController.getInstance().getPhoneIdFromSlotPortIndex(slotIndex,
5958                 portIndex);
5959         if (phoneId == -1) {
5960             throw new IllegalArgumentException("Given slot index: " + slotIndex + " port index: "
5961                     + portIndex + " does not correspond to an active phone");
5962         }
5963         return PhoneFactory.getPhone(phoneId);
5964     }
5965 
5966     @Override
iccOpenLogicalChannel( @onNull IccLogicalChannelRequest request)5967     public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
5968             @NonNull IccLogicalChannelRequest request) {
5969 
5970         Phone phone = getPhoneFromValidIccLogicalChannelRequest(request,
5971                 /*message=*/ "iccOpenLogicalChannel");
5972 
5973         if (DBG) log("iccOpenLogicalChannel: request=" + request);
5974         // Verify that the callingPackage in the request belongs to the calling UID
5975         mAppOps.checkPackage(Binder.getCallingUid(), request.callingPackage);
5976 
5977         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5978                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccOpenLogicalChannel");
5979 
5980         return iccOpenLogicalChannelWithPermission(phone, request);
5981     }
5982 
getPhoneFromValidIccLogicalChannelRequest( @onNull IccLogicalChannelRequest request, String message)5983     private Phone getPhoneFromValidIccLogicalChannelRequest(
5984             @NonNull IccLogicalChannelRequest request, String message) {
5985         Phone phone;
5986         if (request.subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
5987             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5988                     mApp, request.subId, message);
5989             phone = getPhoneFromSubId(request.subId);
5990         } else if (request.slotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5991             enforceModifyPermission();
5992             phone = getPhoneFromSlotPortIndexOrThrowException(request.slotIndex, request.portIndex);
5993         } else {
5994             throw new IllegalArgumentException("Both subId and slotIndex in request are invalid.");
5995         }
5996         return phone;
5997     }
5998 
iccOpenLogicalChannelWithPermission(Phone phone, IccLogicalChannelRequest channelRequest)5999     private IccOpenLogicalChannelResponse iccOpenLogicalChannelWithPermission(Phone phone,
6000             IccLogicalChannelRequest channelRequest) {
6001         final long identity = Binder.clearCallingIdentity();
6002         try {
6003             if (TextUtils.equals(ISDR_AID, channelRequest.aid)) {
6004                 // Only allows LPA to open logical channel to ISD-R.
6005                 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
6006                         .getContext().getPackageManager());
6007                 if (bestComponent == null || !TextUtils.equals(channelRequest.callingPackage,
6008                         bestComponent.packageName)) {
6009                     loge("The calling package is not allowed to access ISD-R.");
6010                     throw new SecurityException(
6011                             "The calling package is not allowed to access ISD-R.");
6012                 }
6013             }
6014 
6015             IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
6016                     CMD_OPEN_CHANNEL, channelRequest, phone, null /* workSource */);
6017             if (DBG) log("iccOpenLogicalChannelWithPermission: response=" + response);
6018             return response;
6019         } finally {
6020             Binder.restoreCallingIdentity(identity);
6021         }
6022     }
6023 
6024     @Override
iccCloseLogicalChannel(@onNull IccLogicalChannelRequest request)6025     public boolean iccCloseLogicalChannel(@NonNull IccLogicalChannelRequest request) {
6026         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6027                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccCloseLogicalChannel");
6028 
6029         Phone phone = getPhoneFromValidIccLogicalChannelRequest(request,
6030                 /*message=*/"iccCloseLogicalChannel");
6031 
6032         if (DBG) log("iccCloseLogicalChannel: request=" + request);
6033 
6034         return iccCloseLogicalChannelWithPermission(phone, request);
6035     }
6036 
iccCloseLogicalChannelWithPermission(Phone phone, IccLogicalChannelRequest request)6037     private boolean iccCloseLogicalChannelWithPermission(Phone phone,
6038             IccLogicalChannelRequest request) {
6039         // before this feature is enabled, this API should only return false if
6040         // the operation fails instead of throwing runtime exception for
6041         // backward-compatibility.
6042         final boolean shouldThrowExceptionOnFailure = CompatChanges.isChangeEnabled(
6043                 ICC_CLOSE_CHANNEL_EXCEPTION_ON_FAILURE, Binder.getCallingUid());
6044         final long identity = Binder.clearCallingIdentity();
6045         try {
6046             if (request.channel < 0) {
6047                 throw new IllegalArgumentException("request.channel is less than 0");
6048             }
6049             Object result = sendRequest(CMD_CLOSE_CHANNEL, request.channel, phone,
6050                     null /* workSource */);
6051             Boolean success = false;
6052             if (result instanceof RuntimeException) {
6053                 // if there is an exception returned, throw from the binder thread here.
6054                 if (shouldThrowExceptionOnFailure) {
6055                     throw (RuntimeException) result;
6056                 } else {
6057                     return false;
6058                 }
6059             } else if (result instanceof Boolean) {
6060                 success = (Boolean) result;
6061             } else {
6062                 loge("iccCloseLogicalChannelWithPermission: supported return type " + result);
6063             }
6064             if (DBG) log("iccCloseLogicalChannelWithPermission: success=" + success);
6065             return success;
6066         } finally {
6067             Binder.restoreCallingIdentity(identity);
6068         }
6069     }
6070 
6071     @Override
iccTransmitApduLogicalChannel(int subId, int channel, int cla, int command, int p1, int p2, int p3, String data)6072     public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
6073             int command, int p1, int p2, int p3, String data) {
6074         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6075                 mApp, subId, "iccTransmitApduLogicalChannel");
6076 
6077         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6078                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccTransmitApduLogicalChannel");
6079 
6080         if (DBG) {
6081             log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
6082                     + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
6083                     + p3 + " data=" + data);
6084         }
6085         return iccTransmitApduLogicalChannelWithPermission(getPhoneFromSubId(subId), channel, cla,
6086                 command, p1, p2, p3, data);
6087     }
6088 
6089     @Override
iccTransmitApduLogicalChannelByPort(int slotIndex, int portIndex, int channel, int cla, int command, int p1, int p2, int p3, String data)6090     public String iccTransmitApduLogicalChannelByPort(int slotIndex, int portIndex, int channel,
6091             int cla, int command, int p1, int p2, int p3, String data) {
6092         enforceModifyPermission();
6093 
6094         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6095                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
6096                 "iccTransmitApduLogicalChannelBySlot");
6097 
6098         if (DBG) {
6099             log("iccTransmitApduLogicalChannelByPort: slotIndex=" + slotIndex + " portIndex="
6100                     + portIndex + " chnl=" + channel + " cla=" + cla + " cmd=" + command + " p1="
6101                     + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
6102         }
6103         return iccTransmitApduLogicalChannelWithPermission(
6104                 getPhoneFromSlotPortIndexOrThrowException(slotIndex, portIndex), channel, cla,
6105                 command, p1, p2, p3, data);
6106     }
6107 
iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla, int command, int p1, int p2, int p3, String data)6108     private String iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla,
6109             int command, int p1, int p2, int p3, String data) {
6110         final long identity = Binder.clearCallingIdentity();
6111         try {
6112             if (channel <= 0) {
6113                 return "";
6114             }
6115 
6116             IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
6117                     new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), phone,
6118                     null /* workSource */);
6119             if (DBG) log("iccTransmitApduLogicalChannelWithPermission: " + response);
6120 
6121             // Append the returned status code to the end of the response payload.
6122             String s = Integer.toHexString(
6123                     (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
6124             if (response.payload != null) {
6125                 s = IccUtils.bytesToHexString(response.payload) + s;
6126             }
6127             return s;
6128         } finally {
6129             Binder.restoreCallingIdentity(identity);
6130         }
6131     }
6132 
6133     @Override
iccTransmitApduBasicChannel(int subId, String callingPackage, int cla, int command, int p1, int p2, int p3, String data)6134     public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
6135             int command, int p1, int p2, int p3, String data) {
6136         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6137                 mApp, subId, "iccTransmitApduBasicChannel");
6138         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
6139 
6140         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6141                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccTransmitApduBasicChannel");
6142 
6143         if (DBG) {
6144             log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
6145                     + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
6146         }
6147         return iccTransmitApduBasicChannelWithPermission(getPhoneFromSubId(subId), callingPackage,
6148                 cla, command, p1, p2, p3, data);
6149     }
6150 
6151     @Override
iccTransmitApduBasicChannelByPort(int slotIndex, int portIndex, String callingPackage, int cla, int command, int p1, int p2, int p3, String data)6152     public String iccTransmitApduBasicChannelByPort(int slotIndex, int portIndex,
6153             String callingPackage, int cla, int command, int p1, int p2, int p3, String data) {
6154         enforceModifyPermission();
6155         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
6156 
6157         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6158                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccTransmitApduBasicChannelBySlot");
6159 
6160         if (DBG) {
6161             log("iccTransmitApduBasicChannelByPort: slotIndex=" + slotIndex + " portIndex="
6162                     + portIndex + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2="
6163                     + p2 + " p3=" + p3 + " data=" + data);
6164         }
6165 
6166         return iccTransmitApduBasicChannelWithPermission(
6167                 getPhoneFromSlotPortIndexOrThrowException(slotIndex, portIndex), callingPackage,
6168                 cla, command, p1, p2, p3, data);
6169     }
6170 
6171     // 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)6172     private String iccTransmitApduBasicChannelWithPermission(Phone phone, String callingPackage,
6173             int cla, int command, int p1, int p2, int p3, String data) {
6174         final long identity = Binder.clearCallingIdentity();
6175         try {
6176             if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
6177                     && TextUtils.equals(ISDR_AID, data)) {
6178                 // Only allows LPA to select ISD-R.
6179                 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
6180                         .getContext().getPackageManager());
6181                 if (bestComponent == null
6182                         || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
6183                     loge("The calling package is not allowed to select ISD-R.");
6184                     throw new SecurityException(
6185                             "The calling package is not allowed to select ISD-R.");
6186                 }
6187             }
6188 
6189             IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
6190                     new IccAPDUArgument(0, cla, command, p1, p2, p3, data), phone,
6191                     null /* workSource */);
6192             if (DBG) log("iccTransmitApduBasicChannelWithPermission: " + response);
6193 
6194             // Append the returned status code to the end of the response payload.
6195             String s = Integer.toHexString(
6196                     (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
6197             if (response.payload != null) {
6198                 s = IccUtils.bytesToHexString(response.payload) + s;
6199             }
6200             return s;
6201         } finally {
6202             Binder.restoreCallingIdentity(identity);
6203         }
6204     }
6205 
6206     @Override
iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3, String filePath)6207     public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
6208             String filePath) {
6209         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6210                 mApp, subId, "iccExchangeSimIO");
6211 
6212         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6213                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccExchangeSimIO");
6214 
6215         final long identity = Binder.clearCallingIdentity();
6216         try {
6217             if (DBG) {
6218                 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
6219                         + p1 + " " + p2 + " " + p3 + ":" + filePath);
6220             }
6221 
6222             IccIoResult response =
6223                     (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
6224                             new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
6225                             subId);
6226 
6227             if (DBG) {
6228                 log("Exchange SIM_IO [R]" + response);
6229             }
6230 
6231             byte[] result = null;
6232             int length = 2;
6233             if (response.payload != null) {
6234                 length = 2 + response.payload.length;
6235                 result = new byte[length];
6236                 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
6237             } else {
6238                 result = new byte[length];
6239             }
6240 
6241             result[length - 1] = (byte) response.sw2;
6242             result[length - 2] = (byte) response.sw1;
6243             return result;
6244         } finally {
6245             Binder.restoreCallingIdentity(identity);
6246         }
6247     }
6248 
6249     /**
6250      * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
6251      * on a particular subscription
6252      */
getForbiddenPlmns(int subId, int appType, String callingPackage, String callingFeatureId)6253     public String[] getForbiddenPlmns(int subId, int appType, String callingPackage,
6254             String callingFeatureId) {
6255         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6256                 mApp, subId, callingPackage, callingFeatureId, "getForbiddenPlmns")) {
6257             return null;
6258         }
6259 
6260         enforceTelephonyFeatureWithException(callingPackage,
6261                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getForbiddenPlmns");
6262 
6263         final long identity = Binder.clearCallingIdentity();
6264         try {
6265             if (appType != TelephonyManager.APPTYPE_USIM
6266                     && appType != TelephonyManager.APPTYPE_SIM) {
6267                 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
6268                 return null;
6269             }
6270             Object response = sendRequest(
6271                     CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
6272             if (response instanceof String[]) {
6273                 return (String[]) response;
6274             }
6275             // Response is an Exception of some kind
6276             // which is signalled to the user as a NULL retval
6277             return null;
6278         } finally {
6279             Binder.restoreCallingIdentity(identity);
6280         }
6281     }
6282 
6283     /**
6284      * Set the forbidden PLMN list from the given app type (ex APPTYPE_USIM) on a particular
6285      * subscription.
6286      *
6287      * @param subId the id of the subscription.
6288      * @param appType the uicc app type, must be USIM or SIM.
6289      * @param fplmns the Forbiden plmns list that needed to be written to the SIM.
6290      * @param callingPackage the op Package name.
6291      * @param callingFeatureId the feature in the package.
6292      * @return number of fplmns that is successfully written to the SIM.
6293      */
setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage, String callingFeatureId)6294     public int setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage,
6295             String callingFeatureId) {
6296         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6297                 mApp, subId, "setForbiddenPlmns");
6298 
6299         enforceTelephonyFeatureWithException(callingPackage,
6300                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "setForbiddenPlmns");
6301 
6302         if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
6303             loge("setForbiddenPlmnList(): App Type must be USIM or SIM");
6304             throw new IllegalArgumentException("Invalid appType: App Type must be USIM or SIM");
6305         }
6306         if (fplmns == null) {
6307             throw new IllegalArgumentException("Fplmn List provided is null");
6308         }
6309         for (String fplmn : fplmns) {
6310             if (!CellIdentity.isValidPlmn(fplmn)) {
6311                 throw new IllegalArgumentException("Invalid fplmn provided: " + fplmn);
6312             }
6313         }
6314         final long identity = Binder.clearCallingIdentity();
6315         try {
6316             Object response = sendRequest(
6317                     CMD_SET_FORBIDDEN_PLMNS,
6318                     new Pair<Integer, List<String>>(new Integer(appType), fplmns),
6319                     subId);
6320             return (int) response;
6321         } finally {
6322             Binder.restoreCallingIdentity(identity);
6323         }
6324     }
6325 
6326     @Override
sendEnvelopeWithStatus(int subId, String content)6327     public String sendEnvelopeWithStatus(int subId, String content) {
6328         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6329                 mApp, subId, "sendEnvelopeWithStatus");
6330 
6331         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6332                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "sendEnvelopeWithStatus");
6333 
6334         final long identity = Binder.clearCallingIdentity();
6335         try {
6336             IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
6337             if (response.payload == null) {
6338                 return "";
6339             }
6340 
6341             // Append the returned status code to the end of the response payload.
6342             String s = Integer.toHexString(
6343                     (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
6344             s = IccUtils.bytesToHexString(response.payload) + s;
6345             return s;
6346         } finally {
6347             Binder.restoreCallingIdentity(identity);
6348         }
6349     }
6350 
6351     /**
6352      * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
6353      * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
6354      *
6355      * @param itemID the ID of the item to read
6356      * @return the NV item as a String, or null on error.
6357      */
6358     @Override
nvReadItem(int itemID)6359     public String nvReadItem(int itemID) {
6360         WorkSource workSource = getWorkSource(Binder.getCallingUid());
6361         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6362                 mApp, getDefaultSubscription(), "nvReadItem");
6363 
6364         final long identity = Binder.clearCallingIdentity();
6365         try {
6366             if (DBG) log("nvReadItem: item " + itemID);
6367             String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
6368             if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
6369             return value;
6370         } finally {
6371             Binder.restoreCallingIdentity(identity);
6372         }
6373     }
6374 
6375     /**
6376      * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
6377      * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
6378      *
6379      * @param itemID the ID of the item to read
6380      * @param itemValue the value to write, as a String
6381      * @return true on success; false on any failure
6382      */
6383     @Override
nvWriteItem(int itemID, String itemValue)6384     public boolean nvWriteItem(int itemID, String itemValue) {
6385         WorkSource workSource = getWorkSource(Binder.getCallingUid());
6386         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6387                 mApp, getDefaultSubscription(), "nvWriteItem");
6388 
6389         final long identity = Binder.clearCallingIdentity();
6390         try {
6391             if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
6392             Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
6393                     new Pair<Integer, String>(itemID, itemValue), workSource);
6394             if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
6395             return success;
6396         } finally {
6397             Binder.restoreCallingIdentity(identity);
6398         }
6399     }
6400 
6401     /**
6402      * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
6403      * Used for device configuration by some CDMA operators.
6404      *
6405      * @param preferredRoamingList byte array containing the new PRL
6406      * @return true on success; false on any failure
6407      */
6408     @Override
nvWriteCdmaPrl(byte[] preferredRoamingList)6409     public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
6410         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6411                 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
6412 
6413         final long identity = Binder.clearCallingIdentity();
6414         try {
6415             if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
6416             Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
6417             if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
6418             return success;
6419         } finally {
6420             Binder.restoreCallingIdentity(identity);
6421         }
6422     }
6423 
6424     /**
6425      * Rollback modem configurations to factory default except some config which are in whitelist.
6426      * Used for device configuration by some CDMA operators.
6427      *
6428      * @param slotIndex - device slot.
6429      *
6430      * @return true on success; false on any failure
6431      */
6432     @Override
resetModemConfig(int slotIndex)6433     public boolean resetModemConfig(int slotIndex) {
6434         Phone phone = PhoneFactory.getPhone(slotIndex);
6435         if (phone != null) {
6436             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6437                     mApp, phone.getSubId(), "resetModemConfig");
6438 
6439             enforceTelephonyFeatureWithException(getCurrentPackageName(),
6440                     PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "resetModemConfig");
6441 
6442             final long identity = Binder.clearCallingIdentity();
6443             try {
6444                 Boolean success = (Boolean) sendRequest(CMD_RESET_MODEM_CONFIG, null);
6445                 if (DBG) log("resetModemConfig:" + ' ' + (success ? "ok" : "fail"));
6446                 return success;
6447             } finally {
6448                 Binder.restoreCallingIdentity(identity);
6449             }
6450         }
6451         return false;
6452     }
6453 
6454     /**
6455      * Generate a radio modem reset. Used for device configuration by some CDMA operators.
6456      *
6457      * @param slotIndex - device slot.
6458      *
6459      * @return true on success; false on any failure
6460      */
6461     @Override
rebootModem(int slotIndex)6462     public boolean rebootModem(int slotIndex) {
6463         Phone phone = PhoneFactory.getPhone(slotIndex);
6464         if (phone != null) {
6465             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6466                     mApp, phone.getSubId(), "rebootModem");
6467 
6468             enforceTelephonyFeatureWithException(getCurrentPackageName(),
6469                     PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "rebootModem");
6470 
6471             final long identity = Binder.clearCallingIdentity();
6472             try {
6473                 Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
6474                 if (DBG) log("rebootModem:" + ' ' + (success ? "ok" : "fail"));
6475                 return success;
6476             } finally {
6477                 Binder.restoreCallingIdentity(identity);
6478             }
6479         }
6480         return false;
6481     }
6482 
6483     /**
6484      * Toggle IMS disable and enable for the framework to reset it. See {@link #enableIms(int)} and
6485      * {@link #disableIms(int)}.
6486      * @param slotIndex device slot.
6487      */
resetIms(int slotIndex)6488     public void resetIms(int slotIndex) {
6489         enforceModifyPermission();
6490 
6491         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6492                 PackageManager.FEATURE_TELEPHONY_IMS, "resetIms");
6493 
6494         final long identity = Binder.clearCallingIdentity();
6495         try {
6496             if (mImsResolver == null) {
6497                 // may happen if the does not support IMS.
6498                 return;
6499             }
6500             mImsResolver.resetIms(slotIndex);
6501         } finally {
6502             Binder.restoreCallingIdentity(identity);
6503         }
6504     }
6505 
6506     /**
6507      * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
6508      * status updates, if not already enabled.
6509      */
enableIms(int slotId)6510     public void enableIms(int slotId) {
6511         enforceModifyPermission();
6512 
6513         final long identity = Binder.clearCallingIdentity();
6514         try {
6515             if (mImsResolver == null) {
6516                 // may happen if the device does not support IMS.
6517                 return;
6518             }
6519             mImsResolver.enableIms(slotId);
6520         } finally {
6521             Binder.restoreCallingIdentity(identity);
6522         }
6523     }
6524 
6525     /**
6526      * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
6527      * status updates to disabled.
6528      */
disableIms(int slotId)6529     public void disableIms(int slotId) {
6530         enforceModifyPermission();
6531 
6532         final long identity = Binder.clearCallingIdentity();
6533         try {
6534             if (mImsResolver == null) {
6535                 // may happen if the device does not support IMS.
6536                 return;
6537             }
6538             mImsResolver.disableIms(slotId);
6539         } finally {
6540             Binder.restoreCallingIdentity(identity);
6541         }
6542     }
6543 
6544     /**
6545      * Registers for updates to the MmTelFeature connection through the IImsServiceFeatureCallback
6546      * callback.
6547      */
6548     @Override
registerMmTelFeatureCallback(int slotId, IImsServiceFeatureCallback callback)6549     public void registerMmTelFeatureCallback(int slotId, IImsServiceFeatureCallback callback) {
6550         enforceModifyPermission();
6551 
6552         final long identity = Binder.clearCallingIdentity();
6553         try {
6554             if (mImsResolver == null) {
6555                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
6556                         "Device does not support IMS");
6557             }
6558             mImsResolver.listenForFeature(slotId, ImsFeature.FEATURE_MMTEL, callback);
6559         } finally {
6560             Binder.restoreCallingIdentity(identity);
6561         }
6562     }
6563     /**
6564      * Unregister a previously registered IImsServiceFeatureCallback associated with an ImsFeature.
6565      */
6566     @Override
unregisterImsFeatureCallback(IImsServiceFeatureCallback callback)6567     public void unregisterImsFeatureCallback(IImsServiceFeatureCallback callback) {
6568         enforceModifyPermission();
6569 
6570         final long identity = Binder.clearCallingIdentity();
6571         try {
6572             if (mImsResolver == null) return;
6573             mImsResolver.unregisterImsFeatureCallback(callback);
6574         } finally {
6575             Binder.restoreCallingIdentity(identity);
6576         }
6577     }
6578 
6579     /**
6580      * Returns the {@link IImsRegistration} structure associated with the slotId and feature
6581      * specified or null if IMS is not supported on the slot specified.
6582      */
getImsRegistration(int slotId, int feature)6583     public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
6584         enforceModifyPermission();
6585 
6586         final long identity = Binder.clearCallingIdentity();
6587         try {
6588             if (mImsResolver == null) {
6589                 // may happen if the device does not support IMS.
6590                 return null;
6591             }
6592             return mImsResolver.getImsRegistration(slotId, feature);
6593         } finally {
6594             Binder.restoreCallingIdentity(identity);
6595         }
6596     }
6597 
6598     /**
6599      * Returns the {@link IImsConfig} structure associated with the slotId and feature
6600      * specified or null if IMS is not supported on the slot specified.
6601      */
getImsConfig(int slotId, int feature)6602     public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
6603         enforceModifyPermission();
6604 
6605         final long identity = Binder.clearCallingIdentity();
6606         try {
6607             if (mImsResolver == null) {
6608                 // may happen if the device does not support IMS.
6609                 return null;
6610             }
6611             return mImsResolver.getImsConfig(slotId, feature);
6612         } finally {
6613             Binder.restoreCallingIdentity(identity);
6614         }
6615     }
6616 
6617     /**
6618      * Sets the ImsService Package Name that Telephony will bind to.
6619      *
6620      * @param slotIndex the slot ID that the ImsService should bind for.
6621      * @param isCarrierService true if the ImsService is the carrier override, false if the
6622      *         ImsService is the device default ImsService.
6623      * @param featureTypes An integer array of feature types associated with a packageName.
6624      * @param packageName The name of the package that the current configuration will be replaced
6625      *                    with.
6626      * @return true if setting the ImsService to bind to succeeded, false if it did not.
6627      */
setBoundImsServiceOverride(int slotIndex, boolean isCarrierService, int[] featureTypes, String packageName)6628     public boolean setBoundImsServiceOverride(int slotIndex, boolean isCarrierService,
6629             int[] featureTypes, String packageName) {
6630         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setBoundImsServiceOverride");
6631         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
6632                 SubscriptionManager.getSubscriptionId(slotIndex), "setBoundImsServiceOverride");
6633 
6634         final long identity = Binder.clearCallingIdentity();
6635         try {
6636             if (mImsResolver == null) {
6637                 // may happen if the device does not support IMS.
6638                 return false;
6639             }
6640             Map<Integer, String> featureConfig = new HashMap<>();
6641             for (int featureType : featureTypes) {
6642                 featureConfig.put(featureType, packageName);
6643             }
6644             return mImsResolver.overrideImsServiceConfiguration(slotIndex, isCarrierService,
6645                     featureConfig);
6646         } finally {
6647             Binder.restoreCallingIdentity(identity);
6648         }
6649     }
6650 
6651     /**
6652      * Clears any carrier ImsService overrides for the slot index specified that were previously
6653      * set with {@link #setBoundImsServiceOverride(int, boolean, int[], String)}.
6654      *
6655      * This should only be used for testing.
6656      *
6657      * @param slotIndex the slot ID that the ImsService should bind for.
6658      * @return true if clearing the carrier ImsService override succeeded or false if it did not.
6659      */
6660     @Override
clearCarrierImsServiceOverride(int slotIndex)6661     public boolean clearCarrierImsServiceOverride(int slotIndex) {
6662         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
6663                 "clearCarrierImsServiceOverride");
6664         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
6665                 SubscriptionManager.getSubscriptionId(slotIndex), "clearCarrierImsServiceOverride");
6666 
6667         final long identity = Binder.clearCallingIdentity();
6668         try {
6669             if (mImsResolver == null) {
6670                 // may happen if the device does not support IMS.
6671                 return false;
6672             }
6673             return mImsResolver.clearCarrierImsServiceConfiguration(slotIndex);
6674         } finally {
6675             Binder.restoreCallingIdentity(identity);
6676         }
6677     }
6678 
6679     /**
6680      * Return the package name of the currently bound ImsService.
6681      *
6682      * @param slotId The slot that the ImsService is associated with.
6683      * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
6684      *         the device default.
6685      * @param featureType The feature associated with the queried configuration.
6686      * @return the package name of the ImsService configuration.
6687      */
getBoundImsServicePackage(int slotId, boolean isCarrierImsService, @ImsFeature.FeatureType int featureType)6688     public String getBoundImsServicePackage(int slotId, boolean isCarrierImsService,
6689             @ImsFeature.FeatureType int featureType) {
6690         TelephonyPermissions
6691                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(mApp,
6692                         SubscriptionManager.getSubscriptionId(slotId), "getBoundImsServicePackage");
6693 
6694         final long identity = Binder.clearCallingIdentity();
6695         try {
6696             if (mImsResolver == null) {
6697                 // may happen if the device does not support IMS.
6698                 return "";
6699             }
6700             // TODO: change API to query RCS separately.
6701             return mImsResolver.getImsServiceConfiguration(slotId, isCarrierImsService,
6702                     featureType);
6703         } finally {
6704             Binder.restoreCallingIdentity(identity);
6705         }
6706     }
6707 
6708     /**
6709      * Get the MmTelFeature state associated with the requested subscription id.
6710      * @param subId The subscription that the MmTelFeature is associated with.
6711      * @param callback A callback with an integer containing the
6712      * {@link android.telephony.ims.feature.ImsFeature.ImsState} associated with the MmTelFeature.
6713      */
6714     @Override
getImsMmTelFeatureState(int subId, IIntegerConsumer callback)6715     public void getImsMmTelFeatureState(int subId, IIntegerConsumer callback) {
6716         enforceReadPrivilegedPermission("getImsMmTelFeatureState");
6717         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
6718             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
6719                     "IMS not available on device.");
6720         }
6721         final long token = Binder.clearCallingIdentity();
6722         try {
6723             int slotId = getSlotIndex(subId);
6724             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
6725                 Log.w(LOG_TAG, "getImsMmTelFeatureState: called with an inactive subscription '"
6726                         + subId + "'");
6727                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
6728             }
6729             verifyImsMmTelConfiguredOrThrow(slotId);
6730             ImsManager.getInstance(mApp, slotId).getImsServiceState(anInteger -> {
6731                 try {
6732                     callback.accept(anInteger == null ? ImsFeature.STATE_UNAVAILABLE : anInteger);
6733                 } catch (RemoteException e) {
6734                     Log.w(LOG_TAG, "getImsMmTelFeatureState: remote caller is no longer running. "
6735                             + "Ignore");
6736                 }
6737             });
6738         } catch (ImsException e) {
6739             throw new ServiceSpecificException(e.getCode());
6740         } finally {
6741             Binder.restoreCallingIdentity(token);
6742         }
6743     }
6744 
6745     /**
6746      * Sets the ims registration state on all valid {@link Phone}s.
6747      */
setImsRegistrationState(final boolean registered)6748     public void setImsRegistrationState(final boolean registered) {
6749         enforceModifyPermission();
6750 
6751         final long identity = Binder.clearCallingIdentity();
6752         try {
6753             // NOTE: Before S, this method only set the default phone.
6754             for (final Phone phone : PhoneFactory.getPhones()) {
6755                 if (SubscriptionManager.isValidSubscriptionId(phone.getSubId())) {
6756                     phone.setImsRegistrationState(registered);
6757                 }
6758             }
6759         } finally {
6760             Binder.restoreCallingIdentity(identity);
6761         }
6762     }
6763 
6764     /**
6765      * Set the network selection mode to automatic.
6766      *
6767      */
6768     @Override
setNetworkSelectionModeAutomatic(int subId)6769     public void setNetworkSelectionModeAutomatic(int subId) {
6770         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6771                 mApp, subId, "setNetworkSelectionModeAutomatic");
6772 
6773         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6774                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "setNetworkSelectionModeAutomatic");
6775 
6776         final long identity = Binder.clearCallingIdentity();
6777         try {
6778             if (!isActiveSubscription(subId)) {
6779                 return;
6780             }
6781             if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
6782             sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId,
6783                     SET_NETWORK_SELECTION_MODE_AUTOMATIC_TIMEOUT_MS);
6784         } finally {
6785             Binder.restoreCallingIdentity(identity);
6786         }
6787     }
6788 
6789     /**
6790      * Ask the radio to connect to the input network and change selection mode to manual.
6791      *
6792      * @param subId the id of the subscription.
6793      * @param operatorInfo the operator information, included the PLMN, long name and short name of
6794      * the operator to attach to.
6795      * @param persistSelection whether the selection will persist until reboot. If true, only allows
6796      * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
6797      * normal network selection next time.
6798      * @return {@code true} on success; {@code true} on any failure.
6799      */
6800     @Override
setNetworkSelectionModeManual( int subId, OperatorInfo operatorInfo, boolean persistSelection)6801     public boolean setNetworkSelectionModeManual(
6802             int subId, OperatorInfo operatorInfo, boolean persistSelection) {
6803         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6804                 mApp, subId, "setNetworkSelectionModeManual");
6805 
6806         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6807                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "setNetworkSelectionModeManual");
6808 
6809         final long identity = Binder.clearCallingIdentity();
6810         if (!isActiveSubscription(subId)) {
6811             return false;
6812         }
6813 
6814         try {
6815             ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
6816                     persistSelection);
6817             if (DBG) {
6818                 log("setNetworkSelectionModeManual: subId: " + subId
6819                         + " operator: " + operatorInfo);
6820             }
6821             return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
6822         } finally {
6823             Binder.restoreCallingIdentity(identity);
6824         }
6825     }
6826     /**
6827      * Get the manual network selection
6828      *
6829      * @param subId the id of the subscription.
6830      *
6831      * @return the previously saved user selected PLMN
6832      */
6833     @Override
getManualNetworkSelectionPlmn(int subId)6834     public String getManualNetworkSelectionPlmn(int subId) {
6835         TelephonyPermissions
6836                 .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
6837                         mApp, subId, "getManualNetworkSelectionPlmn");
6838 
6839         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6840                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getManualNetworkSelectionPlmn");
6841 
6842         final long identity = Binder.clearCallingIdentity();
6843         try {
6844             if (!isActiveSubscription(subId)) {
6845                 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
6846             }
6847 
6848             final Phone phone = getPhone(subId);
6849             if (phone == null) {
6850                 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
6851             }
6852             OperatorInfo networkSelection = phone.getSavedNetworkSelection();
6853             return TextUtils.isEmpty(networkSelection.getOperatorNumeric())
6854                     ? phone.getManualNetworkSelectionPlmn() : networkSelection.getOperatorNumeric();
6855         } finally {
6856             Binder.restoreCallingIdentity(identity);
6857         }
6858     }
6859 
6860     /**
6861      * Scans for available networks.
6862      */
6863     @Override
getCellNetworkScanResults(int subId, String callingPackage, String callingFeatureId)6864     public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage,
6865             String callingFeatureId) {
6866         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6867                 mApp, subId, "getCellNetworkScanResults");
6868         LocationAccessPolicy.LocationPermissionResult locationResult =
6869                 LocationAccessPolicy.checkLocationPermission(mApp,
6870                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
6871                                 .setCallingPackage(callingPackage)
6872                                 .setCallingFeatureId(callingFeatureId)
6873                                 .setCallingPid(Binder.getCallingPid())
6874                                 .setCallingUid(Binder.getCallingUid())
6875                                 .setMethod("getCellNetworkScanResults")
6876                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
6877                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
6878                                 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
6879                                 .build());
6880         switch (locationResult) {
6881             case DENIED_HARD:
6882                 throw new SecurityException("Not allowed to access scan results -- location");
6883             case DENIED_SOFT:
6884                 return null;
6885         }
6886 
6887         long identity = Binder.clearCallingIdentity();
6888         try {
6889             if (DBG) log("getCellNetworkScanResults: subId " + subId);
6890             return (CellNetworkScanResult) sendRequest(
6891                     CMD_PERFORM_NETWORK_SCAN, null, subId);
6892         } finally {
6893             Binder.restoreCallingIdentity(identity);
6894         }
6895     }
6896 
6897     /**
6898      * Get the call forwarding info, given the call forwarding reason.
6899      */
6900     @Override
getCallForwarding(int subId, int callForwardingReason, ICallForwardingInfoCallback callback)6901     public void getCallForwarding(int subId, int callForwardingReason,
6902             ICallForwardingInfoCallback callback) {
6903         enforceReadPrivilegedPermission("getCallForwarding");
6904 
6905         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6906                 PackageManager.FEATURE_TELEPHONY_CALLING, "getCallForwarding");
6907 
6908         long identity = Binder.clearCallingIdentity();
6909         try {
6910             if (DBG) {
6911                 log("getCallForwarding: subId " + subId
6912                         + " callForwardingReason" + callForwardingReason);
6913             }
6914 
6915             Phone phone = getPhone(subId);
6916             if (phone == null) {
6917                 try {
6918                     callback.onError(
6919                             TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
6920                 } catch (RemoteException e) {
6921                     // ignore
6922                 }
6923                 return;
6924             }
6925 
6926             Pair<Integer, TelephonyManager.CallForwardingInfoCallback> argument = Pair.create(
6927                     callForwardingReason, new TelephonyManager.CallForwardingInfoCallback() {
6928                         @Override
6929                         public void onCallForwardingInfoAvailable(CallForwardingInfo info) {
6930                             try {
6931                                 callback.onCallForwardingInfoAvailable(info);
6932                             } catch (RemoteException e) {
6933                                 // ignore
6934                             }
6935                         }
6936 
6937                         @Override
6938                         public void onError(int error) {
6939                             try {
6940                                 callback.onError(error);
6941                             } catch (RemoteException e) {
6942                                 // ignore
6943                             }
6944                         }
6945                     });
6946             sendRequestAsync(CMD_GET_CALL_FORWARDING, argument, phone, null);
6947         } finally {
6948             Binder.restoreCallingIdentity(identity);
6949         }
6950     }
6951 
6952     /**
6953      * Sets the voice call forwarding info including status (enable/disable), call forwarding
6954      * reason, the number to forward, and the timeout before the forwarding is attempted.
6955      */
6956     @Override
setCallForwarding(int subId, CallForwardingInfo callForwardingInfo, IIntegerConsumer callback)6957     public void setCallForwarding(int subId, CallForwardingInfo callForwardingInfo,
6958             IIntegerConsumer callback) {
6959         enforceModifyPermission();
6960 
6961         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6962                 PackageManager.FEATURE_TELEPHONY_CALLING, "setCallForwarding");
6963 
6964         long identity = Binder.clearCallingIdentity();
6965         try {
6966             if (DBG) {
6967                 log("setCallForwarding: subId " + subId
6968                         + " callForwardingInfo" + callForwardingInfo);
6969             }
6970 
6971             Phone phone = getPhone(subId);
6972             if (phone == null) {
6973                 try {
6974                     callback.accept(
6975                             TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
6976                 } catch (RemoteException e) {
6977                     // ignore
6978                 }
6979                 return;
6980             }
6981 
6982             Pair<CallForwardingInfo, Consumer<Integer>> arguments = Pair.create(callForwardingInfo,
6983                     FunctionalUtils.ignoreRemoteException(callback::accept));
6984 
6985             sendRequestAsync(CMD_SET_CALL_FORWARDING, arguments, phone, null);
6986         } finally {
6987             Binder.restoreCallingIdentity(identity);
6988         }
6989     }
6990 
6991     /**
6992      * Get the call waiting status for a subId.
6993      */
6994     @Override
getCallWaitingStatus(int subId, IIntegerConsumer callback)6995     public void getCallWaitingStatus(int subId, IIntegerConsumer callback) {
6996         enforceReadPrivilegedPermission("getCallWaitingStatus");
6997 
6998         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6999                 PackageManager.FEATURE_TELEPHONY_CALLING, "getCallWaitingStatus");
7000 
7001         long identity = Binder.clearCallingIdentity();
7002         try {
7003             Phone phone = getPhone(subId);
7004             if (phone == null) {
7005                 try {
7006                     callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
7007                 } catch (RemoteException e) {
7008                     // ignore
7009                 }
7010                 return;
7011             }
7012             CarrierConfigManager configManager = new CarrierConfigManager(phone.getContext());
7013             PersistableBundle c = configManager.getConfigForSubId(subId);
7014             boolean requireUssd = c.getBoolean(
7015                     CarrierConfigManager.KEY_USE_CALL_WAITING_USSD_BOOL, false);
7016 
7017             if (DBG) log("getCallWaitingStatus: subId " + subId);
7018             if (requireUssd) {
7019                 CarrierXmlParser carrierXmlParser = new CarrierXmlParser(phone.getContext(),
7020                         getSubscriptionCarrierId(subId));
7021                 String newUssdCommand = "";
7022                 try {
7023                     newUssdCommand = carrierXmlParser.getFeature(
7024                                     CarrierXmlParser.FEATURE_CALL_WAITING)
7025                             .makeCommand(CarrierXmlParser.SsEntry.SSAction.QUERY, null);
7026                 } catch (NullPointerException e) {
7027                     loge("Failed to generate USSD number" + e);
7028                 }
7029                 ResultReceiver wrappedCallback = new CallWaitingUssdResultReceiver(
7030                         mMainThreadHandler, callback, carrierXmlParser,
7031                         CarrierXmlParser.SsEntry.SSAction.QUERY);
7032                 final String ussdCommand = newUssdCommand;
7033                 Executors.newSingleThreadExecutor().execute(() -> {
7034                     handleUssdRequest(subId, ussdCommand, wrappedCallback);
7035                 });
7036             } else {
7037                 Consumer<Integer> argument = FunctionalUtils.ignoreRemoteException(
7038                         callback::accept);
7039                 sendRequestAsync(CMD_GET_CALL_WAITING, argument, phone, null);
7040             }
7041         } finally {
7042             Binder.restoreCallingIdentity(identity);
7043         }
7044     }
7045 
7046     /**
7047      * Sets whether call waiting is enabled for a given subId.
7048      */
7049     @Override
setCallWaitingStatus(int subId, boolean enable, IIntegerConsumer callback)7050     public void setCallWaitingStatus(int subId, boolean enable, IIntegerConsumer callback) {
7051         enforceModifyPermission();
7052 
7053         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7054                 PackageManager.FEATURE_TELEPHONY_CALLING, "setCallWaitingStatus");
7055 
7056         long identity = Binder.clearCallingIdentity();
7057         try {
7058             if (DBG) log("setCallWaitingStatus: subId " + subId + " enable: " + enable);
7059 
7060             Phone phone = getPhone(subId);
7061             if (phone == null) {
7062                 try {
7063                     callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
7064                 } catch (RemoteException e) {
7065                     // ignore
7066                 }
7067                 return;
7068             }
7069 
7070             CarrierConfigManager configManager = new CarrierConfigManager(phone.getContext());
7071             PersistableBundle c = configManager.getConfigForSubId(subId);
7072             boolean requireUssd = c.getBoolean(
7073                     CarrierConfigManager.KEY_USE_CALL_WAITING_USSD_BOOL, false);
7074 
7075             if (DBG) log("getCallWaitingStatus: subId " + subId);
7076             if (requireUssd) {
7077                 CarrierXmlParser carrierXmlParser = new CarrierXmlParser(phone.getContext(),
7078                         getSubscriptionCarrierId(subId));
7079                 CarrierXmlParser.SsEntry.SSAction ssAction =
7080                         enable ? CarrierXmlParser.SsEntry.SSAction.UPDATE_ACTIVATE
7081                                 : CarrierXmlParser.SsEntry.SSAction.UPDATE_DEACTIVATE;
7082                 String newUssdCommand = "";
7083                 try {
7084                     newUssdCommand = carrierXmlParser.getFeature(
7085                                     CarrierXmlParser.FEATURE_CALL_WAITING)
7086                             .makeCommand(ssAction, null);
7087                 } catch (NullPointerException e) {
7088                     loge("Failed to generate USSD number" + e);
7089                 }
7090                 ResultReceiver wrappedCallback = new CallWaitingUssdResultReceiver(
7091                         mMainThreadHandler, callback, carrierXmlParser, ssAction);
7092                 final String ussdCommand = newUssdCommand;
7093                 Executors.newSingleThreadExecutor().execute(() -> {
7094                     handleUssdRequest(subId, ussdCommand, wrappedCallback);
7095                 });
7096             } else {
7097                 Pair<Boolean, Consumer<Integer>> arguments = Pair.create(enable,
7098                         FunctionalUtils.ignoreRemoteException(callback::accept));
7099 
7100                 sendRequestAsync(CMD_SET_CALL_WAITING, arguments, phone, null);
7101             }
7102         } finally {
7103             Binder.restoreCallingIdentity(identity);
7104         }
7105     }
7106 
7107     /**
7108      * Starts a new network scan and returns the id of this scan.
7109      *
7110      * @param subId id of the subscription
7111      * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
7112      * location related information which will be sent if the caller already possess
7113      * {@android.Manifest.permission.ACCESS_FINE_LOCATION} and do not renounce the permission
7114      * @param request contains the radio access networks with bands/channels to scan
7115      * @param messenger callback messenger for scan results or errors
7116      * @param binder for the purpose of auto clean when the user thread crashes
7117      * @return the id of the requested scan which can be used to stop the scan.
7118      */
7119     @Override
requestNetworkScan(int subId, boolean renounceFineLocationAccess, NetworkScanRequest request, Messenger messenger, IBinder binder, String callingPackage, String callingFeatureId)7120     public int requestNetworkScan(int subId, boolean renounceFineLocationAccess,
7121             NetworkScanRequest request, Messenger messenger,
7122             IBinder binder, String callingPackage, String callingFeatureId) {
7123         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7124                 mApp, subId, "requestNetworkScan");
7125         LocationAccessPolicy.LocationPermissionResult locationResult =
7126                 LocationAccessPolicy.LocationPermissionResult.DENIED_HARD;
7127         if (!renounceFineLocationAccess) {
7128             locationResult = LocationAccessPolicy.checkLocationPermission(mApp,
7129                     new LocationAccessPolicy.LocationPermissionQuery.Builder()
7130                             .setCallingPackage(callingPackage)
7131                             .setCallingFeatureId(callingFeatureId)
7132                             .setCallingPid(Binder.getCallingPid())
7133                             .setCallingUid(Binder.getCallingUid())
7134                             .setMethod("requestNetworkScan")
7135                             .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
7136                             .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
7137                             .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
7138                             .build());
7139         }
7140         if (locationResult != LocationAccessPolicy.LocationPermissionResult.ALLOWED) {
7141             SecurityException e = checkNetworkRequestForSanitizedLocationAccess(
7142                     request, subId, callingPackage);
7143             if (e != null) {
7144                 if (locationResult == LocationAccessPolicy.LocationPermissionResult.DENIED_HARD) {
7145                     throw e;
7146                 } else {
7147                     loge(e.getMessage());
7148                     return TelephonyScanManager.INVALID_SCAN_ID;
7149                 }
7150             }
7151         }
7152 
7153         enforceTelephonyFeatureWithException(callingPackage,
7154                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "requestNetworkScan");
7155 
7156         int callingUid = Binder.getCallingUid();
7157         int callingPid = Binder.getCallingPid();
7158         final long identity = Binder.clearCallingIdentity();
7159         try {
7160             return mNetworkScanRequestTracker.startNetworkScan(
7161                     renounceFineLocationAccess, request, messenger, binder,
7162                     getPhoneFromSubIdOrDefault(subId),
7163                     callingUid, callingPid, callingPackage);
7164         } finally {
7165             Binder.restoreCallingIdentity(identity);
7166         }
7167     }
7168 
checkNetworkRequestForSanitizedLocationAccess( NetworkScanRequest request, int subId, String callingPackage)7169     private SecurityException checkNetworkRequestForSanitizedLocationAccess(
7170             NetworkScanRequest request, int subId, String callingPackage) {
7171         boolean hasCarrierPriv;
7172         final long identity = Binder.clearCallingIdentity();
7173         try {
7174             hasCarrierPriv = checkCarrierPrivilegesForPackage(subId, callingPackage)
7175                     == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
7176         } finally {
7177             Binder.restoreCallingIdentity(identity);
7178         }
7179         boolean hasNetworkScanPermission =
7180                 mApp.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SCAN)
7181                         == PERMISSION_GRANTED;
7182 
7183         if (!hasCarrierPriv && !hasNetworkScanPermission) {
7184             return new SecurityException("permission.NETWORK_SCAN or carrier privileges is needed"
7185                     + " for network scans without location access.");
7186         }
7187 
7188         if (request.getSpecifiers() != null && request.getSpecifiers().length > 0) {
7189             for (RadioAccessSpecifier ras : request.getSpecifiers()) {
7190                 if (ras.getChannels() != null && ras.getChannels().length > 0) {
7191                     return new SecurityException("Specific channels must not be"
7192                             + " scanned without location access.");
7193                 }
7194             }
7195         }
7196 
7197         return null;
7198     }
7199 
7200     /**
7201      * Stops an existing network scan with the given scanId.
7202      *
7203      * @param subId id of the subscription
7204      * @param scanId id of the scan that needs to be stopped
7205      */
7206     @Override
stopNetworkScan(int subId, int scanId)7207     public void stopNetworkScan(int subId, int scanId) {
7208         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7209                 mApp, subId, "stopNetworkScan");
7210 
7211         int callingUid = Binder.getCallingUid();
7212         final long identity = Binder.clearCallingIdentity();
7213         try {
7214             mNetworkScanRequestTracker.stopNetworkScan(scanId, callingUid);
7215         } finally {
7216             Binder.restoreCallingIdentity(identity);
7217         }
7218     }
7219 
7220     /**
7221      * Get the allowed network types bitmask.
7222      *
7223      * @return the allowed network types bitmask, defined in RILConstants.java.
7224      */
7225     @Override
getAllowedNetworkTypesBitmask(int subId)7226     public int getAllowedNetworkTypesBitmask(int subId) {
7227         TelephonyPermissions
7228                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
7229                         mApp, subId, "getAllowedNetworkTypesBitmask");
7230 
7231         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7232                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getAllowedNetworkTypesBitmask");
7233 
7234         final long identity = Binder.clearCallingIdentity();
7235         try {
7236             if (DBG) log("getAllowedNetworkTypesBitmask");
7237             int[] result = (int[]) sendRequest(CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK, null, subId);
7238             int networkTypesBitmask = (result != null ? result[0] : -1);
7239             if (DBG) log("getAllowedNetworkTypesBitmask: " + networkTypesBitmask);
7240             return networkTypesBitmask;
7241         } finally {
7242             Binder.restoreCallingIdentity(identity);
7243         }
7244     }
7245 
7246     /**
7247      * Get the allowed network types for certain reason.
7248      *
7249      * @param subId the id of the subscription.
7250      * @param reason the reason the allowed network type change is taking place
7251      * @return the allowed network types.
7252      */
7253     @Override
getAllowedNetworkTypesForReason(int subId, @TelephonyManager.AllowedNetworkTypesReason int reason)7254     public long getAllowedNetworkTypesForReason(int subId,
7255             @TelephonyManager.AllowedNetworkTypesReason int reason) {
7256         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
7257                 mApp, subId, "getAllowedNetworkTypesForReason");
7258 
7259         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7260                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getAllowedNetworkTypesForReason");
7261 
7262         final long identity = Binder.clearCallingIdentity();
7263         try {
7264             return getPhoneFromSubIdOrDefault(subId).getAllowedNetworkTypes(reason);
7265         } finally {
7266             Binder.restoreCallingIdentity(identity);
7267         }
7268     }
7269 
7270     /**
7271      * Enable/Disable E-UTRA-NR Dual Connectivity
7272      * @param subId subscription id of the sim card
7273      * @param nrDualConnectivityState expected NR dual connectivity state
7274      * This can be passed following states
7275      * <ol>
7276      * <li>Enable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_ENABLE}
7277      * <li>Disable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE}
7278      * <li>Disable NR dual connectivity and force secondary cell to be released
7279      * {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE}
7280      * </ol>
7281      * @return operation result.
7282      */
7283     @Override
setNrDualConnectivityState(int subId, @TelephonyManager.NrDualConnectivityState int nrDualConnectivityState)7284     public int setNrDualConnectivityState(int subId,
7285             @TelephonyManager.NrDualConnectivityState int nrDualConnectivityState) {
7286         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7287                 mApp, subId, "enableNRDualConnectivity");
7288         if (!isRadioInterfaceCapabilitySupported(
7289                 TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE)) {
7290             return TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED;
7291         }
7292 
7293         WorkSource workSource = getWorkSource(Binder.getCallingUid());
7294         final long identity = Binder.clearCallingIdentity();
7295         try {
7296             int result = (int) sendRequest(CMD_ENABLE_NR_DUAL_CONNECTIVITY,
7297                     nrDualConnectivityState, subId,
7298                     workSource);
7299             if (DBG) log("enableNRDualConnectivity result: " + result);
7300             return result;
7301         } finally {
7302             Binder.restoreCallingIdentity(identity);
7303         }
7304     }
7305 
7306     /**
7307      * Is E-UTRA-NR Dual Connectivity enabled
7308      * @return true if dual connectivity is enabled else false
7309      */
7310     @Override
isNrDualConnectivityEnabled(int subId)7311     public boolean isNrDualConnectivityEnabled(int subId) {
7312         TelephonyPermissions
7313                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
7314                         mApp, subId, "isNRDualConnectivityEnabled");
7315         if (!isRadioInterfaceCapabilitySupported(
7316                 TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE)) {
7317             return false;
7318         }
7319         WorkSource workSource = getWorkSource(Binder.getCallingUid());
7320         final long identity = Binder.clearCallingIdentity();
7321         try {
7322             boolean isEnabled = (boolean) sendRequest(CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED,
7323                     null, subId, workSource);
7324             if (DBG) log("isNRDualConnectivityEnabled: " + isEnabled);
7325             return isEnabled;
7326         } finally {
7327             Binder.restoreCallingIdentity(identity);
7328         }
7329     }
7330 
7331     /**
7332      * Set the allowed network types of the device and
7333      * provide the reason triggering the allowed network change.
7334      *
7335      * @param subId the id of the subscription.
7336      * @param reason the reason the allowed network type change is taking place
7337      * @param allowedNetworkTypes the allowed network types.
7338      * @return true on success; false on any failure.
7339      */
7340     @Override
setAllowedNetworkTypesForReason(int subId, @TelephonyManager.AllowedNetworkTypesReason int reason, @TelephonyManager.NetworkTypeBitMask long allowedNetworkTypes)7341     public boolean setAllowedNetworkTypesForReason(int subId,
7342             @TelephonyManager.AllowedNetworkTypesReason int reason,
7343             @TelephonyManager.NetworkTypeBitMask long allowedNetworkTypes) {
7344         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7345                 mApp, subId, "setAllowedNetworkTypesForReason");
7346         // If the caller only has carrier privileges, then they should not be able to override
7347         // any network types which were set for security reasons.
7348         if (mApp.checkCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE)
7349                 != PERMISSION_GRANTED
7350                 && reason == TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G) {
7351             throw new SecurityException(
7352                     "setAllowedNetworkTypesForReason cannot be called with carrier privileges for"
7353                             + " reason " + reason);
7354         }
7355 
7356         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7357                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "setAllowedNetworkTypesForReason");
7358 
7359         if (!TelephonyManager.isValidAllowedNetworkTypesReason(reason)) {
7360             loge("setAllowedNetworkTypesForReason: Invalid allowed network type reason: " + reason);
7361             return false;
7362         }
7363         if (!SubscriptionManager.isUsableSubscriptionId(subId)) {
7364             loge("setAllowedNetworkTypesForReason: Invalid subscriptionId:" + subId);
7365             return false;
7366         }
7367 
7368         log("setAllowedNetworkTypesForReason: subId=" + subId + ", reason=" + reason + " value: "
7369                 + TelephonyManager.convertNetworkTypeBitmaskToString(allowedNetworkTypes));
7370 
7371         Phone phone = getPhone(subId);
7372         if (phone == null) {
7373             return false;
7374         }
7375 
7376         if (allowedNetworkTypes == phone.getAllowedNetworkTypes(reason)) {
7377             log("setAllowedNetworkTypesForReason: " + reason + "does not change value");
7378             return true;
7379         }
7380 
7381         final long identity = Binder.clearCallingIdentity();
7382         try {
7383             Boolean success = (Boolean) sendRequest(
7384                     CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON,
7385                     new Pair<Integer, Long>(reason, allowedNetworkTypes), subId);
7386 
7387             if (DBG) log("setAllowedNetworkTypesForReason: " + (success ? "ok" : "fail"));
7388             return success;
7389         } finally {
7390             Binder.restoreCallingIdentity(identity);
7391         }
7392     }
7393 
7394     /**
7395      * Check whether DUN APN is required for tethering with subId.
7396      *
7397      * @param subId the id of the subscription to require tethering.
7398      * @return {@code true} if DUN APN is required for tethering.
7399      * @hide
7400      */
7401     @Override
isTetheringApnRequiredForSubscriber(int subId)7402     public boolean isTetheringApnRequiredForSubscriber(int subId) {
7403         enforceModifyPermission();
7404 
7405         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7406                 PackageManager.FEATURE_TELEPHONY_DATA, "isTetheringApnRequiredForSubscriber");
7407 
7408         final long identity = Binder.clearCallingIdentity();
7409         final Phone phone = getPhone(subId);
7410         try {
7411             if (phone != null) {
7412                 return phone.hasMatchedTetherApnSetting();
7413             } else {
7414                 return false;
7415             }
7416         } finally {
7417             Binder.restoreCallingIdentity(identity);
7418         }
7419     }
7420 
7421     /**
7422      * Get the user enabled state of Mobile Data.
7423      *
7424      * TODO: remove and use isUserDataEnabled.
7425      * This can't be removed now because some vendor codes
7426      * calls through ITelephony directly while they should
7427      * use TelephonyManager.
7428      *
7429      * @return true on enabled
7430      */
7431     @Override
getDataEnabled(int subId)7432     public boolean getDataEnabled(int subId) {
7433         return isUserDataEnabled(subId);
7434     }
7435 
7436     /**
7437      * Get whether mobile data is enabled per user setting.
7438      *
7439      * There are other factors deciding whether mobile data is actually enabled, but they are
7440      * not considered here. See {@link #isDataEnabled(int)} for more details.
7441      *
7442      * Accepts either READ_BASIC_PHONE_STATE, ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE
7443      * or carrier privileges.
7444      *
7445      * @return {@code true} if data is enabled else {@code false}
7446      */
7447     @Override
isUserDataEnabled(int subId)7448     public boolean isUserDataEnabled(int subId) {
7449         String functionName = "isUserDataEnabled";
7450         try {
7451             try {
7452                 mApp.enforceCallingOrSelfPermission(permission.READ_BASIC_PHONE_STATE,
7453                         functionName);
7454             } catch (SecurityException e) {
7455                 mApp.enforceCallingOrSelfPermission(permission.ACCESS_NETWORK_STATE, functionName);
7456             }
7457         } catch (SecurityException e) {
7458             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7459                     mApp, subId, functionName);
7460 
7461         }
7462 
7463         final long identity = Binder.clearCallingIdentity();
7464         try {
7465             int phoneId = SubscriptionManager.getPhoneId(subId);
7466             if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
7467             Phone phone = PhoneFactory.getPhone(phoneId);
7468             if (phone != null) {
7469                 boolean retVal = phone.isUserDataEnabled();
7470                 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
7471                 return retVal;
7472             } else {
7473                 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
7474                 return false;
7475             }
7476         } finally {
7477             Binder.restoreCallingIdentity(identity);
7478         }
7479     }
7480 
7481     /**
7482      * Checks if the device is capable of mobile data by considering whether whether the
7483      * user has enabled mobile data, whether the carrier has enabled mobile data, and
7484      * whether the network policy allows data connections.
7485      *
7486      * @return {@code true} if the overall data connection is capable; {@code false} if not.
7487      */
7488     @Override
isDataEnabled(int subId)7489     public boolean isDataEnabled(int subId) {
7490         String functionName = "isDataEnabled";
7491         try {
7492             try {
7493                 mApp.enforceCallingOrSelfPermission(
7494                         android.Manifest.permission.ACCESS_NETWORK_STATE,
7495                         functionName);
7496             } catch (SecurityException e) {
7497                 try {
7498                     mApp.enforceCallingOrSelfPermission(
7499                             android.Manifest.permission.READ_PHONE_STATE,
7500                             functionName);
7501                 } catch (SecurityException e2) {
7502                     mApp.enforceCallingOrSelfPermission(
7503                             permission.READ_BASIC_PHONE_STATE, functionName);
7504                 }
7505             }
7506         } catch (SecurityException e) {
7507             enforceReadPrivilegedPermission(functionName);
7508         }
7509 
7510         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7511                 PackageManager.FEATURE_TELEPHONY_DATA, "isDataEnabled");
7512 
7513         final long identity = Binder.clearCallingIdentity();
7514         try {
7515             int phoneId = SubscriptionManager.getPhoneId(subId);
7516             Phone phone = PhoneFactory.getPhone(phoneId);
7517             if (phone != null) {
7518                 boolean retVal = phone.getDataSettingsManager().isDataEnabled();
7519                 if (DBG) log("isDataEnabled: " + retVal + ", subId=" + subId);
7520                 return retVal;
7521             } else {
7522                 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
7523                 return false;
7524             }
7525         } finally {
7526             Binder.restoreCallingIdentity(identity);
7527         }
7528     }
7529 
7530     /**
7531      * Check if data is enabled for a specific reason
7532      * @param subId Subscription index
7533      * @param reason the reason the data enable change is taking place
7534      * @return {@code true} if the overall data is enabled; {@code false} if not.
7535      */
7536     @Override
isDataEnabledForReason(int subId, @TelephonyManager.DataEnabledReason int reason)7537     public boolean isDataEnabledForReason(int subId,
7538             @TelephonyManager.DataEnabledReason int reason) {
7539         String functionName = "isDataEnabledForReason";
7540         try {
7541             try {
7542                 mApp.enforceCallingOrSelfPermission(
7543                         android.Manifest.permission.ACCESS_NETWORK_STATE,
7544                         functionName);
7545             } catch (SecurityException e) {
7546                 mApp.enforceCallingOrSelfPermission(permission.READ_BASIC_PHONE_STATE,
7547                         functionName);
7548             }
7549         } catch (SecurityException e) {
7550             try {
7551                 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
7552                         functionName);
7553             } catch (SecurityException e2) {
7554                 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7555                         mApp, subId, functionName);
7556             }
7557         }
7558 
7559         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7560                 PackageManager.FEATURE_TELEPHONY_DATA, "isDataEnabledForReason");
7561 
7562         final long identity = Binder.clearCallingIdentity();
7563         try {
7564             int phoneId = SubscriptionManager.getPhoneId(subId);
7565             if (DBG) {
7566                 log("isDataEnabledForReason: subId=" + subId + " phoneId=" + phoneId
7567                         + " reason=" + reason);
7568             }
7569             Phone phone = PhoneFactory.getPhone(phoneId);
7570             if (phone != null) {
7571                 boolean retVal;
7572                 retVal = phone.getDataSettingsManager().isDataEnabledForReason(reason);
7573                 if (DBG) log("isDataEnabledForReason: retVal=" + retVal);
7574                 return retVal;
7575             } else {
7576                 if (DBG) {
7577                     loge("isDataEnabledForReason: no phone subId="
7578                             + subId + " retVal=false");
7579                 }
7580                 return false;
7581             }
7582         } finally {
7583             Binder.restoreCallingIdentity(identity);
7584         }
7585     }
7586 
7587     @Override
getCarrierPrivilegeStatus(int subId)7588     public int getCarrierPrivilegeStatus(int subId) {
7589         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7590                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getCarrierPrivilegeStatus");
7591 
7592         // No permission needed; this only lets the caller inspect their own status.
7593         return getCarrierPrivilegeStatusForUidWithPermission(subId, Binder.getCallingUid());
7594     }
7595 
7596     @Override
getCarrierPrivilegeStatusForUid(int subId, int uid)7597     public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
7598         enforceReadPrivilegedPermission("getCarrierPrivilegeStatusForUid");
7599 
7600         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7601                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getCarrierPrivilegeStatusForUid");
7602 
7603         return getCarrierPrivilegeStatusForUidWithPermission(subId, uid);
7604     }
7605 
getCarrierPrivilegeStatusForUidWithPermission(int subId, int uid)7606     private int getCarrierPrivilegeStatusForUidWithPermission(int subId, int uid) {
7607         Phone phone = getPhone(subId);
7608         if (phone == null) {
7609             loge("getCarrierPrivilegeStatusForUid: Invalid subId");
7610             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
7611         }
7612         CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7613         if (cpt == null) {
7614             loge("getCarrierPrivilegeStatusForUid: No CarrierPrivilegesTracker");
7615             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
7616         }
7617         return cpt.getCarrierPrivilegeStatusForUid(uid);
7618     }
7619 
7620     @Override
checkCarrierPrivilegesForPackage(int subId, String pkgName)7621     public int checkCarrierPrivilegesForPackage(int subId, String pkgName) {
7622         enforceReadPrivilegedPermission("checkCarrierPrivilegesForPackage");
7623 
7624         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7625                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "checkCarrierPrivilegesForPackage");
7626 
7627         if (TextUtils.isEmpty(pkgName)) {
7628             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
7629         }
7630         Phone phone = getPhone(subId);
7631         if (phone == null) {
7632             loge("checkCarrierPrivilegesForPackage: Invalid subId");
7633             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
7634         }
7635         CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7636         if (cpt == null) {
7637             loge("checkCarrierPrivilegesForPackage: No CarrierPrivilegesTracker");
7638             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
7639         }
7640         return cpt.getCarrierPrivilegeStatusForPackage(pkgName);
7641     }
7642 
7643     @Override
checkCarrierPrivilegesForPackageAnyPhone(String pkgName)7644     public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
7645         enforceReadPrivilegedPermission("checkCarrierPrivilegesForPackageAnyPhone");
7646 
7647         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7648                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
7649                 "checkCarrierPrivilegesForPackageAnyPhone");
7650 
7651         return checkCarrierPrivilegesForPackageAnyPhoneWithPermission(pkgName);
7652     }
7653 
checkCarrierPrivilegesForPackageAnyPhoneWithPermission(String pkgName)7654     private int checkCarrierPrivilegesForPackageAnyPhoneWithPermission(String pkgName) {
7655         if (TextUtils.isEmpty(pkgName)) {
7656             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
7657         }
7658         int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
7659         for (int phoneId = 0; phoneId < TelephonyManager.getDefault().getPhoneCount(); phoneId++) {
7660             Phone phone = PhoneFactory.getPhone(phoneId);
7661             if (phone == null) {
7662                 continue;
7663             }
7664             CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7665             if (cpt == null) {
7666                 continue;
7667             }
7668             result = cpt.getCarrierPrivilegeStatusForPackage(pkgName);
7669             if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
7670                 break;
7671             }
7672         }
7673         return result;
7674     }
7675 
7676     @Override
getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId)7677     public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
7678         enforceReadPrivilegedPermission("getCarrierPackageNamesForIntentAndPhone");
7679 
7680         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7681                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
7682                 "getCarrierPackageNamesForIntentAndPhone");
7683 
7684         Phone phone = PhoneFactory.getPhone(phoneId);
7685         if (phone == null) {
7686             return Collections.emptyList();
7687         }
7688         CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7689         if (cpt == null) {
7690             return Collections.emptyList();
7691         }
7692         return cpt.getCarrierPackageNamesForIntent(intent);
7693     }
7694 
7695     @Override
getPackagesWithCarrierPrivileges(int phoneId)7696     public List<String> getPackagesWithCarrierPrivileges(int phoneId) {
7697         enforceReadPrivilegedPermission("getPackagesWithCarrierPrivileges");
7698         Phone phone = PhoneFactory.getPhone(phoneId);
7699         if (phone == null) {
7700             return Collections.emptyList();
7701         }
7702         CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7703         if (cpt == null) {
7704             return Collections.emptyList();
7705         }
7706         return new ArrayList<>(cpt.getPackagesWithCarrierPrivileges());
7707     }
7708 
7709     @Override
getPackagesWithCarrierPrivilegesForAllPhones()7710     public List<String> getPackagesWithCarrierPrivilegesForAllPhones() {
7711         enforceReadPrivilegedPermission("getPackagesWithCarrierPrivilegesForAllPhones");
7712 
7713         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7714                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
7715                 "getPackagesWithCarrierPrivilegesForAllPhones");
7716 
7717         Set<String> privilegedPackages = new ArraySet<>();
7718         final long identity = Binder.clearCallingIdentity();
7719         try {
7720             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
7721                 privilegedPackages.addAll(getPackagesWithCarrierPrivileges(i));
7722             }
7723         } finally {
7724             Binder.restoreCallingIdentity(identity);
7725         }
7726         return new ArrayList<>(privilegedPackages);
7727     }
7728 
7729     @Override
getCarrierServicePackageNameForLogicalSlot(int logicalSlotIndex)7730     public @Nullable String getCarrierServicePackageNameForLogicalSlot(int logicalSlotIndex) {
7731         enforceReadPrivilegedPermission("getCarrierServicePackageNameForLogicalSlot");
7732 
7733         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7734                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
7735                 "getCarrierServicePackageNameForLogicalSlot");
7736 
7737         final Phone phone = PhoneFactory.getPhone(logicalSlotIndex);
7738         if (phone == null) {
7739             return null;
7740         }
7741         final CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7742         if (cpt == null) {
7743             return null;
7744         }
7745         return cpt.getCarrierServicePackageName();
7746     }
7747 
getIccId(int subId)7748     private String getIccId(int subId) {
7749         final Phone phone = getPhone(subId);
7750         UiccPort port = phone == null ? null : phone.getUiccPort();
7751         if (port == null) {
7752             return null;
7753         }
7754         String iccId = port.getIccId();
7755         if (TextUtils.isEmpty(iccId)) {
7756             return null;
7757         }
7758         return iccId;
7759     }
7760 
7761     @Override
setCallComposerStatus(int subId, int status)7762     public void setCallComposerStatus(int subId, int status) {
7763         enforceModifyPermission();
7764 
7765         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7766                 PackageManager.FEATURE_TELEPHONY_CALLING, "setCallComposerStatus");
7767 
7768         final long identity = Binder.clearCallingIdentity();
7769         try {
7770             Phone phone = getPhone(subId);
7771             if (phone != null) {
7772                 Phone defaultPhone = phone.getImsPhone();
7773                 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
7774                     ImsPhone imsPhone = (ImsPhone) defaultPhone;
7775                     imsPhone.setCallComposerStatus(status);
7776                     ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
7777                             .updateImsServiceConfig();
7778                 }
7779             }
7780         } catch (ImsException e) {
7781             throw new ServiceSpecificException(e.getCode());
7782         }  finally {
7783             Binder.restoreCallingIdentity(identity);
7784         }
7785     }
7786 
7787     @Override
getCallComposerStatus(int subId)7788     public int getCallComposerStatus(int subId) {
7789         enforceReadPrivilegedPermission("getCallComposerStatus");
7790 
7791         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7792                 PackageManager.FEATURE_TELEPHONY_CALLING, "getCallComposerStatus");
7793 
7794         final long identity = Binder.clearCallingIdentity();
7795         try {
7796             Phone phone = getPhone(subId);
7797             if (phone != null) {
7798                 Phone defaultPhone = phone.getImsPhone();
7799                 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
7800                     ImsPhone imsPhone = (ImsPhone) defaultPhone;
7801                     return imsPhone.getCallComposerStatus();
7802                 }
7803             }
7804         } finally {
7805             Binder.restoreCallingIdentity(identity);
7806         }
7807         return TelephonyManager.CALL_COMPOSER_STATUS_OFF;
7808     }
7809 
7810     @Override
setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, String number)7811     public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
7812             String number) {
7813         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
7814                 subId, "setLine1NumberForDisplayForSubscriber");
7815 
7816         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7817                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
7818                 "setLine1NumberForDisplayForSubscriber");
7819 
7820         final long identity = Binder.clearCallingIdentity();
7821         try {
7822             final String iccId = getIccId(subId);
7823             final Phone phone = getPhone(subId);
7824             if (phone == null) {
7825                 return false;
7826             }
7827             final String subscriberId = phone.getSubscriberId();
7828 
7829             if (DBG_MERGE) {
7830                 Rlog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
7831                         + subscriberId + " to " + number);
7832             }
7833 
7834             if (TextUtils.isEmpty(iccId)) {
7835                 return false;
7836             }
7837 
7838             final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
7839 
7840             final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
7841             if (alphaTag == null) {
7842                 editor.remove(alphaTagPrefKey);
7843             } else {
7844                 editor.putString(alphaTagPrefKey, alphaTag);
7845             }
7846 
7847             // Record both the line number and IMSI for this ICCID, since we need to
7848             // track all merged IMSIs based on line number
7849             final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
7850             final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
7851             if (number == null) {
7852                 editor.remove(numberPrefKey);
7853                 editor.remove(subscriberPrefKey);
7854             } else {
7855                 editor.putString(numberPrefKey, number);
7856                 editor.putString(subscriberPrefKey, subscriberId);
7857             }
7858 
7859             editor.commit();
7860             return true;
7861         } finally {
7862             Binder.restoreCallingIdentity(identity);
7863         }
7864     }
7865 
7866     @Override
getLine1NumberForDisplay(int subId, String callingPackage, String callingFeatureId)7867     public String getLine1NumberForDisplay(int subId, String callingPackage,
7868             String callingFeatureId) {
7869         // This is open to apps with WRITE_SMS.
7870         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
7871                 mApp, subId, callingPackage, callingFeatureId, "getLine1NumberForDisplay")) {
7872             if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
7873             return null;
7874         }
7875 
7876         enforceTelephonyFeatureWithException(callingPackage,
7877                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getLine1NumberForDisplay");
7878 
7879         final long identity = Binder.clearCallingIdentity();
7880         try {
7881             String iccId = getIccId(subId);
7882             if (iccId != null) {
7883                 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
7884                 if (DBG_MERGE) {
7885                     log("getLine1NumberForDisplay returning "
7886                             + mTelephonySharedPreferences.getString(numberPrefKey, null));
7887                 }
7888                 return mTelephonySharedPreferences.getString(numberPrefKey, null);
7889             }
7890             if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
7891             return null;
7892         } finally {
7893             Binder.restoreCallingIdentity(identity);
7894         }
7895     }
7896 
7897     @Override
getLine1AlphaTagForDisplay(int subId, String callingPackage, String callingFeatureId)7898     public String getLine1AlphaTagForDisplay(int subId, String callingPackage,
7899             String callingFeatureId) {
7900         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
7901                 mApp, subId, callingPackage, callingFeatureId, "getLine1AlphaTagForDisplay")) {
7902             return null;
7903         }
7904 
7905         final long identity = Binder.clearCallingIdentity();
7906         try {
7907             String iccId = getIccId(subId);
7908             if (iccId != null) {
7909                 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
7910                 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
7911             }
7912             return null;
7913         } finally {
7914             Binder.restoreCallingIdentity(identity);
7915         }
7916     }
7917 
7918     @Override
getMergedSubscriberIds(int subId, String callingPackage, String callingFeatureId)7919     public String[] getMergedSubscriberIds(int subId, String callingPackage,
7920             String callingFeatureId) {
7921         // This API isn't public, so no need to provide a valid subscription ID - we're not worried
7922         // about carrier-privileged callers not having access.
7923         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
7924                 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
7925                 callingFeatureId, "getMergedSubscriberIds")) {
7926             return null;
7927         }
7928 
7929         // Clear calling identity, when calling TelephonyManager, because callerUid must be
7930         // the process, where TelephonyManager was instantiated.
7931         // Otherwise AppOps check will fail.
7932         final long identity  = Binder.clearCallingIdentity();
7933         try {
7934             final Context context = mApp;
7935             final TelephonyManager tele = TelephonyManager.from(context);
7936             final SubscriptionManager sub = SubscriptionManager.from(context);
7937 
7938             // Figure out what subscribers are currently active
7939             final ArraySet<String> activeSubscriberIds = new ArraySet<>();
7940 
7941             // Only consider subs which match the current subId
7942             // This logic can be simplified. See b/131189269 for progress.
7943             if (isActiveSubscription(subId)) {
7944                 activeSubscriberIds.add(tele.getSubscriberId(subId));
7945             }
7946 
7947             // First pass, find a number override for an active subscriber
7948             String mergeNumber = null;
7949             final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
7950             for (String key : prefs.keySet()) {
7951                 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
7952                     final String subscriberId = (String) prefs.get(key);
7953                     if (activeSubscriberIds.contains(subscriberId)) {
7954                         final String iccId = key.substring(
7955                                 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
7956                         final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
7957                         mergeNumber = (String) prefs.get(numberKey);
7958                         if (DBG_MERGE) {
7959                             Rlog.d(LOG_TAG, "Found line number " + mergeNumber
7960                                     + " for active subscriber " + subscriberId);
7961                         }
7962                         if (!TextUtils.isEmpty(mergeNumber)) {
7963                             break;
7964                         }
7965                     }
7966                 }
7967             }
7968 
7969             // Shortcut when no active merged subscribers
7970             if (TextUtils.isEmpty(mergeNumber)) {
7971                 return null;
7972             }
7973 
7974             // Second pass, find all subscribers under that line override
7975             final ArraySet<String> result = new ArraySet<>();
7976             for (String key : prefs.keySet()) {
7977                 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
7978                     final String number = (String) prefs.get(key);
7979                     if (mergeNumber.equals(number)) {
7980                         final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
7981                         final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
7982                         final String subscriberId = (String) prefs.get(subscriberKey);
7983                         if (!TextUtils.isEmpty(subscriberId)) {
7984                             result.add(subscriberId);
7985                         }
7986                     }
7987                 }
7988             }
7989 
7990             final String[] resultArray = result.toArray(new String[result.size()]);
7991             Arrays.sort(resultArray);
7992             if (DBG_MERGE) {
7993                 Rlog.d(LOG_TAG,
7994                         "Found subscribers " + Arrays.toString(resultArray) + " after merge");
7995             }
7996             return resultArray;
7997         } finally {
7998             Binder.restoreCallingIdentity(identity);
7999         }
8000     }
8001 
8002     @Override
getMergedImsisFromGroup(int subId, String callingPackage)8003     public String[] getMergedImsisFromGroup(int subId, String callingPackage) {
8004         enforceReadPrivilegedPermission("getMergedImsisFromGroup");
8005 
8006         enforceTelephonyFeatureWithException(callingPackage,
8007                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getMergedImsisFromGroup");
8008 
8009         final long identity = Binder.clearCallingIdentity();
8010         try {
8011             final TelephonyManager telephonyManager = mApp.getSystemService(
8012                     TelephonyManager.class);
8013             String subscriberId = telephonyManager.getSubscriberId(subId);
8014             if (subscriberId == null) {
8015                 if (DBG) {
8016                     log("getMergedImsisFromGroup can't find subscriberId for subId "
8017                             + subId);
8018                 }
8019                 return null;
8020             }
8021 
8022             final SubscriptionInfo info = getSubscriptionManagerService()
8023                     .getSubscriptionInfo(subId);
8024             ParcelUuid groupUuid = info.getGroupUuid();
8025             // If it doesn't belong to any group, return just subscriberId of itself.
8026             if (groupUuid == null) {
8027                 return new String[]{subscriberId};
8028             }
8029 
8030             // Get all subscriberIds from the group.
8031             final List<String> mergedSubscriberIds = new ArrayList<>();
8032             List<SubscriptionInfo> groupInfos = getSubscriptionManagerService()
8033                     .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
8034                             mApp.getAttributionTag());
8035             for (SubscriptionInfo subInfo : groupInfos) {
8036                 subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
8037                 if (subscriberId != null) {
8038                     mergedSubscriberIds.add(subscriberId);
8039                 }
8040             }
8041 
8042             return mergedSubscriberIds.toArray(new String[mergedSubscriberIds.size()]);
8043         } finally {
8044             Binder.restoreCallingIdentity(identity);
8045 
8046         }
8047     }
8048 
8049     @Override
setOperatorBrandOverride(int subId, String brand)8050     public boolean setOperatorBrandOverride(int subId, String brand) {
8051         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
8052                 subId, "setOperatorBrandOverride");
8053 
8054         enforceTelephonyFeatureWithException(getCurrentPackageName(),
8055                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "setOperatorBrandOverride");
8056 
8057         final long identity = Binder.clearCallingIdentity();
8058         try {
8059             final Phone phone = getPhone(subId);
8060             return phone == null ? false : phone.setOperatorBrandOverride(brand);
8061         } finally {
8062             Binder.restoreCallingIdentity(identity);
8063         }
8064     }
8065 
8066     @Override
setRoamingOverride(int subId, List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList)8067     public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
8068             List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
8069             List<String> cdmaNonRoamingList) {
8070         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
8071                 mApp, subId, "setRoamingOverride");
8072 
8073         final long identity = Binder.clearCallingIdentity();
8074         try {
8075             final Phone phone = getPhone(subId);
8076             if (phone == null) {
8077                 return false;
8078             }
8079             return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
8080                     cdmaNonRoamingList);
8081         } finally {
8082             Binder.restoreCallingIdentity(identity);
8083         }
8084     }
8085 
8086     @Override
getRadioAccessFamily(int phoneId, String callingPackage)8087     public int getRadioAccessFamily(int phoneId, String callingPackage) {
8088         int raf = RadioAccessFamily.RAF_UNKNOWN;
8089         Phone phone = PhoneFactory.getPhone(phoneId);
8090         if (phone == null) {
8091             return raf;
8092         }
8093 
8094         try {
8095             TelephonyPermissions
8096                     .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
8097                             mApp, phone.getSubId(), "getRadioAccessFamily");
8098         } catch (SecurityException e) {
8099             EventLog.writeEvent(0x534e4554, "150857259", -1, "Missing Permission");
8100             throw e;
8101         }
8102 
8103         enforceTelephonyFeatureWithException(callingPackage,
8104                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getRadioAccessFamily");
8105 
8106         final long identity = Binder.clearCallingIdentity();
8107         try {
8108             raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
8109         } finally {
8110             Binder.restoreCallingIdentity(identity);
8111         }
8112         return raf;
8113     }
8114 
8115     @Override
uploadCallComposerPicture(int subscriptionId, String callingPackage, String contentType, ParcelFileDescriptor fd, ResultReceiver callback)8116     public void uploadCallComposerPicture(int subscriptionId, String callingPackage,
8117             String contentType, ParcelFileDescriptor fd, ResultReceiver callback) {
8118         try {
8119             if (!Objects.equals(mApp.getPackageManager().getPackageUid(callingPackage, 0),
8120                     Binder.getCallingUid())) {
8121                 throw new SecurityException("Invalid package:" + callingPackage);
8122             }
8123         } catch (PackageManager.NameNotFoundException e) {
8124             throw new SecurityException("Invalid package:" + callingPackage);
8125         }
8126 
8127         enforceTelephonyFeatureWithException(callingPackage,
8128                 PackageManager.FEATURE_TELEPHONY_CALLING, "uploadCallComposerPicture");
8129 
8130         RoleManager rm = mApp.getSystemService(RoleManager.class);
8131         List<String> dialerRoleHolders = rm.getRoleHolders(RoleManager.ROLE_DIALER);
8132         if (!dialerRoleHolders.contains(callingPackage)) {
8133             throw new SecurityException("App must be the dialer role holder to"
8134                     + " upload a call composer pic");
8135         }
8136 
8137         Executors.newSingleThreadExecutor().execute(() -> {
8138             ByteArrayOutputStream output = new ByteArrayOutputStream(
8139                     (int) TelephonyManager.getMaximumCallComposerPictureSize());
8140             InputStream input = new ParcelFileDescriptor.AutoCloseInputStream(fd);
8141             boolean readUntilEnd = false;
8142             int totalBytesRead = 0;
8143             byte[] buffer = new byte[16 * 1024];
8144             while (true) {
8145                 int numRead;
8146                 try {
8147                     numRead = input.read(buffer);
8148                 } catch (IOException e) {
8149                     try {
8150                         fd.checkError();
8151                         callback.send(TelephonyManager.CallComposerException.ERROR_INPUT_CLOSED,
8152                                 null);
8153                     } catch (IOException e1) {
8154                         // This means that the other side closed explicitly with an error. If this
8155                         // happens, log and ignore.
8156                         loge("Remote end of call composer picture pipe closed: " + e1);
8157                     }
8158                     break;
8159                 }
8160                 if (numRead == -1) {
8161                     readUntilEnd = true;
8162                     break;
8163                 }
8164                 totalBytesRead += numRead;
8165                 if (totalBytesRead > TelephonyManager.getMaximumCallComposerPictureSize()) {
8166                     loge("Too many bytes read for call composer picture: " + totalBytesRead);
8167                     try {
8168                         input.close();
8169                     } catch (IOException e) {
8170                         // ignore
8171                     }
8172                     break;
8173                 }
8174                 output.write(buffer, 0, numRead);
8175             }
8176             // Generally, the remote end will close the file descriptors. The only case where we
8177             // close is above, where the picture size is too big.
8178 
8179             try {
8180                 fd.checkError();
8181             } catch (IOException e) {
8182                 loge("Remote end for call composer closed with an error: " + e);
8183                 return;
8184             }
8185 
8186             if (!readUntilEnd) {
8187                 loge("Did not finish reading entire image; aborting");
8188                 return;
8189             }
8190 
8191             ImageData imageData = new ImageData(output.toByteArray(), contentType, null);
8192             CallComposerPictureManager.getInstance(mApp, subscriptionId).handleUploadToServer(
8193                     new CallComposerPictureTransfer.Factory() {},
8194                     imageData,
8195                     (result) -> {
8196                         if (result.first != null) {
8197                             ParcelUuid parcelUuid = new ParcelUuid(result.first);
8198                             Bundle outputResult = new Bundle();
8199                             outputResult.putParcelable(
8200                                     TelephonyManager.KEY_CALL_COMPOSER_PICTURE_HANDLE, parcelUuid);
8201                             callback.send(TelephonyManager.CallComposerException.SUCCESS,
8202                                     outputResult);
8203                         } else {
8204                             callback.send(result.second, null);
8205                         }
8206                     }
8207             );
8208         });
8209     }
8210 
8211     @Override
enableVideoCalling(boolean enable)8212     public void enableVideoCalling(boolean enable) {
8213         final Phone defaultPhone = getDefaultPhone();
8214         enforceModifyPermission();
8215 
8216         enforceTelephonyFeatureWithException(getCurrentPackageName(),
8217                 PackageManager.FEATURE_TELEPHONY_IMS, "enableVideoCalling");
8218 
8219         final long identity = Binder.clearCallingIdentity();
8220         try {
8221             ImsManager.getInstance(defaultPhone.getContext(),
8222                     defaultPhone.getPhoneId()).setVtSetting(enable);
8223         } finally {
8224             Binder.restoreCallingIdentity(identity);
8225         }
8226     }
8227 
8228     @Override
isVideoCallingEnabled(String callingPackage, String callingFeatureId)8229     public boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId) {
8230         final Phone defaultPhone = getDefaultPhone();
8231         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
8232                 callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
8233             return false;
8234         }
8235 
8236         enforceTelephonyFeatureWithException(callingPackage,
8237                 PackageManager.FEATURE_TELEPHONY_IMS, "isVideoCallingEnabled");
8238 
8239         final long identity = Binder.clearCallingIdentity();
8240         try {
8241             // Check the user preference and the  system-level IMS setting. Even if the user has
8242             // enabled video calling, if IMS is disabled we aren't able to support video calling.
8243             // In the long run, we may instead need to check if there exists a connection service
8244             // which can support video calling.
8245             ImsManager imsManager =
8246                     ImsManager.getInstance(defaultPhone.getContext(), defaultPhone.getPhoneId());
8247             return imsManager.isVtEnabledByPlatform()
8248                     && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
8249                     && imsManager.isVtEnabledByUser();
8250         } finally {
8251             Binder.restoreCallingIdentity(identity);
8252         }
8253     }
8254 
8255     @Override
canChangeDtmfToneLength(int subId, String callingPackage, String callingFeatureId)8256     public boolean canChangeDtmfToneLength(int subId, String callingPackage,
8257             String callingFeatureId) {
8258         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
8259                 mApp, subId, callingPackage, callingFeatureId,
8260                 "isVideoCallingEnabled")) {
8261             return false;
8262         }
8263 
8264         enforceTelephonyFeatureWithException(callingPackage,
8265                 PackageManager.FEATURE_TELEPHONY_CALLING, "canChangeDtmfToneLength");
8266 
8267         final long identity = Binder.clearCallingIdentity();
8268         try {
8269             CarrierConfigManager configManager =
8270                     (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
8271             return configManager.getConfigForSubId(subId)
8272                     .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
8273         } finally {
8274             Binder.restoreCallingIdentity(identity);
8275         }
8276     }
8277 
8278     @Override
isWorldPhone(int subId, String callingPackage, String callingFeatureId)8279     public boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId) {
8280         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
8281                 mApp, subId, callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
8282             return false;
8283         }
8284 
8285         enforceTelephonyFeatureWithException(callingPackage,
8286                 PackageManager.FEATURE_TELEPHONY, "isWorldPhone");
8287 
8288         final long identity = Binder.clearCallingIdentity();
8289         try {
8290             CarrierConfigManager configManager =
8291                     (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
8292             return configManager.getConfigForSubId(subId)
8293                     .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
8294         } finally {
8295             Binder.restoreCallingIdentity(identity);
8296         }
8297     }
8298 
8299     @Override
isTtyModeSupported()8300     public boolean isTtyModeSupported() {
8301         TelecomManager telecomManager = mApp.getSystemService(TelecomManager.class);
8302         return telecomManager.isTtySupported();
8303     }
8304 
8305     @Override
isHearingAidCompatibilitySupported()8306     public boolean isHearingAidCompatibilitySupported() {
8307         enforceTelephonyFeatureWithException(getCurrentPackageName(),
8308                 PackageManager.FEATURE_TELEPHONY_CALLING, "isHearingAidCompatibilitySupported");
8309 
8310         final long identity = Binder.clearCallingIdentity();
8311         try {
8312             return mApp.getResources().getBoolean(R.bool.hac_enabled);
8313         } finally {
8314             Binder.restoreCallingIdentity(identity);
8315         }
8316     }
8317 
8318     /**
8319      * Determines whether the device currently supports RTT (Real-time text). Based both on carrier
8320      * support for the feature and device firmware support.
8321      *
8322      * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
8323      */
8324     @Override
isRttSupported(int subscriptionId)8325     public boolean isRttSupported(int subscriptionId) {
8326         enforceTelephonyFeatureWithException(getCurrentPackageName(),
8327                 PackageManager.FEATURE_TELEPHONY_IMS, "isRttSupported");
8328 
8329         final long identity = Binder.clearCallingIdentity();
8330         final Phone phone = getPhone(subscriptionId);
8331         if (phone == null) {
8332             loge("isRttSupported: no Phone found. Invalid subId:" + subscriptionId);
8333             return false;
8334         }
8335         try {
8336             boolean isCarrierSupported = mApp.getCarrierConfigForSubId(subscriptionId).getBoolean(
8337                     CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
8338             boolean isDeviceSupported = (phone.getContext().getResources() != null)
8339                     ? phone.getContext().getResources().getBoolean(R.bool.config_support_rtt)
8340                     : false;
8341             return isCarrierSupported && isDeviceSupported;
8342         } finally {
8343             Binder.restoreCallingIdentity(identity);
8344         }
8345     }
8346 
8347     /**
8348      * Determines whether the user has turned on RTT. If the carrier wants to ignore the user-set
8349      * RTT setting, will return true if the device and carrier both support RTT.
8350      * Otherwise. only returns true if the device and carrier both also support RTT.
8351      */
isRttEnabled(int subscriptionId)8352     public boolean isRttEnabled(int subscriptionId) {
8353         final long identity = Binder.clearCallingIdentity();
8354         try {
8355             if (mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()) {
8356                 if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS)) {
8357                     return false;
8358                 }
8359             }
8360 
8361             boolean isRttSupported = isRttSupported(subscriptionId);
8362             boolean isUserRttSettingOn = Settings.Secure.getInt(
8363                     mApp.getContentResolver(), Settings.Secure.RTT_CALLING_MODE, 0) != 0;
8364             boolean shouldIgnoreUserRttSetting = mApp.getCarrierConfigForSubId(subscriptionId)
8365                     .getBoolean(CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL);
8366             return isRttSupported && (isUserRttSettingOn || shouldIgnoreUserRttSetting);
8367         } finally {
8368             Binder.restoreCallingIdentity(identity);
8369         }
8370     }
8371 
8372     @Deprecated
8373     @Override
getDeviceId(String callingPackage)8374     public String getDeviceId(String callingPackage) {
8375         return getDeviceIdWithFeature(callingPackage, null);
8376     }
8377 
8378     /**
8379      * Returns the unique device ID of phone, for example, the IMEI for
8380      * GSM and the MEID for CDMA phones. Return null if device ID is not available.
8381      *
8382      * <p>Requires Permission:
8383      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
8384      */
8385     @Override
getDeviceIdWithFeature(String callingPackage, String callingFeatureId)8386     public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
8387         try {
8388             mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
8389         } catch (SecurityException se) {
8390             EventLog.writeEvent(0x534e4554, "186530889", Binder.getCallingUid());
8391             throw new SecurityException("Package " + callingPackage + " does not belong to "
8392                     + Binder.getCallingUid());
8393         }
8394         final Phone phone = PhoneFactory.getPhone(0);
8395         if (phone == null) {
8396             return null;
8397         }
8398         int subId = phone.getSubId();
8399         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
8400                 callingPackage, callingFeatureId, "getDeviceId")) {
8401             return null;
8402         }
8403 
8404         final long identity = Binder.clearCallingIdentity();
8405         try {
8406             return phone.getDeviceId();
8407         } finally {
8408             Binder.restoreCallingIdentity(identity);
8409         }
8410     }
8411 
8412     /**
8413      * {@hide}
8414      * Returns the IMS Registration Status on a particular subid
8415      *
8416      * @param subId
8417      */
isImsRegistered(int subId)8418     public boolean isImsRegistered(int subId) {
8419         Phone phone = getPhone(subId);
8420         if (phone != null) {
8421             return phone.isImsRegistered();
8422         } else {
8423             return false;
8424         }
8425     }
8426 
8427     @Override
getSubIdForPhoneAccountHandle( PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId)8428     public int getSubIdForPhoneAccountHandle(
8429             PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId) {
8430         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, getDefaultSubscription(),
8431                 callingPackage, callingFeatureId, "getSubIdForPhoneAccountHandle")) {
8432             throw new SecurityException("Requires READ_PHONE_STATE permission.");
8433         }
8434         final long identity = Binder.clearCallingIdentity();
8435         try {
8436             return PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle);
8437         } finally {
8438             Binder.restoreCallingIdentity(identity);
8439         }
8440     }
8441 
8442     @Override
getPhoneAccountHandleForSubscriptionId(int subscriptionId)8443     public @Nullable PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId) {
8444         TelephonyPermissions
8445                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
8446                         mApp,
8447                         subscriptionId,
8448                         "getPhoneAccountHandleForSubscriptionId, " + "subscriptionId: "
8449                                 + subscriptionId);
8450 
8451         enforceTelephonyFeatureWithException(getCurrentPackageName(),
8452                 PackageManager.FEATURE_TELEPHONY_CALLING, "getPhoneAccountHandleForSubscriptionId");
8453 
8454         final long identity = Binder.clearCallingIdentity();
8455         try {
8456             Phone phone = getPhone(subscriptionId);
8457             if (phone == null) {
8458                 return null;
8459             }
8460             return PhoneUtils.makePstnPhoneAccountHandle(phone);
8461         } finally {
8462             Binder.restoreCallingIdentity(identity);
8463         }
8464     }
8465 
8466     /**
8467      * @return the VoWiFi calling availability.
8468      */
isWifiCallingAvailable(int subId)8469     public boolean isWifiCallingAvailable(int subId) {
8470         final long identity = Binder.clearCallingIdentity();
8471         try {
8472             Phone phone = getPhone(subId);
8473             if (phone != null) {
8474                 return phone.isWifiCallingEnabled();
8475             } else {
8476                 return false;
8477             }
8478         } finally {
8479             Binder.restoreCallingIdentity(identity);
8480         }
8481     }
8482 
8483     /**
8484      * @return the VT calling availability.
8485      */
isVideoTelephonyAvailable(int subId)8486     public boolean isVideoTelephonyAvailable(int subId) {
8487         final long identity = Binder.clearCallingIdentity();
8488         try {
8489             Phone phone = getPhone(subId);
8490             if (phone != null) {
8491                 return phone.isVideoEnabled();
8492             } else {
8493                 return false;
8494             }
8495         } finally {
8496             Binder.restoreCallingIdentity(identity);
8497         }
8498     }
8499 
8500     /**
8501      * @return the IMS registration technology for the MMTEL feature. Valid return values are
8502      * defined in {@link ImsRegistrationImplBase}.
8503      */
getImsRegTechnologyForMmTel(int subId)8504     public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
8505         final long identity = Binder.clearCallingIdentity();
8506         try {
8507             Phone phone = getPhone(subId);
8508             if (phone != null) {
8509                 return phone.getImsRegistrationTech();
8510             } else {
8511                 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
8512             }
8513         } finally {
8514             Binder.restoreCallingIdentity(identity);
8515         }
8516     }
8517 
8518     @Override
factoryReset(int subId, String callingPackage)8519     public void factoryReset(int subId, String callingPackage) {
8520         enforceSettingsPermission();
8521 
8522         enforceTelephonyFeatureWithException(callingPackage,
8523                 PackageManager.FEATURE_TELEPHONY, "factoryReset");
8524 
8525         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
8526             return;
8527         }
8528         Phone defaultPhone = getDefaultPhone();
8529         if (defaultPhone != null) {
8530             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8531                     mApp, getDefaultPhone().getSubId(), "factoryReset");
8532         }
8533         final long identity = Binder.clearCallingIdentity();
8534 
8535         try {
8536             if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
8537                     UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
8538                 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_USER,
8539                         getDefaultDataEnabled(), callingPackage);
8540                 setNetworkSelectionModeAutomatic(subId);
8541                 Phone phone = getPhone(subId);
8542                 cleanUpAllowedNetworkTypes(phone, subId);
8543                 setDataRoamingEnabled(subId, phone == null ? false
8544                         : phone.getDataSettingsManager().isDefaultDataRoamingEnabled());
8545                 getPhone(subId).resetCarrierKeysForImsiEncryption();
8546             }
8547             // There has been issues when Sms raw table somehow stores orphan
8548             // fragments. They lead to garbled message when new fragments come
8549             // in and combined with those stale ones. In case this happens again,
8550             // user can reset all network settings which will clean up this table.
8551             cleanUpSmsRawTable(getDefaultPhone().getContext());
8552             // Clean up IMS settings as well here.
8553             int slotId = getSlotIndex(subId);
8554             if (slotId > SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
8555                 ImsManager.getInstance(mApp, slotId).factoryReset();
8556             }
8557 
8558             if (defaultPhone == null) {
8559                 return;
8560             }
8561             // Erase modem config if erase modem on network setting is enabled.
8562             String configValue = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_TELEPHONY,
8563                     RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED);
8564             if (configValue != null && Boolean.parseBoolean(configValue)) {
8565                 sendEraseModemConfig(defaultPhone);
8566             }
8567 
8568             sendEraseDataInSharedPreferences(defaultPhone);
8569         } finally {
8570             Binder.restoreCallingIdentity(identity);
8571         }
8572     }
8573 
8574     @VisibleForTesting
cleanUpAllowedNetworkTypes(Phone phone, int subId)8575     void cleanUpAllowedNetworkTypes(Phone phone, int subId) {
8576         if (phone == null || !SubscriptionManager.isUsableSubscriptionId(subId)) {
8577             return;
8578         }
8579         long defaultNetworkType = RadioAccessFamily.getRafFromNetworkType(
8580                 RILConstants.PREFERRED_NETWORK_MODE);
8581         SubscriptionManager.setSubscriptionProperty(subId,
8582                 SubscriptionManager.ALLOWED_NETWORK_TYPES,
8583                 "user=" + defaultNetworkType);
8584         phone.loadAllowedNetworksFromSubscriptionDatabase();
8585         phone.setAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER,
8586                 defaultNetworkType, null);
8587     }
8588 
cleanUpSmsRawTable(Context context)8589     private void cleanUpSmsRawTable(Context context) {
8590         ContentResolver resolver = context.getContentResolver();
8591         Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
8592         resolver.delete(uri, null, null);
8593     }
8594 
8595     @Override
getSimLocaleForSubscriber(int subId)8596     public String getSimLocaleForSubscriber(int subId) {
8597         enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
8598 
8599         enforceTelephonyFeatureWithException(getCurrentPackageName(),
8600                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSimLocaleForSubscriber");
8601 
8602         final Phone phone = getPhone(subId);
8603         if (phone == null) {
8604             log("getSimLocaleForSubscriber, invalid subId");
8605             return null;
8606         }
8607         final long identity = Binder.clearCallingIdentity();
8608         try {
8609             SubscriptionInfo info = getSubscriptionManagerService().getActiveSubscriptionInfo(subId,
8610                     phone.getContext().getOpPackageName(),
8611                     phone.getContext().getAttributionTag());
8612             if (info == null) {
8613                 log("getSimLocaleForSubscriber, inactive subId: " + subId);
8614                 return null;
8615             }
8616             // Try and fetch the locale from the carrier properties or from the SIM language
8617             // preferences (EF-PL and EF-LI)...
8618             final int mcc = info.getMcc();
8619             String simLanguage = null;
8620             final Locale localeFromDefaultSim = phone.getLocaleFromSimAndCarrierPrefs();
8621             if (localeFromDefaultSim != null) {
8622                 if (!localeFromDefaultSim.getCountry().isEmpty()) {
8623                     if (DBG) log("Using locale from subId: " + subId + " locale: "
8624                             + localeFromDefaultSim);
8625                     return matchLocaleFromSupportedLocaleList(phone, localeFromDefaultSim);
8626                 } else {
8627                     simLanguage = localeFromDefaultSim.getLanguage();
8628                 }
8629             }
8630 
8631             // The SIM language preferences only store a language (e.g. fr = French), not an
8632             // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
8633             // the SIM and carrier preferences does not include a country we add the country
8634             // determined from the SIM MCC to provide an exact locale.
8635             final Locale mccLocale = LocaleUtils.getLocaleFromMcc(mApp, mcc, simLanguage);
8636             if (mccLocale != null) {
8637                 if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale);
8638                 return matchLocaleFromSupportedLocaleList(phone, mccLocale);
8639             }
8640 
8641             if (DBG) log("No locale found - returning null");
8642             return null;
8643         } finally {
8644             Binder.restoreCallingIdentity(identity);
8645         }
8646     }
8647 
8648     @VisibleForTesting
matchLocaleFromSupportedLocaleList(Phone phone, @NonNull Locale inputLocale)8649     String matchLocaleFromSupportedLocaleList(Phone phone, @NonNull Locale inputLocale) {
8650         String[] supportedLocale = com.android.internal.app.LocalePicker.getSupportedLocales(
8651                 phone.getContext());
8652         for (String localeTag : supportedLocale) {
8653             if (LocaleList.matchesLanguageAndScript(inputLocale, Locale.forLanguageTag(localeTag))
8654                     && TextUtils.equals(inputLocale.getCountry(),
8655                     Locale.forLanguageTag(localeTag).getCountry())) {
8656                 return localeTag;
8657             }
8658         }
8659         return inputLocale.toLanguageTag();
8660     }
8661 
8662     /**
8663      * NOTE: this method assumes permission checks are done and caller identity has been cleared.
8664      */
getActiveSubscriptionInfoListPrivileged()8665     private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
8666         return getSubscriptionManagerService().getActiveSubscriptionInfoList(
8667                 mApp.getOpPackageName(), mApp.getAttributionTag(), true/*isForAllProfile*/);
8668     }
8669 
8670     private ActivityStatsTechSpecificInfo[] mLastModemActivitySpecificInfo = null;
8671     private ModemActivityInfo mLastModemActivityInfo = null;
8672 
8673     /**
8674      * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
8675      * representing the state of the modem.
8676      *
8677      * NOTE: The underlying implementation clears the modem state, so there should only ever be one
8678      * caller to it. Everyone should call this class to get cumulative data.
8679      * @hide
8680      */
8681     @Override
requestModemActivityInfo(ResultReceiver result)8682     public void requestModemActivityInfo(ResultReceiver result) {
8683         enforceModifyPermission();
8684 
8685         enforceTelephonyFeatureWithException(getCurrentPackageName(),
8686                 PackageManager.FEATURE_TELEPHONY, "requestModemActivityInfo");
8687 
8688         WorkSource workSource = getWorkSource(Binder.getCallingUid());
8689 
8690         final long identity = Binder.clearCallingIdentity();
8691         try {
8692             sendRequestAsync(CMD_GET_MODEM_ACTIVITY_INFO, result, null, workSource);
8693         } finally {
8694             Binder.restoreCallingIdentity(identity);
8695         }
8696     }
8697 
8698     // Checks that ModemActivityInfo is valid. Sleep time and Idle time should be
8699     // less than total activity duration.
isModemActivityInfoValid(ModemActivityInfo info)8700     private boolean isModemActivityInfoValid(ModemActivityInfo info) {
8701         if (info == null) {
8702             return false;
8703         }
8704         int activityDurationMs =
8705                 (int) (info.getTimestampMillis() - mLastModemActivityInfo.getTimestampMillis());
8706         activityDurationMs += MODEM_ACTIVITY_TIME_OFFSET_CORRECTION_MS;
8707 
8708         int totalTxTimeMs = Arrays.stream(info.getTransmitTimeMillis()).sum();
8709 
8710         return (info.isValid()
8711                 && (info.getSleepTimeMillis() <= activityDurationMs)
8712                 && (info.getIdleTimeMillis() <= activityDurationMs));
8713     }
8714 
updateLastModemActivityInfo(ModemActivityInfo info, int rat, int freq)8715     private void updateLastModemActivityInfo(ModemActivityInfo info, int rat, int freq) {
8716         int[] mergedTxTimeMs = new int [ModemActivityInfo.getNumTxPowerLevels()];
8717         int[] txTimeMs = info.getTransmitTimeMillis(rat, freq);
8718         int[] lastModemTxTimeMs = mLastModemActivityInfo.getTransmitTimeMillis(rat, freq);
8719 
8720         for (int lvl = 0; lvl < mergedTxTimeMs.length; lvl++) {
8721             mergedTxTimeMs[lvl] = txTimeMs[lvl] + lastModemTxTimeMs[lvl];
8722         }
8723 
8724         mLastModemActivityInfo.setTransmitTimeMillis(rat, freq, mergedTxTimeMs);
8725         mLastModemActivityInfo.setReceiveTimeMillis(
8726                 rat,
8727                 freq,
8728                 info.getReceiveTimeMillis(rat, freq)
8729                         + mLastModemActivityInfo.getReceiveTimeMillis(rat, freq));
8730     }
8731 
updateLastModemActivityInfo(ModemActivityInfo info, int rat)8732     private void updateLastModemActivityInfo(ModemActivityInfo info, int rat) {
8733         int[] mergedTxTimeMs = new int [ModemActivityInfo.getNumTxPowerLevels()];
8734         int[] txTimeMs = info.getTransmitTimeMillis(rat);
8735         int[] lastModemTxTimeMs = mLastModemActivityInfo.getTransmitTimeMillis(rat);
8736 
8737         for (int lvl = 0; lvl < mergedTxTimeMs.length; lvl++) {
8738             mergedTxTimeMs[lvl] = txTimeMs[lvl] + lastModemTxTimeMs[lvl];
8739         }
8740         mLastModemActivityInfo.setTransmitTimeMillis(rat, mergedTxTimeMs);
8741         mLastModemActivityInfo.setReceiveTimeMillis(
8742                 rat,
8743                 info.getReceiveTimeMillis(rat) + mLastModemActivityInfo.getReceiveTimeMillis(rat));
8744     }
8745 
8746     /**
8747      * Merge this ModemActivityInfo with mLastModemActivitySpecificInfo
8748      * @param info recent ModemActivityInfo
8749      */
mergeModemActivityInfo(ModemActivityInfo info)8750     private void mergeModemActivityInfo(ModemActivityInfo info) {
8751         List<ActivityStatsTechSpecificInfo> merged = new ArrayList<>();
8752         ActivityStatsTechSpecificInfo deltaSpecificInfo;
8753         boolean matched;
8754         for (int i = 0; i < info.getSpecificInfoLength(); i++) {
8755             matched = false;
8756             int rat = info.getSpecificInfoRat(i);
8757             int freq = info.getSpecificInfoFrequencyRange(i);
8758             //Check each ActivityStatsTechSpecificInfo in this ModemActivityInfo for new rat returns
8759             //Add a new ActivityStatsTechSpecificInfo if is a new rat, and merge with the original
8760             //if it already exists
8761             for (int j = 0; j < mLastModemActivitySpecificInfo.length; j++) {
8762                 if (rat == mLastModemActivityInfo.getSpecificInfoRat(j) && !matched) {
8763                     //Merged based on frequency range (MMWAVE vs SUB6) for 5G
8764                     if (rat == AccessNetworkConstants.AccessNetworkType.NGRAN) {
8765                         if (freq == mLastModemActivityInfo.getSpecificInfoFrequencyRange(j)) {
8766                             updateLastModemActivityInfo(info, rat, freq);
8767                             matched = true;
8768                         }
8769                     } else {
8770                         updateLastModemActivityInfo(info, rat);
8771                         matched = true;
8772                     }
8773                 }
8774             }
8775 
8776             if (!matched) {
8777                 deltaSpecificInfo =
8778                         new ActivityStatsTechSpecificInfo(
8779                                 rat,
8780                                 freq,
8781                                 info.getTransmitTimeMillis(rat, freq),
8782                                 (int) info.getReceiveTimeMillis(rat, freq));
8783                 merged.addAll(Arrays.asList(deltaSpecificInfo));
8784             }
8785         }
8786         merged.addAll(Arrays.asList(mLastModemActivitySpecificInfo));
8787         mLastModemActivitySpecificInfo =
8788                 new ActivityStatsTechSpecificInfo[merged.size()];
8789         merged.toArray(mLastModemActivitySpecificInfo);
8790 
8791         mLastModemActivityInfo.setTimestamp(info.getTimestampMillis());
8792         mLastModemActivityInfo.setSleepTimeMillis(
8793                 info.getSleepTimeMillis()
8794                         + mLastModemActivityInfo.getSleepTimeMillis());
8795         mLastModemActivityInfo.setIdleTimeMillis(
8796                 info.getIdleTimeMillis()
8797                         + mLastModemActivityInfo.getIdleTimeMillis());
8798 
8799         mLastModemActivityInfo =
8800                 new ModemActivityInfo(
8801                         mLastModemActivityInfo.getTimestampMillis(),
8802                         mLastModemActivityInfo.getSleepTimeMillis(),
8803                         mLastModemActivityInfo.getIdleTimeMillis(),
8804                         mLastModemActivitySpecificInfo);
8805     }
8806 
deepCopyModemActivitySpecificInfo( ActivityStatsTechSpecificInfo[] info)8807     private ActivityStatsTechSpecificInfo[] deepCopyModemActivitySpecificInfo(
8808             ActivityStatsTechSpecificInfo[] info) {
8809         int infoSize = info.length;
8810         ActivityStatsTechSpecificInfo[] ret = new ActivityStatsTechSpecificInfo[infoSize];
8811         for (int i = 0; i < infoSize; i++) {
8812             ret[i] = new ActivityStatsTechSpecificInfo(
8813                     info[i].getRat(), info[i].getFrequencyRange(),
8814                     info[i].getTransmitTimeMillis(),
8815                     (int) info[i].getReceiveTimeMillis());
8816         }
8817         return ret;
8818     }
8819 
8820     /**
8821      * Returns the service state information on specified SIM slot.
8822      */
8823     @Override
getServiceStateForSlot(int slotIndex, boolean renounceFineLocationAccess, boolean renounceCoarseLocationAccess, String callingPackage, String callingFeatureId)8824     public ServiceState getServiceStateForSlot(int slotIndex, boolean renounceFineLocationAccess,
8825             boolean renounceCoarseLocationAccess, String callingPackage, String callingFeatureId) {
8826         Phone phone = PhoneFactory.getPhone(slotIndex);
8827         if (phone == null) {
8828             loge("getServiceStateForSlot retuning null for invalid slotIndex=" + slotIndex);
8829             return null;
8830         }
8831 
8832         int subId = phone.getSubId();
8833         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
8834                 mApp, subId, callingPackage, callingFeatureId, "getServiceStateForSubscriber")) {
8835             return null;
8836         }
8837 
8838         enforceTelephonyFeatureWithException(callingPackage,
8839                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getServiceStateForSubscriber");
8840 
8841         boolean hasFinePermission = false;
8842         boolean hasCoarsePermission = false;
8843         if (!renounceFineLocationAccess) {
8844             LocationAccessPolicy.LocationPermissionResult fineLocationResult =
8845                     LocationAccessPolicy.checkLocationPermission(mApp,
8846                             new LocationAccessPolicy.LocationPermissionQuery.Builder()
8847                                     .setCallingPackage(callingPackage)
8848                                     .setCallingFeatureId(callingFeatureId)
8849                                     .setCallingPid(Binder.getCallingPid())
8850                                     .setCallingUid(Binder.getCallingUid())
8851                                     .setMethod("getServiceStateForSlot")
8852                                     .setLogAsInfo(true)
8853                                     .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
8854                                     .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
8855                                     .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
8856                                     .build());
8857             hasFinePermission =
8858                     fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
8859         }
8860 
8861         if (!renounceCoarseLocationAccess) {
8862             LocationAccessPolicy.LocationPermissionResult coarseLocationResult =
8863                     LocationAccessPolicy.checkLocationPermission(mApp,
8864                             new LocationAccessPolicy.LocationPermissionQuery.Builder()
8865                                     .setCallingPackage(callingPackage)
8866                                     .setCallingFeatureId(callingFeatureId)
8867                                     .setCallingPid(Binder.getCallingPid())
8868                                     .setCallingUid(Binder.getCallingUid())
8869                                     .setMethod("getServiceStateForSlot")
8870                                     .setLogAsInfo(true)
8871                                     .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
8872                                     .setMinSdkVersionForFine(Integer.MAX_VALUE)
8873                                     .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
8874                                     .build());
8875             hasCoarsePermission =
8876                     coarseLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
8877         }
8878 
8879         final long identity = Binder.clearCallingIdentity();
8880         try {
8881             SubscriptionInfoInternal subInfo = getSubscriptionManagerService()
8882                     .getSubscriptionInfoInternal(subId);
8883             if (subInfo != null && !subInfo.isActive()) {
8884                 log("getServiceStateForSlot returning null for inactive subId=" + subId);
8885                 return null;
8886             }
8887 
8888             ServiceState ss = phone.getServiceState();
8889             boolean isCallingPackageDataService = phone.getDataServicePackages()
8890                     .contains(callingPackage);
8891 
8892             // Scrub out the location info in ServiceState depending on what level of access
8893             // the caller has.
8894             if (hasFinePermission || isCallingPackageDataService) return ss;
8895             if (hasCoarsePermission) return ss.createLocationInfoSanitizedCopy(false);
8896             return ss.createLocationInfoSanitizedCopy(true);
8897         } finally {
8898             Binder.restoreCallingIdentity(identity);
8899         }
8900     }
8901 
8902     /**
8903      * Returns the URI for the per-account voicemail ringtone set in Phone settings.
8904      *
8905      * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
8906      * voicemail ringtone.
8907      * @return The URI for the ringtone to play when receiving a voicemail from a specific
8908      * PhoneAccount.
8909      */
8910     @Override
getVoicemailRingtoneUri(PhoneAccountHandle accountHandle)8911     public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
8912         enforceTelephonyFeatureWithException(getCurrentPackageName(),
8913                 PackageManager.FEATURE_TELEPHONY_CALLING, "getVoicemailRingtoneUri");
8914 
8915         final long identity = Binder.clearCallingIdentity();
8916         try {
8917             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
8918             if (phone == null) {
8919                 phone = getDefaultPhone();
8920             }
8921 
8922             return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
8923         } finally {
8924             Binder.restoreCallingIdentity(identity);
8925         }
8926     }
8927 
8928     /**
8929      * Sets the per-account voicemail ringtone.
8930      *
8931      * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
8932      * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
8933      *
8934      * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
8935      * voicemail ringtone.
8936      * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
8937      * PhoneAccount.
8938      */
8939     @Override
setVoicemailRingtoneUri(String callingPackage, PhoneAccountHandle phoneAccountHandle, Uri uri)8940     public void setVoicemailRingtoneUri(String callingPackage,
8941             PhoneAccountHandle phoneAccountHandle, Uri uri) {
8942         final Phone defaultPhone = getDefaultPhone();
8943         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
8944         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
8945         if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
8946             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8947                     mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
8948                     "setVoicemailRingtoneUri");
8949         }
8950 
8951         enforceTelephonyFeatureWithException(callingPackage,
8952                 PackageManager.FEATURE_TELEPHONY_CALLING, "setVoicemailRingtoneUri");
8953 
8954         final long identity = Binder.clearCallingIdentity();
8955         try {
8956             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
8957             if (phone == null) {
8958                 phone = defaultPhone;
8959             }
8960             VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
8961         } finally {
8962             Binder.restoreCallingIdentity(identity);
8963         }
8964     }
8965 
8966     /**
8967      * Returns whether vibration is set for voicemail notification in Phone settings.
8968      *
8969      * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
8970      * voicemail vibration setting.
8971      * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
8972      */
8973     @Override
isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle)8974     public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
8975         enforceTelephonyFeatureWithException(getCurrentPackageName(),
8976                 PackageManager.FEATURE_TELEPHONY_CALLING, "isVoicemailVibrationEnabled");
8977 
8978         final long identity = Binder.clearCallingIdentity();
8979         try {
8980             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
8981             if (phone == null) {
8982                 phone = getDefaultPhone();
8983             }
8984 
8985             return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
8986         } finally {
8987             Binder.restoreCallingIdentity(identity);
8988         }
8989     }
8990 
8991     /**
8992      * Sets the per-account voicemail vibration.
8993      *
8994      * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
8995      * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
8996      *
8997      * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
8998      * voicemail vibration setting.
8999      * @param enabled Whether to enable or disable vibration for voicemail notifications from a
9000      * specific PhoneAccount.
9001      */
9002     @Override
setVoicemailVibrationEnabled(String callingPackage, PhoneAccountHandle phoneAccountHandle, boolean enabled)9003     public void setVoicemailVibrationEnabled(String callingPackage,
9004             PhoneAccountHandle phoneAccountHandle, boolean enabled) {
9005         final Phone defaultPhone = getDefaultPhone();
9006         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
9007         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
9008         if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
9009             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9010                     mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
9011                     "setVoicemailVibrationEnabled");
9012         }
9013 
9014         enforceTelephonyFeatureWithException(callingPackage,
9015                 PackageManager.FEATURE_TELEPHONY_CALLING, "setVoicemailVibrationEnabled");
9016 
9017         final long identity = Binder.clearCallingIdentity();
9018         try {
9019             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
9020             if (phone == null) {
9021                 phone = defaultPhone;
9022             }
9023             VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
9024         } finally {
9025             Binder.restoreCallingIdentity(identity);
9026         }
9027     }
9028 
9029     /**
9030      * Make sure either called from same process as self (phone) or IPC caller has read privilege.
9031      *
9032      * @throws SecurityException if the caller does not have the required permission
9033      */
9034     @VisibleForTesting
enforceReadPrivilegedPermission(String message)9035     public void enforceReadPrivilegedPermission(String message) {
9036         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
9037                 message);
9038     }
9039 
9040     /**
9041      * Make sure either called from same process as self (phone) or IPC caller has send SMS
9042      * permission.
9043      *
9044      * @throws SecurityException if the caller does not have the required permission
9045      */
enforceSendSmsPermission()9046     private void enforceSendSmsPermission() {
9047         mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
9048     }
9049 
9050     /**
9051      * Make sure either called from same process as self (phone) or IPC caller has interact across
9052      * users permission.
9053      *
9054      * @throws SecurityException if the caller does not have the required permission
9055      */
enforceInteractAcrossUsersPermission(String message)9056     private void enforceInteractAcrossUsersPermission(String message) {
9057         mApp.enforceCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS, message);
9058     }
9059 
9060     /**
9061      * Make sure called from the package in charge of visual voicemail.
9062      *
9063      * @throws SecurityException if the caller is not the visual voicemail package.
9064      */
enforceVisualVoicemailPackage(String callingPackage, int subId)9065     private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
9066         final long identity = Binder.clearCallingIdentity();
9067         try {
9068             ComponentName componentName =
9069                     RemoteVvmTaskManager.getRemotePackage(mApp, subId);
9070             if (componentName == null) {
9071                 throw new SecurityException(
9072                         "Caller not current active visual voicemail package[null]");
9073             }
9074             String vvmPackage = componentName.getPackageName();
9075             if (!callingPackage.equals(vvmPackage)) {
9076                 throw new SecurityException("Caller not current active visual voicemail package");
9077             }
9078         } finally {
9079             Binder.restoreCallingIdentity(identity);
9080         }
9081     }
9082 
9083     /**
9084      * Return the application ID for the app type.
9085      *
9086      * @param subId the subscription ID that this request applies to.
9087      * @param appType the uicc app type.
9088      * @return Application ID for specificied app type, or null if no uicc.
9089      */
9090     @Override
getAidForAppType(int subId, int appType)9091     public String getAidForAppType(int subId, int appType) {
9092         enforceReadPrivilegedPermission("getAidForAppType");
9093 
9094         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9095                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getAidForAppType");
9096 
9097         Phone phone = getPhone(subId);
9098 
9099         final long identity = Binder.clearCallingIdentity();
9100         try {
9101             if (phone == null) {
9102                 return null;
9103             }
9104             String aid = null;
9105             try {
9106                 aid = UiccController.getInstance().getUiccPort(phone.getPhoneId())
9107                         .getApplicationByType(appType).getAid();
9108             } catch (Exception e) {
9109                 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
9110             }
9111             return aid;
9112         } finally {
9113             Binder.restoreCallingIdentity(identity);
9114         }
9115     }
9116 
9117     /**
9118      * Return the Electronic Serial Number.
9119      *
9120      * @param subId the subscription ID that this request applies to.
9121      * @return ESN or null if error.
9122      */
9123     @Override
getEsn(int subId)9124     public String getEsn(int subId) {
9125         enforceReadPrivilegedPermission("getEsn");
9126         Phone phone = getPhone(subId);
9127 
9128         final long identity = Binder.clearCallingIdentity();
9129         try {
9130             if (phone == null) {
9131                 return null;
9132             }
9133             String esn = null;
9134             try {
9135                 esn = phone.getEsn();
9136             } catch (Exception e) {
9137                 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
9138             }
9139             return esn;
9140         } finally {
9141             Binder.restoreCallingIdentity(identity);
9142         }
9143     }
9144 
9145     /**
9146      * Return the Preferred Roaming List Version.
9147      *
9148      * @param subId the subscription ID that this request applies to.
9149      * @return PRLVersion or null if error.
9150      */
9151     @Override
getCdmaPrlVersion(int subId)9152     public String getCdmaPrlVersion(int subId) {
9153         enforceReadPrivilegedPermission("getCdmaPrlVersion");
9154 
9155         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9156                 PackageManager.FEATURE_TELEPHONY_CDMA, "getCdmaPrlVersion");
9157 
9158         Phone phone = getPhone(subId);
9159 
9160         final long identity = Binder.clearCallingIdentity();
9161         try {
9162             if (phone == null) {
9163                 return null;
9164             }
9165             String cdmaPrlVersion = null;
9166             try {
9167                 cdmaPrlVersion = phone.getCdmaPrlVersion();
9168             } catch (Exception e) {
9169                 Log.e(LOG_TAG, "Not getting PRLVersion", e);
9170             }
9171             return cdmaPrlVersion;
9172         } finally {
9173             Binder.restoreCallingIdentity(identity);
9174         }
9175     }
9176 
9177     /**
9178      * Get snapshot of Telephony histograms
9179      * @return List of Telephony histograms
9180      * @hide
9181      */
9182     @Override
getTelephonyHistograms()9183     public List<TelephonyHistogram> getTelephonyHistograms() {
9184         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9185                 mApp, getDefaultSubscription(), "getTelephonyHistograms");
9186 
9187         final long identity = Binder.clearCallingIdentity();
9188         try {
9189             return RIL.getTelephonyRILTimingHistograms();
9190         } finally {
9191             Binder.restoreCallingIdentity(identity);
9192         }
9193     }
9194 
9195     /**
9196      * {@hide}
9197      * Set the allowed carrier list and the excluded carrier list, indicating the priority between
9198      * the two lists.
9199      * Require system privileges. In the future we may add this to carrier APIs.
9200      *
9201      * @return Integer with the result of the operation, as defined in {@link TelephonyManager}.
9202      */
9203     @Override
9204     @TelephonyManager.SetCarrierRestrictionResult
setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules)9205     public int setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules) {
9206         enforceModifyPermission();
9207 
9208         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9209                 PackageManager.FEATURE_TELEPHONY_CARRIERLOCK, "setAllowedCarriers");
9210 
9211         WorkSource workSource = getWorkSource(Binder.getCallingUid());
9212 
9213         if (carrierRestrictionRules == null) {
9214             throw new NullPointerException("carrier restriction cannot be null");
9215         }
9216 
9217         final long identity = Binder.clearCallingIdentity();
9218         try {
9219             return (int) sendRequest(CMD_SET_ALLOWED_CARRIERS, carrierRestrictionRules,
9220                     workSource);
9221         } finally {
9222             Binder.restoreCallingIdentity(identity);
9223         }
9224     }
9225 
9226     /**
9227      * {@hide}
9228      * Get the allowed carrier list and the excluded carrier list, including the priority between
9229      * the two lists.
9230      * Require system privileges. In the future we may add this to carrier APIs.
9231      *
9232      * @return {@link android.telephony.CarrierRestrictionRules}
9233      */
9234     @Override
getAllowedCarriers()9235     public CarrierRestrictionRules getAllowedCarriers() {
9236         enforceReadPrivilegedPermission("getAllowedCarriers");
9237 
9238         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9239                 PackageManager.FEATURE_TELEPHONY_CARRIERLOCK, "getAllowedCarriers");
9240 
9241         WorkSource workSource = getWorkSource(Binder.getCallingUid());
9242 
9243         final long identity = Binder.clearCallingIdentity();
9244         try {
9245             Object response = sendRequest(CMD_GET_ALLOWED_CARRIERS, null, workSource);
9246             if (response instanceof CarrierRestrictionRules) {
9247                 return (CarrierRestrictionRules) response;
9248             }
9249             // Response is an Exception of some kind,
9250             // which is signalled to the user as a NULL retval
9251             return null;
9252         } catch (Exception e) {
9253             Log.e(LOG_TAG, "getAllowedCarriers. Exception ex=" + e);
9254             return null;
9255         } finally {
9256             Binder.restoreCallingIdentity(identity);
9257         }
9258     }
9259 
9260     /**
9261      * Fetches the carrier restriction status of the device and sends the status to the caller
9262      * through the callback.
9263      *
9264      * @param callback The callback that will be used to send the result.
9265      * @throws SecurityException if the caller does not have the required permission/privileges or
9266      *                           the caller is not allowlisted.
9267      */
9268     @Override
getCarrierRestrictionStatus(IIntegerConsumer callback, String packageName)9269     public void getCarrierRestrictionStatus(IIntegerConsumer callback, String packageName) {
9270         enforceReadPermission("getCarrierRestrictionStatus");
9271 
9272         enforceTelephonyFeatureWithException(packageName,
9273                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getCarrierRestrictionStatus");
9274 
9275         Set<Integer> carrierIds = validateCallerAndGetCarrierIds(packageName);
9276         if (carrierIds.contains(CarrierAllowListInfo.INVALID_CARRIER_ID)) {
9277             Rlog.e(LOG_TAG, "getCarrierRestrictionStatus: caller is not registered");
9278             throw new SecurityException("Not an authorized caller");
9279         }
9280         final long identity = Binder.clearCallingIdentity();
9281         try {
9282             Consumer<Integer> consumer = FunctionalUtils.ignoreRemoteException(callback::accept);
9283             CallerCallbackInfo callbackInfo = new CallerCallbackInfo(consumer, carrierIds);
9284             sendRequestAsync(CMD_GET_ALLOWED_CARRIERS, callbackInfo);
9285         } finally {
9286             Binder.restoreCallingIdentity(identity);
9287         }
9288     }
9289 
9290     @Override
getShaIdFromAllowList(String pkgName, int carrierId)9291     public List<String> getShaIdFromAllowList(String pkgName, int carrierId) {
9292         enforceReadPrivilegedPermission("checkCarrierRestrictionFileForNoChange");
9293         CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mApp);
9294         return allowListInfo.getShaIdList(pkgName, carrierId);
9295     }
9296 
9297     @VisibleForTesting
validateCallerAndGetCarrierIds(String packageName)9298     public Set<Integer> validateCallerAndGetCarrierIds(String packageName) {
9299         CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mApp);
9300         return allowListInfo.validateCallerAndGetCarrierIds(packageName);
9301     }
9302 
9303     /**
9304      * Action set from carrier signalling broadcast receivers to enable/disable radio
9305      * @param subId the subscription ID that this action applies to.
9306      * @param enabled control enable or disable radio.
9307      * {@hide}
9308      */
9309     @Override
carrierActionSetRadioEnabled(int subId, boolean enabled)9310     public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
9311         enforceModifyPermission();
9312         final Phone phone = getPhone(subId);
9313 
9314         final long identity = Binder.clearCallingIdentity();
9315         if (phone == null) {
9316             loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
9317             return;
9318         }
9319         try {
9320             phone.carrierActionSetRadioEnabled(enabled);
9321         } catch (Exception e) {
9322             Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
9323         } finally {
9324             Binder.restoreCallingIdentity(identity);
9325         }
9326     }
9327 
9328     /**
9329      * Enable or disable Voice over NR (VoNR)
9330      * @param subId the subscription ID that this action applies to.
9331      * @param enabled enable or disable VoNR.
9332      * @return operation result.
9333      */
9334     @Override
setVoNrEnabled(int subId, boolean enabled)9335     public int setVoNrEnabled(int subId, boolean enabled) {
9336         enforceModifyPermission();
9337         final Phone phone = getPhone(subId);
9338 
9339         final long identity = Binder.clearCallingIdentity();
9340         if (phone == null) {
9341             loge("setVoNrEnabled fails with no phone object for subId: " + subId);
9342             return TelephonyManager.ENABLE_VONR_RADIO_NOT_AVAILABLE;
9343         }
9344 
9345         WorkSource workSource = getWorkSource(Binder.getCallingUid());
9346         try {
9347             int result = (int) sendRequest(CMD_ENABLE_VONR, enabled, subId,
9348                     workSource);
9349             if (DBG) log("setVoNrEnabled result: " + result);
9350 
9351             if (result == TelephonyManager.ENABLE_VONR_SUCCESS) {
9352                 if (DBG) {
9353                     log("Set VoNR settings in siminfo db; subId=" + subId + ", value:" + enabled);
9354                 }
9355                 SubscriptionManager.setSubscriptionProperty(
9356                         subId, SubscriptionManager.NR_ADVANCED_CALLING_ENABLED,
9357                         (enabled ? "1" : "0"));
9358             }
9359 
9360             return result;
9361         } finally {
9362             Binder.restoreCallingIdentity(identity);
9363         }
9364     }
9365 
9366     /**
9367      * Is voice over NR enabled
9368      * @return true if VoNR is enabled else false
9369      */
9370     @Override
isVoNrEnabled(int subId)9371     public boolean isVoNrEnabled(int subId) {
9372         enforceReadPrivilegedPermission("isVoNrEnabled");
9373         WorkSource workSource = getWorkSource(Binder.getCallingUid());
9374         final long identity = Binder.clearCallingIdentity();
9375         try {
9376             boolean isEnabled = (boolean) sendRequest(CMD_IS_VONR_ENABLED,
9377                     null, subId, workSource);
9378             if (DBG) log("isVoNrEnabled: " + isEnabled);
9379             return isEnabled;
9380         } finally {
9381             Binder.restoreCallingIdentity(identity);
9382         }
9383     }
9384 
9385     /**
9386      * Action set from carrier signalling broadcast receivers to start/stop reporting the default
9387      * network status based on which carrier apps could apply actions accordingly,
9388      * enable/disable default url handler for example.
9389      *
9390      * @param subId the subscription ID that this action applies to.
9391      * @param report control start/stop reporting the default network status.
9392      * {@hide}
9393      */
9394     @Override
carrierActionReportDefaultNetworkStatus(int subId, boolean report)9395     public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
9396         enforceModifyPermission();
9397 
9398         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9399                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS,
9400                 "carrierActionReportDefaultNetworkStatus");
9401 
9402         final Phone phone = getPhone(subId);
9403 
9404         final long identity = Binder.clearCallingIdentity();
9405         if (phone == null) {
9406             loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
9407             return;
9408         }
9409         try {
9410             phone.carrierActionReportDefaultNetworkStatus(report);
9411         } catch (Exception e) {
9412             Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
9413         } finally {
9414             Binder.restoreCallingIdentity(identity);
9415         }
9416     }
9417 
9418     /**
9419      * Action set from carrier signalling broadcast receivers to reset all carrier actions
9420      * @param subId the subscription ID that this action applies to.
9421      * {@hide}
9422      */
9423     @Override
carrierActionResetAll(int subId)9424     public void carrierActionResetAll(int subId) {
9425         enforceModifyPermission();
9426 
9427         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9428                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "carrierActionResetAll");
9429 
9430         final Phone phone = getPhone(subId);
9431         if (phone == null) {
9432             loge("carrierAction: ResetAll fails with invalid sibId: " + subId);
9433             return;
9434         }
9435         try {
9436             phone.carrierActionResetAll();
9437         } catch (Exception e) {
9438             Log.e(LOG_TAG, "carrierAction: ResetAll fails. Exception ex=" + e);
9439         }
9440     }
9441 
9442     /**
9443      * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
9444      * bug report is being generated.
9445      */
9446     @Override
dump(FileDescriptor fd, PrintWriter writer, String[] args)9447     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
9448         if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
9449                 != PackageManager.PERMISSION_GRANTED) {
9450             writer.println("Permission Denial: can't dump Phone from pid="
9451                     + Binder.getCallingPid()
9452                     + ", uid=" + Binder.getCallingUid()
9453                     + "without permission "
9454                     + android.Manifest.permission.DUMP);
9455             return;
9456         }
9457         try {
9458             DumpsysHandler.dump(mApp, fd, writer, args);
9459         } catch (Exception e) {
9460             writer.println("Failed to dump phone information: " + e);
9461         }
9462     }
9463 
9464     @Override
handleShellCommand(@onNull ParcelFileDescriptor in, @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, @NonNull String[] args)9465     public int handleShellCommand(@NonNull ParcelFileDescriptor in,
9466             @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
9467             @NonNull String[] args) {
9468         return new TelephonyShellCommand(this, getDefaultPhone().getContext()).exec(
9469                 this, in.getFileDescriptor(), out.getFileDescriptor(),
9470                 err.getFileDescriptor(), args);
9471     }
9472 
9473     /**
9474      * Policy control of data connection with reason {@@TelephonyManager.DataEnabledReason}
9475      * @param subId Subscription index
9476      * @param reason The reason the data enable change is taking place.
9477      * @param enabled True if enabling the data, otherwise disabling.
9478      * @param callingPackage The package that changed the data enabled state.
9479      * @hide
9480      */
9481     @Override
setDataEnabledForReason(int subId, @TelephonyManager.DataEnabledReason int reason, boolean enabled, String callingPackage)9482     public void setDataEnabledForReason(int subId, @TelephonyManager.DataEnabledReason int reason,
9483             boolean enabled, String callingPackage) {
9484         if (reason == TelephonyManager.DATA_ENABLED_REASON_USER
9485                 || reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
9486             try {
9487                 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
9488                         mApp, subId, "setDataEnabledForReason");
9489             } catch (SecurityException se) {
9490                 enforceModifyPermission();
9491             }
9492         } else {
9493             enforceModifyPermission();
9494         }
9495 
9496         enforceTelephonyFeatureWithException(callingPackage,
9497                 PackageManager.FEATURE_TELEPHONY_DATA, "setDataEnabledForReason");
9498 
9499         int callingUid = Binder.getCallingUid();
9500         final long identity = Binder.clearCallingIdentity();
9501         try {
9502             if (reason == TelephonyManager.DATA_ENABLED_REASON_USER && enabled
9503                     && null != callingPackage && opEnableMobileDataByUser()) {
9504                 mAppOps.noteOpNoThrow(AppOpsManager.OPSTR_ENABLE_MOBILE_DATA_BY_USER,
9505                         callingUid, callingPackage, null, null);
9506             }
9507             Phone phone = getPhone(subId);
9508             if (phone != null) {
9509                 if (reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
9510                     phone.carrierActionSetMeteredApnsEnabled(enabled);
9511                 } else {
9512                     phone.getDataSettingsManager().setDataEnabled(
9513                             reason, enabled, callingPackage);
9514                 }
9515             }
9516         } finally {
9517             Binder.restoreCallingIdentity(identity);
9518         }
9519     }
9520 
9521     /**
9522      * Get Client request stats
9523      * @return List of Client Request Stats
9524      * @hide
9525      */
9526     @Override
getClientRequestStats(String callingPackage, String callingFeatureId, int subId)9527     public List<ClientRequestStats> getClientRequestStats(String callingPackage,
9528             String callingFeatureId, int subId) {
9529         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
9530                 mApp, subId, callingPackage, callingFeatureId, "getClientRequestStats")) {
9531             return null;
9532         }
9533         Phone phone = getPhone(subId);
9534 
9535         final long identity = Binder.clearCallingIdentity();
9536         try {
9537             if (phone != null) {
9538                 return phone.getClientRequestStats();
9539             }
9540 
9541             return null;
9542         } finally {
9543             Binder.restoreCallingIdentity(identity);
9544         }
9545     }
9546 
getWorkSource(int uid)9547     private WorkSource getWorkSource(int uid) {
9548         String packageName = mApp.getPackageManager().getNameForUid(uid);
9549         if (uid == Process.ROOT_UID && packageName == null) {
9550             // Downstream WorkSource attribution inside the RIL requires both a UID and package name
9551             // to be set for wakelock tracking, otherwise RIL requests fail with a runtime
9552             // exception. ROOT_UID seems not to have a valid package name returned by
9553             // PackageManager, so just fake it here to avoid issues when running telephony shell
9554             // commands that plumb through the RIL as root, like so:
9555             // $ adb root
9556             // $ adb shell cmd phone ...
9557             packageName = "root";
9558         }
9559         return new WorkSource(uid, packageName);
9560     }
9561 
9562     /**
9563      * Set SIM card power state.
9564      *
9565      * @param slotIndex SIM slot id.
9566      * @param state  State of SIM (power down, power up, pass through)
9567      * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
9568      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
9569      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
9570      *
9571      **/
9572     @Override
setSimPowerStateForSlot(int slotIndex, int state)9573     public void setSimPowerStateForSlot(int slotIndex, int state) {
9574         enforceModifyPermission();
9575 
9576         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9577                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "setSimPowerStateForSlot");
9578 
9579         Phone phone = PhoneFactory.getPhone(slotIndex);
9580 
9581         WorkSource workSource = getWorkSource(Binder.getCallingUid());
9582 
9583         final long identity = Binder.clearCallingIdentity();
9584         try {
9585             if (phone != null) {
9586                 phone.setSimPowerState(state, null, workSource);
9587             }
9588         } finally {
9589             Binder.restoreCallingIdentity(identity);
9590         }
9591     }
9592 
9593     /**
9594      * Set SIM card power state.
9595      *
9596      * @param slotIndex SIM slot id.
9597      * @param state  State of SIM (power down, power up, pass through)
9598      * @param callback  callback to trigger after success or failure
9599      * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
9600      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
9601      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
9602      *
9603      **/
9604     @Override
setSimPowerStateForSlotWithCallback(int slotIndex, int state, IIntegerConsumer callback)9605     public void setSimPowerStateForSlotWithCallback(int slotIndex, int state,
9606             IIntegerConsumer callback) {
9607         enforceModifyPermission();
9608 
9609         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9610                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
9611                 "setSimPowerStateForSlotWithCallback");
9612 
9613         Phone phone = PhoneFactory.getPhone(slotIndex);
9614 
9615         WorkSource workSource = getWorkSource(Binder.getCallingUid());
9616 
9617         final long identity = Binder.clearCallingIdentity();
9618         try {
9619             if (phone != null) {
9620                 Pair<Integer, IIntegerConsumer> arguments = Pair.create(state, callback);
9621                 sendRequestAsync(CMD_SET_SIM_POWER, arguments, phone, workSource);
9622             }
9623         } finally {
9624             Binder.restoreCallingIdentity(identity);
9625         }
9626     }
9627 
isUssdApiAllowed(int subId)9628     private boolean isUssdApiAllowed(int subId) {
9629         CarrierConfigManager configManager =
9630                 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
9631         if (configManager == null) {
9632             return false;
9633         }
9634         PersistableBundle pb = configManager.getConfigForSubId(subId);
9635         if (pb == null) {
9636             return false;
9637         }
9638         return pb.getBoolean(
9639                 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
9640     }
9641 
9642     /**
9643      * Check if phone is in emergency callback mode.
9644      * @return true if phone is in emergency callback mode
9645      * @param subId sub Id, but the check is in fact irrlevant to sub Id.
9646      */
9647     @Override
getEmergencyCallbackMode(int subId)9648     public boolean getEmergencyCallbackMode(int subId) {
9649         enforceReadPrivilegedPermission("getEmergencyCallbackMode");
9650 
9651         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9652                 PackageManager.FEATURE_TELEPHONY_CALLING, "getEmergencyCallbackMode");
9653 
9654         final long identity = Binder.clearCallingIdentity();
9655         try {
9656             return getPhoneFromSubIdOrDefault(subId).isInEcm();
9657         } finally {
9658             Binder.restoreCallingIdentity(identity);
9659         }
9660     }
9661 
9662     /**
9663      * Get the current signal strength information for the given subscription.
9664      * Because this information is not updated when the device is in a low power state
9665      * it should not be relied-upon to be current.
9666      * @param subId Subscription index
9667      * @return the most recent cached signal strength info from the modem
9668      */
9669     @Override
getSignalStrength(int subId)9670     public SignalStrength getSignalStrength(int subId) {
9671         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9672                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getSignalStrength");
9673 
9674         final long identity = Binder.clearCallingIdentity();
9675         try {
9676             Phone p = getPhone(subId);
9677             if (p == null) {
9678                 return null;
9679             }
9680 
9681             return p.getSignalStrength();
9682         } finally {
9683             Binder.restoreCallingIdentity(identity);
9684         }
9685     }
9686 
9687     /**
9688      * Get the current modem radio state for the given slot.
9689      * @param slotIndex slot index.
9690      * @param callingPackage the name of the package making the call.
9691      * @param callingFeatureId The feature in the package.
9692      * @return the current radio power state from the modem
9693      */
9694     @Override
getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId)9695     public int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId) {
9696         Phone phone = PhoneFactory.getPhone(slotIndex);
9697         if (phone != null) {
9698             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, phone.getSubId(),
9699                     callingPackage, callingFeatureId, "getRadioPowerState")) {
9700                 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
9701             }
9702 
9703             enforceTelephonyFeatureWithException(callingPackage,
9704                     PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getRadioPowerState");
9705 
9706             final long identity = Binder.clearCallingIdentity();
9707             try {
9708                 return phone.getRadioPowerState();
9709             } finally {
9710                 Binder.restoreCallingIdentity(identity);
9711             }
9712         }
9713         return TelephonyManager.RADIO_POWER_UNAVAILABLE;
9714     }
9715 
9716     /**
9717      * Checks if data roaming is enabled on the subscription with id {@code subId}.
9718      *
9719      * <p>Requires one of the following permissions:
9720      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
9721      * {@link android.Manifest.permission#READ_BASIC_PHONE_STATE},
9722      * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
9723      * privileges.
9724      *
9725      * @param subId subscription id
9726      * @return {@code true} if data roaming is enabled on this subscription, otherwise return
9727      * {@code false}.
9728      */
9729     @Override
isDataRoamingEnabled(int subId)9730     public boolean isDataRoamingEnabled(int subId) {
9731         String functionName = "isDataRoamingEnabled";
9732         try {
9733             try {
9734                 mApp.enforceCallingOrSelfPermission(
9735                         android.Manifest.permission.ACCESS_NETWORK_STATE,
9736                         functionName);
9737             } catch (SecurityException e) {
9738                 mApp.enforceCallingOrSelfPermission(
9739                         permission.READ_BASIC_PHONE_STATE, functionName);
9740             }
9741         } catch (SecurityException e) {
9742             TelephonyPermissions.enforceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
9743                     mApp, subId, functionName);
9744         }
9745 
9746         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9747                 PackageManager.FEATURE_TELEPHONY_DATA, "isDataRoamingEnabled");
9748 
9749         boolean isEnabled = false;
9750         final long identity = Binder.clearCallingIdentity();
9751         try {
9752             Phone phone = getPhone(subId);
9753             isEnabled =  phone != null ? phone.getDataRoamingEnabled() : false;
9754         } finally {
9755             Binder.restoreCallingIdentity(identity);
9756         }
9757         return isEnabled;
9758     }
9759 
9760 
9761     /**
9762      * Enables/Disables the data roaming on the subscription with id {@code subId}.
9763      *
9764      * <p> Requires permission:
9765      * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
9766      * privileges.
9767      *
9768      * @param subId subscription id
9769      * @param isEnabled {@code true} means enable, {@code false} means disable.
9770      */
9771     @Override
setDataRoamingEnabled(int subId, boolean isEnabled)9772     public void setDataRoamingEnabled(int subId, boolean isEnabled) {
9773         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9774                 mApp, subId, "setDataRoamingEnabled");
9775 
9776         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9777                 PackageManager.FEATURE_TELEPHONY_DATA, "setDataRoamingEnabled");
9778 
9779         final long identity = Binder.clearCallingIdentity();
9780         try {
9781             Phone phone = getPhone(subId);
9782             if (phone != null) {
9783                 phone.setDataRoamingEnabled(isEnabled);
9784             }
9785         } finally {
9786             Binder.restoreCallingIdentity(identity);
9787         }
9788     }
9789 
9790     @Override
isManualNetworkSelectionAllowed(int subId)9791     public boolean isManualNetworkSelectionAllowed(int subId) {
9792         TelephonyPermissions
9793                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
9794                         mApp, subId, "isManualNetworkSelectionAllowed");
9795 
9796         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9797                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "isManualNetworkSelectionAllowed");
9798 
9799         boolean isAllowed = true;
9800         final long identity = Binder.clearCallingIdentity();
9801         try {
9802             Phone phone = getPhone(subId);
9803             if (phone != null) {
9804                 isAllowed = phone.isCspPlmnEnabled();
9805             }
9806         } finally {
9807             Binder.restoreCallingIdentity(identity);
9808         }
9809         return isAllowed;
9810     }
9811 
haveCarrierPrivilegeAccess(UiccPort port, String callingPackage)9812     private boolean haveCarrierPrivilegeAccess(UiccPort port, String callingPackage) {
9813         UiccProfile profile = port.getUiccProfile();
9814         if (profile == null) {
9815             return false;
9816         }
9817         Phone phone = PhoneFactory.getPhone(profile.getPhoneId());
9818         if (phone == null) {
9819             return false;
9820         }
9821         CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
9822         return cpt != null && cpt.getCarrierPrivilegeStatusForPackage(callingPackage)
9823                 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
9824     }
9825 
9826     @Override
getUiccCardsInfo(String callingPackage)9827     public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
9828         // Verify that the callingPackage belongs to the calling UID
9829         mApp.getSystemService(AppOpsManager.class)
9830                 .checkPackage(Binder.getCallingUid(), callingPackage);
9831 
9832         boolean hasReadPermission = false;
9833         boolean isIccIdAccessRestricted = false;
9834         try {
9835             enforceReadPrivilegedPermission("getUiccCardsInfo");
9836             hasReadPermission = true;
9837         } catch (SecurityException e) {
9838             // even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
9839             // has carrier privileges on an active UICC
9840             if (checkCarrierPrivilegesForPackageAnyPhoneWithPermission(callingPackage)
9841                     != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
9842                 throw new SecurityException("Caller does not have permission.");
9843             }
9844         }
9845 
9846         enforceTelephonyFeatureWithException(callingPackage,
9847                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getUiccCardsInfo");
9848 
9849         // checking compatibility, if calling app's target SDK is T and beyond.
9850         if (CompatChanges.isChangeEnabled(GET_API_SIGNATURES_FROM_UICC_PORT_INFO,
9851                 Binder.getCallingUid())) {
9852             isIccIdAccessRestricted = true;
9853         }
9854         final long identity = Binder.clearCallingIdentity();
9855         try {
9856             UiccController uiccController = UiccController.getInstance();
9857             ArrayList<UiccCardInfo> cardInfos = uiccController.getAllUiccCardInfos();
9858             if (hasReadPermission) {
9859                 return cardInfos;
9860             }
9861 
9862             // Remove private info if the caller doesn't have access
9863             ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
9864             for (UiccCardInfo cardInfo : cardInfos) {
9865                 //setting the value after compatibility check
9866                 cardInfo.setIccIdAccessRestricted(isIccIdAccessRestricted);
9867                 // For an inactive eUICC, the UiccCard will be null even though the UiccCardInfo
9868                 // is available
9869                 UiccCard card = uiccController.getUiccCardForSlot(cardInfo.getPhysicalSlotIndex());
9870                 if (card == null) {
9871                     // assume no access if the card is unavailable
9872                     filteredInfos.add(getUiccCardInfoUnPrivileged(cardInfo));
9873                     continue;
9874                 }
9875                 Collection<UiccPortInfo> portInfos = cardInfo.getPorts();
9876                 if (portInfos.isEmpty()) {
9877                     filteredInfos.add(getUiccCardInfoUnPrivileged(cardInfo));
9878                     continue;
9879                 }
9880                 List<UiccPortInfo> uiccPortInfos = new  ArrayList<>();
9881                 for (UiccPortInfo portInfo : portInfos) {
9882                     UiccPort port = uiccController.getUiccPortForSlot(
9883                             cardInfo.getPhysicalSlotIndex(), portInfo.getPortIndex());
9884                     if (port == null) {
9885                         // assume no access if port is null
9886                         uiccPortInfos.add(getUiccPortInfoUnPrivileged(portInfo));
9887                         continue;
9888                     }
9889                     if (haveCarrierPrivilegeAccess(port, callingPackage)) {
9890                         uiccPortInfos.add(portInfo);
9891                     } else {
9892                         uiccPortInfos.add(getUiccPortInfoUnPrivileged(portInfo));
9893                     }
9894                 }
9895                 filteredInfos.add(new UiccCardInfo(
9896                         cardInfo.isEuicc(),
9897                         cardInfo.getCardId(),
9898                         null,
9899                         cardInfo.getPhysicalSlotIndex(),
9900                         cardInfo.isRemovable(),
9901                         cardInfo.isMultipleEnabledProfilesSupported(),
9902                         uiccPortInfos));
9903             }
9904             return filteredInfos;
9905         } finally {
9906             Binder.restoreCallingIdentity(identity);
9907         }
9908     }
9909 
9910     /**
9911      * Returns a copy of the UiccCardinfo with the EID and ICCID set to null. These values are
9912      * generally private and require carrier privileges to view.
9913      *
9914      * @hide
9915      */
9916     @NonNull
getUiccCardInfoUnPrivileged(UiccCardInfo cardInfo)9917     public UiccCardInfo getUiccCardInfoUnPrivileged(UiccCardInfo cardInfo) {
9918         List<UiccPortInfo> portinfo = new  ArrayList<>();
9919         for (UiccPortInfo portinfos : cardInfo.getPorts()) {
9920             portinfo.add(getUiccPortInfoUnPrivileged(portinfos));
9921         }
9922         return new UiccCardInfo(
9923                 cardInfo.isEuicc(),
9924                 cardInfo.getCardId(),
9925                 null,
9926                 cardInfo.getPhysicalSlotIndex(),
9927                 cardInfo.isRemovable(),
9928                 cardInfo.isMultipleEnabledProfilesSupported(),
9929                 portinfo
9930         );
9931     }
9932 
9933     /**
9934      * @hide
9935      * @return a copy of the UiccPortInfo with ICCID set to {@link UiccPortInfo#ICCID_REDACTED}.
9936      * These values are generally private and require carrier privileges to view.
9937      */
9938     @NonNull
getUiccPortInfoUnPrivileged(UiccPortInfo portInfo)9939     public UiccPortInfo getUiccPortInfoUnPrivileged(UiccPortInfo portInfo) {
9940         return new UiccPortInfo(
9941                 UiccPortInfo.ICCID_REDACTED,
9942                 portInfo.getPortIndex(),
9943                 portInfo.getLogicalSlotIndex(),
9944                 portInfo.isActive()
9945         );
9946     }
9947     @Override
getUiccSlotsInfo(String callingPackage)9948     public UiccSlotInfo[] getUiccSlotsInfo(String callingPackage) {
9949         // Verify that the callingPackage belongs to the calling UID
9950         mApp.getSystemService(AppOpsManager.class)
9951                 .checkPackage(Binder.getCallingUid(), callingPackage);
9952 
9953         boolean isLogicalSlotAccessRestricted = false;
9954 
9955         // This will make sure caller has the READ_PRIVILEGED_PHONE_STATE. Do not remove this as
9956         // we are reading iccId which is PII data.
9957         enforceReadPrivilegedPermission("getUiccSlotsInfo");
9958 
9959         enforceTelephonyFeatureWithException(callingPackage,
9960                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getUiccSlotsInfo");
9961 
9962         // checking compatibility, if calling app's target SDK is T and beyond.
9963         if (CompatChanges.isChangeEnabled(GET_API_SIGNATURES_FROM_UICC_PORT_INFO,
9964                 Binder.getCallingUid())) {
9965             isLogicalSlotAccessRestricted  = true;
9966         }
9967         final long identity = Binder.clearCallingIdentity();
9968         try {
9969             UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
9970             if (slots == null || slots.length == 0) {
9971                 Rlog.i(LOG_TAG, "slots is null or empty.");
9972                 return null;
9973             }
9974             UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
9975             for (int i = 0; i < slots.length; i++) {
9976                 UiccSlot slot = slots[i];
9977                 if (slot == null) {
9978                     continue;
9979                 }
9980 
9981                 String cardId;
9982                 UiccCard card = slot.getUiccCard();
9983                 if (card != null) {
9984                     cardId = card.getCardId();
9985                 } else {
9986                     cardId = slot.getEid();
9987                     if (TextUtils.isEmpty(cardId)) {
9988                         // If cardId is null, use iccId of default port as cardId.
9989                         cardId = slot.getIccId(TelephonyManager.DEFAULT_PORT_INDEX);
9990                     }
9991                 }
9992 
9993                 if (cardId != null) {
9994                     // if cardId is an ICCID, strip off trailing Fs before exposing to user
9995                     // if cardId is an EID, it's all digits so this is fine
9996                     cardId = IccUtils.stripTrailingFs(cardId);
9997                 }
9998 
9999                 int cardState = 0;
10000                 switch (slot.getCardState()) {
10001                     case CARDSTATE_ABSENT:
10002                         cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
10003                         break;
10004                     case CARDSTATE_PRESENT:
10005                         cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
10006                         break;
10007                     case CARDSTATE_ERROR:
10008                         cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
10009                         break;
10010                     case CARDSTATE_RESTRICTED:
10011                         cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
10012                         break;
10013                     default:
10014                         break;
10015 
10016                 }
10017                 List<UiccPortInfo> portInfos = new ArrayList<>();
10018                 int[] portIndexes = slot.getPortList();
10019                 for (int portIdx : portIndexes) {
10020                     String iccId = IccUtils.stripTrailingFs(getIccId(slot, portIdx,
10021                             callingPackage, /* hasReadPermission= */ true));
10022                     portInfos.add(new UiccPortInfo(iccId, portIdx,
10023                             slot.getPhoneIdFromPortIndex(portIdx), slot.isPortActive(portIdx)));
10024                 }
10025                 infos[i] = new UiccSlotInfo(
10026                         slot.isEuicc(),
10027                         cardId,
10028                         cardState,
10029                         slot.isExtendedApduSupported(),
10030                         slot.isRemovable(), portInfos);
10031                 //setting the value after compatibility check
10032                 infos[i].setLogicalSlotAccessRestricted(isLogicalSlotAccessRestricted);
10033             }
10034             return infos;
10035         } finally {
10036             Binder.restoreCallingIdentity(identity);
10037         }
10038     }
10039 
10040     /* Returns null if doesn't have read permission or carrier privilege access. */
getIccId(UiccSlot slot, int portIndex, String callingPackage, boolean hasReadPermission)10041     private String getIccId(UiccSlot slot, int portIndex, String callingPackage,
10042             boolean hasReadPermission) {
10043         String iccId = slot.getIccId(portIndex);
10044         if (hasReadPermission) { // if has read permission
10045             return iccId;
10046         } else {
10047             if (slot.getUiccCard() != null && slot.getUiccCard().getUiccPort(portIndex) != null) {
10048                 UiccPort port = slot.getUiccCard().getUiccPort(portIndex);
10049                 // if no read permission, checking carrier privilege access
10050                 if (haveCarrierPrivilegeAccess(port, callingPackage)) {
10051                     return iccId;
10052                 }
10053             }
10054         }
10055         // No read permission or carrier privilege access.
10056         return UiccPortInfo.ICCID_REDACTED;
10057     }
10058 
10059     @Override
10060     @Deprecated
switchSlots(int[] physicalSlots)10061     public boolean switchSlots(int[] physicalSlots) {
10062         enforceModifyPermission();
10063 
10064         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10065                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "switchSlots");
10066 
10067         final long identity = Binder.clearCallingIdentity();
10068         try {
10069             List<UiccSlotMapping> slotMappings = new ArrayList<>();
10070             for (int i = 0; i < physicalSlots.length; i++) {
10071                 // Deprecated API, hence MEP is not supported. Adding default portIndex 0.
10072                 slotMappings.add(new UiccSlotMapping(TelephonyManager.DEFAULT_PORT_INDEX,
10073                         physicalSlots[i], i));
10074             }
10075             return (Boolean) sendRequest(CMD_SWITCH_SLOTS, slotMappings);
10076         } finally {
10077             Binder.restoreCallingIdentity(identity);
10078         }
10079     }
10080 
10081     @Override
10082     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setSimSlotMapping(@onNull List<UiccSlotMapping> slotMapping)10083     public boolean setSimSlotMapping(@NonNull List<UiccSlotMapping> slotMapping) {
10084         enforceModifyPermission();
10085 
10086         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10087                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "setSimSlotMapping");
10088 
10089         final long identity = Binder.clearCallingIdentity();
10090         try {
10091             return (Boolean) sendRequest(CMD_SWITCH_SLOTS, slotMapping);
10092         } finally {
10093             Binder.restoreCallingIdentity(identity);
10094         }
10095     }
10096 
10097     @Override
getCardIdForDefaultEuicc(int subId, String callingPackage)10098     public int getCardIdForDefaultEuicc(int subId, String callingPackage) {
10099         enforceTelephonyFeatureWithException(callingPackage,
10100                 PackageManager.FEATURE_TELEPHONY_EUICC, "getCardIdForDefaultEuicc");
10101 
10102         final long identity = Binder.clearCallingIdentity();
10103         try {
10104             return UiccController.getInstance().getCardIdForDefaultEuicc();
10105         } finally {
10106             Binder.restoreCallingIdentity(identity);
10107         }
10108     }
10109 
10110     /**
10111      * A test API to reload the UICC profile.
10112      *
10113      * <p>Requires that the calling app has permission
10114      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
10115      * @hide
10116      */
10117     @Override
refreshUiccProfile(int subId)10118     public void refreshUiccProfile(int subId) {
10119         enforceModifyPermission();
10120 
10121         final long identity = Binder.clearCallingIdentity();
10122         try {
10123             Phone phone = getPhone(subId);
10124             if (phone == null) {
10125                 return;
10126             }
10127             UiccPort uiccPort = phone.getUiccPort();
10128             if (uiccPort == null) {
10129                 return;
10130             }
10131             UiccProfile uiccProfile = uiccPort.getUiccProfile();
10132             if (uiccProfile == null) {
10133                 return;
10134             }
10135             uiccProfile.refresh();
10136         } finally {
10137             Binder.restoreCallingIdentity(identity);
10138         }
10139     }
10140 
10141     /**
10142      * Returns false if the mobile data is disabled by default, otherwise return true.
10143      */
getDefaultDataEnabled()10144     private boolean getDefaultDataEnabled() {
10145         return TelephonyProperties.mobile_data().orElse(true);
10146     }
10147 
10148     /**
10149      * Returns the default network type for the given {@code subId}, if the default network type is
10150      * not set, return {@link Phone#PREFERRED_NT_MODE}.
10151      */
getDefaultNetworkType(int subId)10152     private int getDefaultNetworkType(int subId) {
10153         List<Integer> list = TelephonyProperties.default_network();
10154         int phoneId = SubscriptionManager.getPhoneId(subId);
10155         if (phoneId >= 0 && phoneId < list.size() && list.get(phoneId) != null) {
10156             return list.get(phoneId);
10157         }
10158         return Phone.PREFERRED_NT_MODE;
10159     }
10160 
10161     @Override
setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn)10162     public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
10163             gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn) {
10164         enforceModifyPermission();
10165 
10166         final long identity = Binder.clearCallingIdentity();
10167         try {
10168             final Phone phone = getPhone(subId);
10169             if (phone == null) {
10170                 loge("setCarrierTestOverride fails with invalid subId: " + subId);
10171                 return;
10172             }
10173             CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
10174             if (cpt != null) {
10175                 cpt.setTestOverrideCarrierPrivilegeRules(carrierPrivilegeRules);
10176             }
10177             // TODO(b/211796398): remove the legacy logic below once CPT migration is done.
10178             phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn,
10179                     carrierPrivilegeRules, apn);
10180             if (carrierPrivilegeRules == null) {
10181                 mCarrierPrivilegeTestOverrideSubIds.remove(subId);
10182             } else {
10183                 mCarrierPrivilegeTestOverrideSubIds.add(subId);
10184             }
10185         } finally {
10186             Binder.restoreCallingIdentity(identity);
10187         }
10188     }
10189 
10190     @Override
setCarrierServicePackageOverride( int subId, String carrierServicePackage, String callingPackage)10191     public void setCarrierServicePackageOverride(
10192             int subId, String carrierServicePackage, String callingPackage) {
10193         TelephonyPermissions.enforceShellOnly(
10194                 Binder.getCallingUid(), "setCarrierServicePackageOverride");
10195 
10196         final long identity = Binder.clearCallingIdentity();
10197         try {
10198             final Phone phone = getPhone(subId);
10199             if (phone == null || phone.getSubId() != subId) {
10200                 loge("setCarrierServicePackageOverride fails with invalid subId: " + subId);
10201                 throw new IllegalArgumentException("No phone for subid");
10202             }
10203             CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
10204             if (cpt == null) {
10205                 loge("setCarrierServicePackageOverride failed with no CPT for phone");
10206                 throw new IllegalStateException("No CPT for phone");
10207             }
10208             cpt.setTestOverrideCarrierServicePackage(carrierServicePackage);
10209         } finally {
10210             Binder.restoreCallingIdentity(identity);
10211         }
10212     }
10213 
10214     @Override
getCarrierIdListVersion(int subId)10215     public int getCarrierIdListVersion(int subId) {
10216         enforceReadPrivilegedPermission("getCarrierIdListVersion");
10217 
10218         final long identity = Binder.clearCallingIdentity();
10219         try {
10220             final Phone phone = getPhone(subId);
10221             if (phone == null) {
10222                 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
10223                 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
10224             }
10225             return phone.getCarrierIdListVersion();
10226         } finally {
10227             Binder.restoreCallingIdentity(identity);
10228         }
10229     }
10230 
10231     @Override
getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage, String callingFeatureId)10232     public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage,
10233             String callingFeatureId) {
10234         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
10235                 mApp, subId, callingPackage, callingFeatureId,
10236                 "getNumberOfModemsWithSimultaneousDataConnections")) {
10237             return -1;
10238         }
10239 
10240         final long identity = Binder.clearCallingIdentity();
10241         try {
10242             return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
10243         } finally {
10244             Binder.restoreCallingIdentity(identity);
10245         }
10246     }
10247 
10248     @Override
getCdmaRoamingMode(int subId)10249     public int getCdmaRoamingMode(int subId) {
10250         TelephonyPermissions
10251                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
10252                         mApp, subId, "getCdmaRoamingMode");
10253 
10254         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10255                 PackageManager.FEATURE_TELEPHONY_CDMA, "getCdmaRoamingMode");
10256 
10257         final long identity = Binder.clearCallingIdentity();
10258         try {
10259             return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
10260         } finally {
10261             Binder.restoreCallingIdentity(identity);
10262         }
10263     }
10264 
10265     @Override
setCdmaRoamingMode(int subId, int mode)10266     public boolean setCdmaRoamingMode(int subId, int mode) {
10267         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
10268                 mApp, subId, "setCdmaRoamingMode");
10269 
10270         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10271                 PackageManager.FEATURE_TELEPHONY_CDMA, "setCdmaRoamingMode");
10272 
10273         final long identity = Binder.clearCallingIdentity();
10274         try {
10275             return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
10276         } finally {
10277             Binder.restoreCallingIdentity(identity);
10278         }
10279     }
10280 
10281     @Override
getCdmaSubscriptionMode(int subId)10282     public int getCdmaSubscriptionMode(int subId) {
10283         TelephonyPermissions
10284                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
10285                         mApp, subId, "getCdmaSubscriptionMode");
10286 
10287         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10288                 PackageManager.FEATURE_TELEPHONY_CDMA, "getCdmaSubscriptionMode");
10289 
10290         final long identity = Binder.clearCallingIdentity();
10291         try {
10292             return (int) sendRequest(CMD_GET_CDMA_SUBSCRIPTION_MODE, null /* argument */, subId);
10293         } finally {
10294             Binder.restoreCallingIdentity(identity);
10295         }
10296     }
10297 
10298     @Override
setCdmaSubscriptionMode(int subId, int mode)10299     public boolean setCdmaSubscriptionMode(int subId, int mode) {
10300         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
10301                 mApp, subId, "setCdmaSubscriptionMode");
10302 
10303         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10304                 PackageManager.FEATURE_TELEPHONY_CDMA, "setCdmaSubscriptionMode");
10305 
10306         final long identity = Binder.clearCallingIdentity();
10307         try {
10308             return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
10309         } finally {
10310             Binder.restoreCallingIdentity(identity);
10311         }
10312     }
10313 
10314     @Override
getEmergencyNumberList( String callingPackage, String callingFeatureId)10315     public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
10316             String callingPackage, String callingFeatureId) {
10317         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
10318                 mApp, getDefaultSubscription(), callingPackage, callingFeatureId,
10319                 "getEmergencyNumberList")) {
10320             throw new SecurityException("Requires READ_PHONE_STATE permission.");
10321         }
10322 
10323         enforceTelephonyFeatureWithException(callingPackage,
10324                 PackageManager.FEATURE_TELEPHONY_CALLING, "getEmergencyNumberList");
10325 
10326         final long identity = Binder.clearCallingIdentity();
10327         try {
10328             Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
10329             for (Phone phone: PhoneFactory.getPhones()) {
10330                 if (phone.getEmergencyNumberTracker() != null
10331                         && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
10332                     emergencyNumberListInternal.put(
10333                             phone.getSubId(),
10334                             phone.getEmergencyNumberTracker().getEmergencyNumberList());
10335                 }
10336             }
10337             return emergencyNumberListInternal;
10338         } finally {
10339             Binder.restoreCallingIdentity(identity);
10340         }
10341     }
10342 
10343     @Override
isEmergencyNumber(String number, boolean exactMatch)10344     public boolean isEmergencyNumber(String number, boolean exactMatch) {
10345         final Phone defaultPhone = getDefaultPhone();
10346         if (!exactMatch) {
10347             TelephonyPermissions
10348                     .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
10349                             mApp, defaultPhone.getSubId(), "isEmergencyNumber(Potential)");
10350         }
10351 
10352         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10353                 PackageManager.FEATURE_TELEPHONY_CALLING, "isEmergencyNumber");
10354 
10355         final long identity = Binder.clearCallingIdentity();
10356         try {
10357             for (Phone phone: PhoneFactory.getPhones()) {
10358                 //Note: we ignore passed in param exactMatch. We can remove it once
10359                 // TelephonyManager#isPotentialEmergencyNumber is removed completely
10360                 if (phone.getEmergencyNumberTracker() != null
10361                         && phone.getEmergencyNumberTracker()
10362                         .isEmergencyNumber(number)) {
10363                     return true;
10364                 }
10365             }
10366             return false;
10367         } finally {
10368             Binder.restoreCallingIdentity(identity);
10369         }
10370     }
10371 
10372     /**
10373      * Start emergency callback mode for GsmCdmaPhone for testing.
10374      */
10375     @Override
startEmergencyCallbackMode()10376     public void startEmergencyCallbackMode() {
10377         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10378                 "startEmergencyCallbackMode");
10379         enforceModifyPermission();
10380         final long identity = Binder.clearCallingIdentity();
10381         try {
10382             for (Phone phone : PhoneFactory.getPhones()) {
10383                 Rlog.d(LOG_TAG, "startEmergencyCallbackMode phone type: " + phone.getPhoneType());
10384                 if (phone != null && ((phone.getPhoneType() == PHONE_TYPE_GSM)
10385                         || (phone.getPhoneType() == PHONE_TYPE_CDMA))) {
10386                     GsmCdmaPhone gsmCdmaPhone = (GsmCdmaPhone) phone;
10387                     gsmCdmaPhone.obtainMessage(
10388                             GsmCdmaPhone.EVENT_EMERGENCY_CALLBACK_MODE_ENTER).sendToTarget();
10389                     Rlog.d(LOG_TAG, "startEmergencyCallbackMode: triggered");
10390                 }
10391             }
10392         } finally {
10393             Binder.restoreCallingIdentity(identity);
10394         }
10395     }
10396 
10397     /**
10398      * Update emergency number list for test mode.
10399      */
10400     @Override
updateEmergencyNumberListTestMode(int action, EmergencyNumber num)10401     public void updateEmergencyNumberListTestMode(int action, EmergencyNumber num) {
10402         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10403                 "updateEmergencyNumberListTestMode");
10404 
10405         final long identity = Binder.clearCallingIdentity();
10406         try {
10407             for (Phone phone: PhoneFactory.getPhones()) {
10408                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
10409                 if (tracker != null) {
10410                     tracker.executeEmergencyNumberTestModeCommand(action, num);
10411                 }
10412             }
10413         } finally {
10414             Binder.restoreCallingIdentity(identity);
10415         }
10416     }
10417 
10418     /**
10419      * Get the full emergency number list for test mode.
10420      */
10421     @Override
getEmergencyNumberListTestMode()10422     public List<String> getEmergencyNumberListTestMode() {
10423         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10424                 "getEmergencyNumberListTestMode");
10425 
10426         final long identity = Binder.clearCallingIdentity();
10427         try {
10428             Set<String> emergencyNumbers = new HashSet<>();
10429             for (Phone phone: PhoneFactory.getPhones()) {
10430                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
10431                 if (tracker != null) {
10432                     for (EmergencyNumber num : tracker.getEmergencyNumberList()) {
10433                         emergencyNumbers.add(num.getNumber());
10434                     }
10435                 }
10436             }
10437             return new ArrayList<>(emergencyNumbers);
10438         } finally {
10439             Binder.restoreCallingIdentity(identity);
10440         }
10441     }
10442 
10443     @Override
getEmergencyNumberDbVersion(int subId)10444     public int getEmergencyNumberDbVersion(int subId) {
10445         enforceReadPrivilegedPermission("getEmergencyNumberDbVersion");
10446 
10447         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10448                 PackageManager.FEATURE_TELEPHONY_CALLING, "getEmergencyNumberDbVersion");
10449 
10450         final long identity = Binder.clearCallingIdentity();
10451         try {
10452             final Phone phone = getPhone(subId);
10453             if (phone == null) {
10454                 loge("getEmergencyNumberDbVersion fails with invalid subId: " + subId);
10455                 return TelephonyManager.INVALID_EMERGENCY_NUMBER_DB_VERSION;
10456             }
10457             return phone.getEmergencyNumberDbVersion();
10458         } finally {
10459             Binder.restoreCallingIdentity(identity);
10460         }
10461     }
10462 
10463     @Override
notifyOtaEmergencyNumberDbInstalled()10464     public void notifyOtaEmergencyNumberDbInstalled() {
10465         enforceModifyPermission();
10466 
10467         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10468                 PackageManager.FEATURE_TELEPHONY_CALLING, "notifyOtaEmergencyNumberDbInstalled");
10469 
10470         final long identity = Binder.clearCallingIdentity();
10471         try {
10472             for (Phone phone: PhoneFactory.getPhones()) {
10473                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
10474                 if (tracker != null) {
10475                     tracker.updateOtaEmergencyNumberDatabase();
10476                 }
10477             }
10478         } finally {
10479             Binder.restoreCallingIdentity(identity);
10480         }
10481     }
10482 
10483     @Override
updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor)10484     public void updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor) {
10485         enforceActiveEmergencySessionPermission();
10486 
10487         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10488                 PackageManager.FEATURE_TELEPHONY_CALLING, "updateOtaEmergencyNumberDbFilePath");
10489 
10490         final long identity = Binder.clearCallingIdentity();
10491         try {
10492             for (Phone phone: PhoneFactory.getPhones()) {
10493                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
10494                 if (tracker != null) {
10495                     tracker.updateOtaEmergencyNumberDbFilePath(otaParcelFileDescriptor);
10496                 }
10497             }
10498         } finally {
10499             Binder.restoreCallingIdentity(identity);
10500         }
10501     }
10502 
10503     @Override
resetOtaEmergencyNumberDbFilePath()10504     public void resetOtaEmergencyNumberDbFilePath() {
10505         enforceActiveEmergencySessionPermission();
10506 
10507         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10508                 PackageManager.FEATURE_TELEPHONY_CALLING, "resetOtaEmergencyNumberDbFilePath");
10509 
10510         final long identity = Binder.clearCallingIdentity();
10511         try {
10512             for (Phone phone: PhoneFactory.getPhones()) {
10513                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
10514                 if (tracker != null) {
10515                     tracker.resetOtaEmergencyNumberDbFilePath();
10516                 }
10517             }
10518         } finally {
10519             Binder.restoreCallingIdentity(identity);
10520         }
10521     }
10522 
10523     @Override
getCertsFromCarrierPrivilegeAccessRules(int subId)10524     public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
10525         enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
10526         Phone phone = getPhone(subId);
10527         if (phone == null) {
10528             return null;
10529         }
10530         final long identity = Binder.clearCallingIdentity();
10531         try {
10532             UiccProfile profile = UiccController.getInstance()
10533                     .getUiccProfileForPhone(phone.getPhoneId());
10534             if (profile != null) {
10535                 return profile.getCertsFromCarrierPrivilegeAccessRules();
10536             }
10537         } finally {
10538             Binder.restoreCallingIdentity(identity);
10539         }
10540         return null;
10541     }
10542 
10543     /**
10544      * Enable or disable a modem stack.
10545      */
10546     @Override
enableModemForSlot(int slotIndex, boolean enable)10547     public boolean enableModemForSlot(int slotIndex, boolean enable) {
10548         enforceModifyPermission();
10549 
10550         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10551                 PackageManager.FEATURE_TELEPHONY, "enableModemForSlot");
10552 
10553         final long identity = Binder.clearCallingIdentity();
10554         try {
10555             Phone phone = PhoneFactory.getPhone(slotIndex);
10556             if (phone == null) {
10557                 return false;
10558             } else {
10559                 return (Boolean) sendRequest(CMD_REQUEST_ENABLE_MODEM, enable, phone, null);
10560             }
10561         } finally {
10562             Binder.restoreCallingIdentity(identity);
10563         }
10564     }
10565 
10566     /**
10567      * Whether a modem stack is enabled or not.
10568      */
10569     @Override
isModemEnabledForSlot(int slotIndex, String callingPackage, String callingFeatureId)10570     public boolean isModemEnabledForSlot(int slotIndex, String callingPackage,
10571             String callingFeatureId) {
10572         Phone phone = PhoneFactory.getPhone(slotIndex);
10573         if (phone == null) return false;
10574 
10575         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
10576                 mApp, phone.getSubId(), callingPackage, callingFeatureId,
10577                 "isModemEnabledForSlot")) {
10578             throw new SecurityException("Requires READ_PHONE_STATE permission.");
10579         }
10580 
10581         enforceTelephonyFeatureWithException(callingPackage,
10582                 PackageManager.FEATURE_TELEPHONY, "isModemEnabledForSlot");
10583 
10584         final long identity = Binder.clearCallingIdentity();
10585         try {
10586             try {
10587                 return mPhoneConfigurationManager.getPhoneStatusFromCache(phone.getPhoneId());
10588             } catch (NoSuchElementException ex) {
10589                 return (Boolean) sendRequest(CMD_GET_MODEM_STATUS, null, phone, null);
10590             }
10591         } finally {
10592             Binder.restoreCallingIdentity(identity);
10593         }
10594     }
10595 
10596     @Override
setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted)10597     public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
10598         enforceModifyPermission();
10599 
10600         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10601                 PackageManager.FEATURE_TELEPHONY_CARRIERLOCK, "setMultiSimCarrierRestriction");
10602 
10603         final long identity = Binder.clearCallingIdentity();
10604         try {
10605             mTelephonySharedPreferences.edit()
10606                     .putBoolean(PREF_MULTI_SIM_RESTRICTED, isMultiSimCarrierRestricted)
10607                     .commit();
10608         } finally {
10609             Binder.restoreCallingIdentity(identity);
10610         }
10611     }
10612 
10613     @Override
10614     @TelephonyManager.IsMultiSimSupportedResult
isMultiSimSupported(String callingPackage, String callingFeatureId)10615     public int isMultiSimSupported(String callingPackage, String callingFeatureId) {
10616         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
10617                 getDefaultPhone().getSubId(), callingPackage, callingFeatureId,
10618                 "isMultiSimSupported")) {
10619             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
10620         }
10621 
10622         enforceTelephonyFeatureWithException(callingPackage,
10623                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "isMultiSimSupported");
10624 
10625         final long identity = Binder.clearCallingIdentity();
10626         try {
10627             return isMultiSimSupportedInternal();
10628         } finally {
10629             Binder.restoreCallingIdentity(identity);
10630         }
10631     }
10632 
10633     @TelephonyManager.IsMultiSimSupportedResult
isMultiSimSupportedInternal()10634     private int isMultiSimSupportedInternal() {
10635         // If the device has less than 2 SIM cards, indicate that multisim is restricted.
10636         int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
10637         if (numPhysicalSlots < 2) {
10638             loge("isMultiSimSupportedInternal: requires at least 2 cards");
10639             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
10640         }
10641         // Check if the hardware supports multisim functionality. If usage of multisim is not
10642         // supported by the modem, indicate that it is restricted.
10643         PhoneCapability staticCapability =
10644                 mPhoneConfigurationManager.getStaticPhoneCapability();
10645         if (staticCapability == null) {
10646             loge("isMultiSimSupportedInternal: no static configuration available");
10647             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
10648         }
10649         if (staticCapability.getLogicalModemList().size() < 2) {
10650             loge("isMultiSimSupportedInternal: maximum number of modem is < 2");
10651             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
10652         }
10653         // Check if support of multiple SIMs is restricted by carrier
10654         if (mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false)) {
10655             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_CARRIER;
10656         }
10657 
10658         return TelephonyManager.MULTISIM_ALLOWED;
10659     }
10660 
10661     /**
10662      * Switch configs to enable multi-sim or switch back to single-sim
10663      * Note: Switch from multi-sim to single-sim is only possible with MODIFY_PHONE_STATE
10664      * permission, but the other way around is possible with either MODIFY_PHONE_STATE
10665      * or carrier privileges
10666      * @param numOfSims number of active sims we want to switch to
10667      */
10668     @Override
switchMultiSimConfig(int numOfSims)10669     public void switchMultiSimConfig(int numOfSims) {
10670         if (numOfSims == 1) {
10671             enforceModifyPermission();
10672         } else {
10673             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
10674                     mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
10675         }
10676 
10677         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10678                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "switchMultiSimConfig");
10679 
10680         final long identity = Binder.clearCallingIdentity();
10681 
10682         try {
10683             //only proceed if multi-sim is not restricted
10684             if (isMultiSimSupportedInternal() != TelephonyManager.MULTISIM_ALLOWED) {
10685                 loge("switchMultiSimConfig not possible. It is restricted or not supported.");
10686                 return;
10687             }
10688             mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
10689         } finally {
10690             Binder.restoreCallingIdentity(identity);
10691         }
10692     }
10693 
10694     @Override
isApplicationOnUicc(int subId, int appType)10695     public boolean isApplicationOnUicc(int subId, int appType) {
10696         enforceReadPrivilegedPermission("isApplicationOnUicc");
10697 
10698         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10699                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "isApplicationOnUicc");
10700 
10701         Phone phone = getPhone(subId);
10702         if (phone == null) {
10703             return false;
10704         }
10705         final long identity = Binder.clearCallingIdentity();
10706         try {
10707             UiccPort uiccPort = phone.getUiccPort();
10708             if (uiccPort == null) {
10709                 return false;
10710             }
10711             UiccProfile uiccProfile = uiccPort.getUiccProfile();
10712             if (uiccProfile == null) {
10713                 return false;
10714             }
10715             if (TelephonyManager.APPTYPE_SIM <= appType
10716                     && appType <= TelephonyManager.APPTYPE_ISIM) {
10717                 return uiccProfile.isApplicationOnIcc(AppType.values()[appType]);
10718             }
10719             return false;
10720         } finally {
10721             Binder.restoreCallingIdentity(identity);
10722         }
10723     }
10724 
10725     /**
10726      * Get whether making changes to modem configurations will trigger reboot.
10727      * Return value defaults to true.
10728      */
10729     @Override
doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage, String callingFeatureId)10730     public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage,
10731             String callingFeatureId) {
10732         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
10733                 mApp, subId, callingPackage, callingFeatureId,
10734                 "doesSwitchMultiSimConfigTriggerReboot")) {
10735             return false;
10736         }
10737 
10738         enforceTelephonyFeatureWithException(callingPackage,
10739                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
10740                 "doesSwitchMultiSimConfigTriggerReboot");
10741 
10742         final long identity = Binder.clearCallingIdentity();
10743         try {
10744             return mPhoneConfigurationManager.isRebootRequiredForModemConfigChange();
10745         } finally {
10746             Binder.restoreCallingIdentity(identity);
10747         }
10748     }
10749 
updateModemStateMetrics()10750     private void updateModemStateMetrics() {
10751         TelephonyMetrics metrics = TelephonyMetrics.getInstance();
10752         // TODO: check the state for each modem if the api is ready.
10753         metrics.updateEnabledModemBitmap((1 << TelephonyManager.from(mApp).getPhoneCount()) - 1);
10754     }
10755 
10756     @Override
getSlotsMapping(String callingPackage)10757     public List<UiccSlotMapping> getSlotsMapping(String callingPackage) {
10758         enforceReadPrivilegedPermission("getSlotsMapping");
10759         // Verify that the callingPackage belongs to the calling UID
10760         mApp.getSystemService(AppOpsManager.class)
10761                 .checkPackage(Binder.getCallingUid(), callingPackage);
10762 
10763         enforceTelephonyFeatureWithException(callingPackage,
10764                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSlotsMapping");
10765 
10766         final long identity = Binder.clearCallingIdentity();
10767         List<UiccSlotMapping> slotMap = new ArrayList<>();
10768         try {
10769             UiccSlotInfo[] slotInfos = getUiccSlotsInfo(mApp.getOpPackageName());
10770             if (slotInfos != null) {
10771                 for (int i = 0; i < slotInfos.length; i++) {
10772                     for (UiccPortInfo portInfo : slotInfos[i].getPorts()) {
10773                         if (SubscriptionManager.isValidPhoneId(portInfo.getLogicalSlotIndex())) {
10774                             slotMap.add(new UiccSlotMapping(portInfo.getPortIndex(), i,
10775                                     portInfo.getLogicalSlotIndex()));
10776                         }
10777                     }
10778                 }
10779             }
10780             return slotMap;
10781         } finally {
10782             Binder.restoreCallingIdentity(identity);
10783         }
10784     }
10785 
10786     /**
10787      * Get the IRadio HAL Version
10788      * @deprecated use getHalVersion instead
10789      */
10790     @Deprecated
10791     @Override
getRadioHalVersion()10792     public int getRadioHalVersion() {
10793         return getHalVersion(HAL_SERVICE_RADIO);
10794     }
10795 
10796     /**
10797      * Get the HAL Version of a specific service
10798      */
10799     @Override
getHalVersion(int service)10800     public int getHalVersion(int service) {
10801         Phone phone = getDefaultPhone();
10802         if (phone == null) return -1;
10803         HalVersion hv = phone.getHalVersion(service);
10804         if (hv.equals(HalVersion.UNKNOWN)) return -1;
10805         return hv.major * 100 + hv.minor;
10806     }
10807 
10808     /**
10809      * Get the current calling package name.
10810      *
10811      * @return the current calling package name, or null if there is no known package.
10812      */
10813     @Override
getCurrentPackageName()10814     public @Nullable String getCurrentPackageName() {
10815         PackageManager pm = mApp.getPackageManager();
10816         String[] packageNames = pm == null ? null : pm.getPackagesForUid(Binder.getCallingUid());
10817         return packageNames == null ? null : packageNames[0];
10818     }
10819 
10820     /**
10821      * Return whether data is enabled for certain APN type. This will tell if framework will accept
10822      * corresponding network requests on a subId.
10823      *
10824      *  Data is enabled if:
10825      *  1) user data is turned on, or
10826      *  2) APN is un-metered for this subscription, or
10827      *  3) APN type is whitelisted. E.g. MMS is whitelisted if
10828      *  {@link TelephonyManager#MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED} is enabled.
10829      *
10830      * @return whether data is allowed for a apn type.
10831      *
10832      * @hide
10833      */
10834     @Override
isDataEnabledForApn(int apnType, int subId, String callingPackage)10835     public boolean isDataEnabledForApn(int apnType, int subId, String callingPackage) {
10836         enforceReadPrivilegedPermission("Needs READ_PRIVILEGED_PHONE_STATE for "
10837                 + "isDataEnabledForApn");
10838 
10839         enforceTelephonyFeatureWithException(callingPackage,
10840                 PackageManager.FEATURE_TELEPHONY_DATA, "isDataEnabledForApn");
10841 
10842         // Now that all security checks passes, perform the operation as ourselves.
10843         final long identity = Binder.clearCallingIdentity();
10844         try {
10845             Phone phone = getPhone(subId);
10846             if (phone == null) return false;
10847 
10848             boolean isMetered;
10849             boolean isDataEnabled;
10850             isMetered = phone.getDataNetworkController().getDataConfigManager()
10851                     .isMeteredCapability(DataUtils.apnTypeToNetworkCapability(apnType),
10852                             phone.getServiceState().getDataRoaming());
10853             isDataEnabled = phone.getDataSettingsManager().isDataEnabled(apnType);
10854             return !isMetered || isDataEnabled;
10855         } finally {
10856             Binder.restoreCallingIdentity(identity);
10857         }
10858     }
10859 
10860     @Override
isApnMetered(@pnType int apnType, int subId)10861     public boolean isApnMetered(@ApnType int apnType, int subId) {
10862         enforceReadPrivilegedPermission("isApnMetered");
10863 
10864         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10865                 PackageManager.FEATURE_TELEPHONY_DATA, "isApnMetered");
10866 
10867         // Now that all security checks passes, perform the operation as ourselves.
10868         final long identity = Binder.clearCallingIdentity();
10869         try {
10870             Phone phone = getPhone(subId);
10871             if (phone == null) return true; // By default return true.
10872             return phone.getDataNetworkController().getDataConfigManager().isMeteredCapability(
10873                     DataUtils.apnTypeToNetworkCapability(apnType),
10874                     phone.getServiceState().getDataRoaming());
10875         } finally {
10876             Binder.restoreCallingIdentity(identity);
10877         }
10878     }
10879 
10880     @Override
setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers, int subscriptionId, IBooleanConsumer resultCallback)10881     public void setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers,
10882             int subscriptionId, IBooleanConsumer resultCallback) {
10883         enforceModifyPermission();
10884 
10885         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10886                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "setSystemSelectionChannels");
10887 
10888         long token = Binder.clearCallingIdentity();
10889         try {
10890             Phone phone = getPhone(subscriptionId);
10891             if (phone == null) {
10892                 try {
10893                     if (resultCallback != null) {
10894                         resultCallback.accept(false);
10895                     }
10896                 } catch (RemoteException e) {
10897                     // ignore
10898                 }
10899                 return;
10900             }
10901             Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> argument =
10902                     Pair.create(specifiers, (x) -> {
10903                         try {
10904                             if (resultCallback != null) {
10905                                 resultCallback.accept(x);
10906                             }
10907                         } catch (RemoteException e) {
10908                             // ignore
10909                         }
10910                     });
10911             sendRequestAsync(CMD_SET_SYSTEM_SELECTION_CHANNELS, argument, phone, null);
10912         } finally {
10913             Binder.restoreCallingIdentity(token);
10914         }
10915     }
10916 
10917     @Override
getSystemSelectionChannels(int subId)10918     public List<RadioAccessSpecifier> getSystemSelectionChannels(int subId) {
10919         TelephonyPermissions
10920                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
10921                         mApp, subId, "getSystemSelectionChannels");
10922 
10923         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10924                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getSystemSelectionChannels");
10925 
10926         WorkSource workSource = getWorkSource(Binder.getCallingUid());
10927         final long identity = Binder.clearCallingIdentity();
10928         try {
10929             Object result = sendRequest(CMD_GET_SYSTEM_SELECTION_CHANNELS, null, subId, workSource);
10930             if (result instanceof IllegalStateException) {
10931                 throw (IllegalStateException) result;
10932             }
10933             List<RadioAccessSpecifier> specifiers = (List<RadioAccessSpecifier>) result;
10934             if (DBG) log("getSystemSelectionChannels: " + specifiers);
10935             return specifiers;
10936         } finally {
10937             Binder.restoreCallingIdentity(identity);
10938         }
10939     }
10940 
10941     @Override
isMvnoMatched(int slotIndex, int mvnoType, @NonNull String mvnoMatchData)10942     public boolean isMvnoMatched(int slotIndex, int mvnoType, @NonNull String mvnoMatchData) {
10943         enforceReadPrivilegedPermission("isMvnoMatched");
10944 
10945         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10946                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "isMvnoMatched");
10947 
10948         return UiccController.getInstance().mvnoMatches(slotIndex, mvnoType, mvnoMatchData);
10949     }
10950 
10951     @Override
enqueueSmsPickResult(String callingPackage, String callingAttributionTag, IIntegerConsumer pendingSubIdResult)10952     public void enqueueSmsPickResult(String callingPackage, String callingAttributionTag,
10953             IIntegerConsumer pendingSubIdResult) {
10954         if (callingPackage == null) {
10955             callingPackage = getCurrentPackageName();
10956         }
10957         SmsPermissions permissions = new SmsPermissions(getDefaultPhone(), mApp,
10958                 (AppOpsManager) mApp.getSystemService(Context.APP_OPS_SERVICE));
10959         if (!permissions.checkCallingCanSendSms(callingPackage, callingAttributionTag,
10960                 "Sending message")) {
10961             throw new SecurityException("Requires SEND_SMS permission to perform this operation");
10962         }
10963         PickSmsSubscriptionActivity.addPendingResult(pendingSubIdResult);
10964         Intent intent = new Intent();
10965         intent.setClass(mApp, PickSmsSubscriptionActivity.class);
10966         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10967         // Bring up choose default SMS subscription dialog right now
10968         intent.putExtra(PickSmsSubscriptionActivity.DIALOG_TYPE_KEY,
10969                 PickSmsSubscriptionActivity.SMS_PICK_FOR_MESSAGE);
10970         mApp.startActivity(intent);
10971     }
10972 
10973     @Override
showSwitchToManagedProfileDialog()10974     public void showSwitchToManagedProfileDialog() {
10975         enforceModifyPermission();
10976         try {
10977             // Note: This intent is constructed to ensure that the IntentForwarderActivity is
10978             // shown in accordance with the intent filters in DefaultCrossProfileIntentFilterUtils
10979             // for work telephony.
10980             Intent intent = new Intent(Intent.ACTION_SENDTO);
10981             intent.setData(Uri.parse("smsto:"));
10982             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10983             mApp.startActivity(intent);
10984         } catch (ActivityNotFoundException e) {
10985             Log.w(LOG_TAG, "Unable to show intent forwarder, try showing error dialog instead");
10986             Intent intent = new Intent();
10987             intent.setClass(mApp, ErrorDialogActivity.class);
10988             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10989             mApp.startActivity(intent);
10990         }
10991     }
10992 
10993     @Override
getMmsUAProfUrl(int subId)10994     public String getMmsUAProfUrl(int subId) {
10995         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10996                 PackageManager.FEATURE_TELEPHONY_MESSAGING, "getMmsUAProfUrl");
10997 
10998         //TODO investigate if this API should require proper permission check in R b/133791609
10999         final long identity = Binder.clearCallingIdentity();
11000         try {
11001             String carrierUAProfUrl = mApp.getCarrierConfigForSubId(subId).getString(
11002                     CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING);
11003             if (!TextUtils.isEmpty(carrierUAProfUrl)) {
11004                 return carrierUAProfUrl;
11005             }
11006             return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
11007                     .getString(com.android.internal.R.string.config_mms_user_agent_profile_url);
11008         } finally {
11009             Binder.restoreCallingIdentity(identity);
11010         }
11011     }
11012 
11013     @Override
getMmsUserAgent(int subId)11014     public String getMmsUserAgent(int subId) {
11015         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11016                 PackageManager.FEATURE_TELEPHONY_MESSAGING, "getMmsUserAgent");
11017 
11018         //TODO investigate if this API should require proper permission check in R b/133791609
11019         final long identity = Binder.clearCallingIdentity();
11020         try {
11021             String carrierUserAgent = mApp.getCarrierConfigForSubId(subId).getString(
11022                     CarrierConfigManager.KEY_MMS_USER_AGENT_STRING);
11023             if (!TextUtils.isEmpty(carrierUserAgent)) {
11024                 return carrierUserAgent;
11025             }
11026             return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
11027                     .getString(com.android.internal.R.string.config_mms_user_agent);
11028         } finally {
11029             Binder.restoreCallingIdentity(identity);
11030         }
11031     }
11032 
11033     @Override
isMobileDataPolicyEnabled(int subscriptionId, int policy)11034     public boolean isMobileDataPolicyEnabled(int subscriptionId, int policy) {
11035         enforceReadPrivilegedPermission("isMobileDataPolicyEnabled");
11036 
11037         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11038                 PackageManager.FEATURE_TELEPHONY_DATA, "isMobileDataPolicyEnabled");
11039 
11040         final long identity = Binder.clearCallingIdentity();
11041         try {
11042             Phone phone = getPhone(subscriptionId);
11043             if (phone == null) return false;
11044 
11045             return phone.getDataSettingsManager().isMobileDataPolicyEnabled(policy);
11046         } finally {
11047             Binder.restoreCallingIdentity(identity);
11048         }
11049     }
11050 
11051     @Override
setMobileDataPolicyEnabled(int subscriptionId, int policy, boolean enabled)11052     public void setMobileDataPolicyEnabled(int subscriptionId, int policy,
11053             boolean enabled) {
11054         enforceModifyPermission();
11055 
11056         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11057                 PackageManager.FEATURE_TELEPHONY_DATA, "setMobileDataPolicyEnabled");
11058 
11059         final long identity = Binder.clearCallingIdentity();
11060         try {
11061             Phone phone = getPhone(subscriptionId);
11062             if (phone == null) return;
11063 
11064             phone.getDataSettingsManager().setMobileDataPolicy(policy, enabled);
11065         } finally {
11066             Binder.restoreCallingIdentity(identity);
11067         }
11068     }
11069 
11070     /**
11071      * Updates whether conference event package handling is enabled.
11072      * @param isCepEnabled {@code true} if CEP handling is enabled (default), or {@code false}
11073      *                                 otherwise.
11074      */
11075     @Override
setCepEnabled(boolean isCepEnabled)11076     public void setCepEnabled(boolean isCepEnabled) {
11077         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCepEnabled");
11078 
11079         final long identity = Binder.clearCallingIdentity();
11080         try {
11081             Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled);
11082             for (Phone phone : PhoneFactory.getPhones()) {
11083                 Phone defaultPhone = phone.getImsPhone();
11084                 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
11085                     ImsPhone imsPhone = (ImsPhone) defaultPhone;
11086                     ImsPhoneCallTracker imsPhoneCallTracker =
11087                             (ImsPhoneCallTracker) imsPhone.getCallTracker();
11088                     imsPhoneCallTracker.setConferenceEventPackageEnabled(isCepEnabled);
11089                     Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled + ", for imsPhone "
11090                             + imsPhone.getMsisdn());
11091                 }
11092             }
11093         } finally {
11094             Binder.restoreCallingIdentity(identity);
11095         }
11096     }
11097 
11098     /**
11099      * Notify that an RCS autoconfiguration XML file has been received for provisioning.
11100      *
11101      * @param config       The XML file to be read. ASCII/UTF8 encoded text if not compressed.
11102      * @param isCompressed The XML file is compressed in gzip format and must be decompressed
11103      *                     before being read.
11104      */
11105     @Override
notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean isCompressed)11106     public void notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean
11107             isCompressed) {
11108         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
11109                 mApp, subId, "notifyRcsAutoConfigurationReceived");
11110         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11111             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11112         }
11113 
11114         if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
11115                 || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, getCurrentPackageName(),
11116                 Binder.getCallingUserHandle())) {
11117             if (!isImsAvailableOnDevice()) {
11118                 // ProvisioningManager can not handle ServiceSpecificException.
11119                 // Throw the IllegalStateException and annotate ProvisioningManager.
11120                 throw new IllegalStateException("IMS not available on device.");
11121             }
11122         } else {
11123             enforceTelephonyFeatureWithException(getCurrentPackageName(),
11124                     FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION,
11125                     "notifyRcsAutoConfigurationReceived");
11126         }
11127 
11128         final long identity = Binder.clearCallingIdentity();
11129         try {
11130             RcsProvisioningMonitor.getInstance().updateConfig(subId, config, isCompressed);
11131         } finally {
11132             Binder.restoreCallingIdentity(identity);
11133         }
11134     }
11135 
11136     @Override
isIccLockEnabled(int subId)11137     public boolean isIccLockEnabled(int subId) {
11138         enforceReadPrivilegedPermission("isIccLockEnabled");
11139 
11140         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11141                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "isIccLockEnabled");
11142 
11143         // Now that all security checks passes, perform the operation as ourselves.
11144         final long identity = Binder.clearCallingIdentity();
11145         try {
11146             Phone phone = getPhone(subId);
11147             if (phone != null && phone.getIccCard() != null) {
11148                 return phone.getIccCard().getIccLockEnabled();
11149             } else {
11150                 return false;
11151             }
11152         } finally {
11153             Binder.restoreCallingIdentity(identity);
11154         }
11155     }
11156 
11157     /**
11158      * Set the ICC pin lock enabled or disabled.
11159      *
11160      * @return an integer representing the status of IccLock enabled or disabled in the following
11161      * three cases:
11162      *   - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if enabled or disabled IccLock
11163      *   successfully.
11164      *   - Positive number and zero for remaining password attempts.
11165      *   - Negative number for other failure cases (such like enabling/disabling PIN failed).
11166      *
11167      */
11168     @Override
setIccLockEnabled(int subId, boolean enabled, String password)11169     public int setIccLockEnabled(int subId, boolean enabled, String password) {
11170         enforceModifyPermission();
11171 
11172         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11173                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "setIccLockEnabled");
11174 
11175         Phone phone = getPhone(subId);
11176         if (phone == null) {
11177             return 0;
11178         }
11179         // Now that all security checks passes, perform the operation as ourselves.
11180         final long identity = Binder.clearCallingIdentity();
11181         try {
11182             int attemptsRemaining = (int) sendRequest(CMD_SET_ICC_LOCK_ENABLED,
11183                     new Pair<Boolean, String>(enabled, password), phone, null);
11184             return attemptsRemaining;
11185 
11186         } catch (Exception e) {
11187             Log.e(LOG_TAG, "setIccLockEnabled. Exception e =" + e);
11188         } finally {
11189             Binder.restoreCallingIdentity(identity);
11190         }
11191         return 0;
11192     }
11193 
11194     /**
11195      * Change the ICC password used in ICC pin lock.
11196      *
11197      * @return an integer representing the status of IccLock changed in the following three cases:
11198      *   - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if changed IccLock successfully.
11199      *   - Positive number and zero for remaining password attempts.
11200      *   - Negative number for other failure cases (such like enabling/disabling PIN failed).
11201      *
11202      */
11203     @Override
changeIccLockPassword(int subId, String oldPassword, String newPassword)11204     public int changeIccLockPassword(int subId, String oldPassword, String newPassword) {
11205         enforceModifyPermission();
11206 
11207         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11208                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "changeIccLockPassword");
11209 
11210         Phone phone = getPhone(subId);
11211         if (phone == null) {
11212             return 0;
11213         }
11214         // Now that all security checks passes, perform the operation as ourselves.
11215         final long identity = Binder.clearCallingIdentity();
11216         try {
11217             int attemptsRemaining = (int) sendRequest(CMD_CHANGE_ICC_LOCK_PASSWORD,
11218                     new Pair<String, String>(oldPassword, newPassword), phone, null);
11219             return attemptsRemaining;
11220 
11221         } catch (Exception e) {
11222             Log.e(LOG_TAG, "changeIccLockPassword. Exception e =" + e);
11223         } finally {
11224             Binder.restoreCallingIdentity(identity);
11225         }
11226         return 0;
11227     }
11228 
11229     /**
11230      * Request for receiving user activity notification
11231      */
11232     @Override
requestUserActivityNotification()11233     public void requestUserActivityNotification() {
11234         if (!mNotifyUserActivity.get()
11235                 && !mMainThreadHandler.hasMessages(MSG_NOTIFY_USER_ACTIVITY)) {
11236             mNotifyUserActivity.set(true);
11237         }
11238     }
11239 
11240     /**
11241      * Called when userActivity is signalled in the power manager.
11242      * This is safe to call from any thread, with any window manager locks held or not.
11243      */
11244     @Override
userActivity()11245     public void userActivity() {
11246         // ***************************************
11247         // *  Inherited from PhoneWindowManager  *
11248         // ***************************************
11249         // THIS IS CALLED FROM DEEP IN THE POWER MANAGER
11250         // WITH ITS LOCKS HELD.
11251         //
11252         // This code must be VERY careful about the locks
11253         // it acquires.
11254         // In fact, the current code acquires way too many,
11255         // and probably has lurking deadlocks.
11256 
11257         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11258             throw new SecurityException("Only the OS may call notifyUserActivity()");
11259         }
11260 
11261         if (mNotifyUserActivity.getAndSet(false)) {
11262             mMainThreadHandler.sendEmptyMessageDelayed(MSG_NOTIFY_USER_ACTIVITY,
11263                     USER_ACTIVITY_NOTIFICATION_DELAY);
11264         }
11265     }
11266 
11267     @Override
canConnectTo5GInDsdsMode()11268     public boolean canConnectTo5GInDsdsMode() {
11269         return mApp.getResources().getBoolean(R.bool.config_5g_connection_in_dsds_mode);
11270     }
11271 
11272     @Override
getEquivalentHomePlmns(int subId, String callingPackage, String callingFeatureId)11273     public @NonNull List<String> getEquivalentHomePlmns(int subId, String callingPackage,
11274             String callingFeatureId) {
11275         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
11276                 mApp, subId, callingPackage, callingFeatureId, "getEquivalentHomePlmns")) {
11277             throw new SecurityException("Requires READ_PHONE_STATE permission.");
11278         }
11279 
11280         enforceTelephonyFeatureWithException(callingPackage,
11281                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getEquivalentHomePlmns");
11282 
11283         Phone phone = getPhone(subId);
11284         if (phone == null) {
11285             throw new RuntimeException("phone is not available");
11286         }
11287         // Now that all security checks passes, perform the operation as ourselves.
11288         final long identity = Binder.clearCallingIdentity();
11289         try {
11290             return phone.getEquivalentHomePlmns();
11291         } finally {
11292             Binder.restoreCallingIdentity(identity);
11293         }
11294     }
11295 
11296     @Override
isRadioInterfaceCapabilitySupported( final @NonNull @TelephonyManager.RadioInterfaceCapability String capability)11297     public boolean isRadioInterfaceCapabilitySupported(
11298             final @NonNull @TelephonyManager.RadioInterfaceCapability String capability) {
11299         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11300                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS,
11301                 "isRadioInterfaceCapabilitySupported");
11302 
11303         Set<String> radioInterfaceCapabilities =
11304                 mRadioInterfaceCapabilities.getCapabilities();
11305         if (radioInterfaceCapabilities == null) {
11306             throw new RuntimeException("radio interface capabilities are not available");
11307         }
11308         return radioInterfaceCapabilities.contains(capability);
11309     }
11310 
11311     @Override
bootstrapAuthenticationRequest(int subId, int appType, Uri nafUrl, UaSecurityProtocolIdentifier securityProtocol, boolean forceBootStrapping, IBootstrapAuthenticationCallback callback)11312     public void bootstrapAuthenticationRequest(int subId, int appType, Uri nafUrl,
11313             UaSecurityProtocolIdentifier securityProtocol,
11314             boolean forceBootStrapping, IBootstrapAuthenticationCallback callback) {
11315         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
11316                 Binder.getCallingUid(), "bootstrapAuthenticationRequest",
11317                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
11318                 Manifest.permission.MODIFY_PHONE_STATE);
11319 
11320         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11321                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "bootstrapAuthenticationRequest");
11322 
11323         if (DBG) {
11324             log("bootstrapAuthenticationRequest, subId:" + subId + ", appType:"
11325                     + appType + ", NAF:" + nafUrl + ", sp:" + securityProtocol
11326                     + ", forceBootStrapping:" + forceBootStrapping + ", callback:" + callback);
11327         }
11328 
11329         if (!SubscriptionManager.isValidSubscriptionId(subId)
11330                 || appType < TelephonyManager.APPTYPE_UNKNOWN
11331                 || appType > TelephonyManager.APPTYPE_ISIM
11332                 || nafUrl == null || securityProtocol == null || callback == null) {
11333             Log.d(LOG_TAG, "bootstrapAuthenticationRequest failed due to invalid parameters");
11334             if (callback != null) {
11335                 try {
11336                     callback.onAuthenticationFailure(
11337                             0, TelephonyManager.GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED);
11338                 } catch (RemoteException exception) {
11339                     log("Fail to notify onAuthenticationFailure due to " + exception);
11340                 }
11341                 return;
11342             }
11343         }
11344 
11345         final long token = Binder.clearCallingIdentity();
11346         try {
11347             getGbaManager(subId).bootstrapAuthenticationRequest(
11348                     new GbaAuthRequest(subId, appType, nafUrl, securityProtocol.toByteArray(),
11349                             forceBootStrapping, callback));
11350         } finally {
11351             Binder.restoreCallingIdentity(token);
11352         }
11353     }
11354 
11355     /**
11356      * Attempts to set the radio power state for all phones for thermal reason.
11357      * This does not guarantee that the
11358      * requested radio power state will actually be set. See {@link
11359      * PhoneInternalInterface#setRadioPowerForReason} for more details.
11360      *
11361      * @param enable {@code true} if trying to turn radio on.
11362      * @return {@code true} if phone setRadioPowerForReason was called. Otherwise, returns {@code
11363      * false}.
11364      */
setRadioPowerForThermal(boolean enable)11365     private boolean setRadioPowerForThermal(boolean enable) {
11366         boolean isPhoneAvailable = false;
11367         for (int i = 0; i < TelephonyManager.getDefault().getActiveModemCount(); i++) {
11368             Phone phone = PhoneFactory.getPhone(i);
11369             if (phone != null) {
11370                 phone.setRadioPowerForReason(enable, TelephonyManager.RADIO_POWER_REASON_THERMAL);
11371                 isPhoneAvailable = true;
11372             }
11373         }
11374 
11375         // return true if successfully informed the phone object about the thermal radio power
11376         // request.
11377         return isPhoneAvailable;
11378     }
11379 
handleDataThrottlingRequest(int subId, DataThrottlingRequest dataThrottlingRequest, String callingPackage)11380     private int handleDataThrottlingRequest(int subId,
11381             DataThrottlingRequest dataThrottlingRequest, String callingPackage) {
11382         boolean isDataThrottlingSupported = isRadioInterfaceCapabilitySupported(
11383                 TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING);
11384         if (!isDataThrottlingSupported && dataThrottlingRequest.getDataThrottlingAction()
11385                 != DataThrottlingRequest.DATA_THROTTLING_ACTION_NO_DATA_THROTTLING) {
11386             throw new IllegalArgumentException("modem does not support data throttling");
11387         }
11388 
11389         // Ensure that radio is on. If not able to power on due to phone being unavailable, return
11390         // THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
11391         if (!setRadioPowerForThermal(true)) {
11392             return TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
11393         }
11394 
11395         setDataEnabledForReason(
11396                 subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL, true, callingPackage);
11397 
11398         if (isDataThrottlingSupported) {
11399             int thermalMitigationResult =
11400                     (int) sendRequest(CMD_SET_DATA_THROTTLING, dataThrottlingRequest, subId);
11401             if (thermalMitigationResult == SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS) {
11402                 throw new IllegalArgumentException("modem returned INVALID_ARGUMENTS");
11403             } else if (thermalMitigationResult
11404                     == MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE) {
11405                 log("Modem likely does not support data throttling on secondary carrier. Data " +
11406                         "throttling action = " + dataThrottlingRequest.getDataThrottlingAction());
11407                 return TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
11408             }
11409             return thermalMitigationResult;
11410         }
11411 
11412         return TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
11413     }
11414 
getThermalMitigationAllowlist(Context context)11415     private static List<String> getThermalMitigationAllowlist(Context context) {
11416         if (sThermalMitigationAllowlistedPackages.isEmpty()) {
11417             for (String pckg : context.getResources()
11418                     .getStringArray(R.array.thermal_mitigation_allowlisted_packages)) {
11419                 sThermalMitigationAllowlistedPackages.add(pckg);
11420             }
11421         }
11422 
11423         return sThermalMitigationAllowlistedPackages;
11424     }
11425 
isAnyPhoneInEmergencyState()11426     private boolean isAnyPhoneInEmergencyState() {
11427         TelecomManager tm = mApp.getSystemService(TelecomManager.class);
11428         if (tm.isInEmergencyCall()) {
11429             Log.e(LOG_TAG , "Phone state is not valid. One of the phones is in an emergency call");
11430             return true;
11431         }
11432         for (Phone phone : PhoneFactory.getPhones()) {
11433             if (phone.isInEmergencySmsMode() || phone.isInEcm()) {
11434                 Log.e(LOG_TAG, "Phone state is not valid. isInEmergencySmsMode = "
11435                         + phone.isInEmergencySmsMode() + " isInEmergencyCallbackMode = "
11436                         + phone.isInEcm());
11437                 return true;
11438             }
11439         }
11440 
11441         return false;
11442     }
11443 
11444     /**
11445      * Used by shell commands to add an authorized package name for thermal mitigation.
11446      * @param packageName name of package to be allowlisted
11447      * @param context
11448      */
addPackageToThermalMitigationAllowlist(String packageName, Context context)11449     static void addPackageToThermalMitigationAllowlist(String packageName, Context context) {
11450         sThermalMitigationAllowlistedPackages = getThermalMitigationAllowlist(context);
11451         sThermalMitigationAllowlistedPackages.add(packageName);
11452     }
11453 
11454     /**
11455      * Used by shell commands to remove an authorized package name for thermal mitigation.
11456      * @param packageName name of package to remove from allowlist
11457      * @param context
11458      */
removePackageFromThermalMitigationAllowlist(String packageName, Context context)11459     static void removePackageFromThermalMitigationAllowlist(String packageName, Context context) {
11460         sThermalMitigationAllowlistedPackages = getThermalMitigationAllowlist(context);
11461         sThermalMitigationAllowlistedPackages.remove(packageName);
11462     }
11463 
11464     /**
11465      * Thermal mitigation request to control functionalities at modem.
11466      *
11467      * @param subId the id of the subscription.
11468      * @param thermalMitigationRequest holds all necessary information to be passed down to modem.
11469      * @param callingPackage the package name of the calling package.
11470      *
11471      * @return thermalMitigationResult enum as defined in android.telephony.Annotation.
11472      */
11473     @Override
11474     @ThermalMitigationResult
sendThermalMitigationRequest( int subId, ThermalMitigationRequest thermalMitigationRequest, String callingPackage)11475     public int sendThermalMitigationRequest(
11476             int subId,
11477             ThermalMitigationRequest thermalMitigationRequest,
11478             String callingPackage) throws IllegalArgumentException {
11479         enforceModifyPermission();
11480 
11481         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
11482 
11483         enforceTelephonyFeatureWithException(callingPackage,
11484                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "sendThermalMitigationRequest");
11485 
11486         if (!getThermalMitigationAllowlist(getDefaultPhone().getContext())
11487                 .contains(callingPackage)) {
11488             throw new SecurityException("Calling package must be configured in the device config. "
11489                     + "calling package: " + callingPackage);
11490         }
11491 
11492         WorkSource workSource = getWorkSource(Binder.getCallingUid());
11493         final long identity = Binder.clearCallingIdentity();
11494 
11495         int thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR;
11496         try {
11497             int thermalMitigationAction = thermalMitigationRequest.getThermalMitigationAction();
11498             switch (thermalMitigationAction) {
11499                 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_DATA_THROTTLING:
11500                     thermalMitigationResult =
11501                             handleDataThrottlingRequest(subId,
11502                                     thermalMitigationRequest.getDataThrottlingRequest(),
11503                                     callingPackage);
11504                     break;
11505                 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY:
11506                     if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
11507                         throw new IllegalArgumentException("dataThrottlingRequest must be null for "
11508                                 + "ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY");
11509                     }
11510 
11511                     // Ensure that radio is on. If not able to power on due to phone being
11512                     // unavailable, return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
11513                     if (!setRadioPowerForThermal(true)) {
11514                         thermalMitigationResult =
11515                                 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
11516                         break;
11517                     }
11518 
11519                     setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL,
11520                             false, callingPackage);
11521                     thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
11522                     break;
11523                 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF:
11524                     if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
11525                         throw new IllegalArgumentException("dataThrottlingRequest  must be null for"
11526                                 + " ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF");
11527                     }
11528 
11529                     TelecomAccountRegistry registry = TelecomAccountRegistry.getInstance(null);
11530                     if (registry != null) {
11531                         Phone phone = getPhone(subId);
11532                         if (phone == null) {
11533                             thermalMitigationResult =
11534                                     TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
11535                             break;
11536                         }
11537 
11538                         TelephonyConnectionService service =
11539                                 registry.getTelephonyConnectionService();
11540                         if (service != null && service.isEmergencyCallPending()) {
11541                             Log.e(LOG_TAG, "An emergency call is pending");
11542                             thermalMitigationResult =
11543                                     TelephonyManager.THERMAL_MITIGATION_RESULT_INVALID_STATE;
11544                             break;
11545                         } else if (isAnyPhoneInEmergencyState()) {
11546                             thermalMitigationResult =
11547                                     TelephonyManager.THERMAL_MITIGATION_RESULT_INVALID_STATE;
11548                             break;
11549                         }
11550                     } else {
11551                         thermalMitigationResult =
11552                                 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
11553                         break;
11554                     }
11555 
11556                     // Turn radio off. If not able to power off due to phone being unavailable,
11557                     // return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
11558                     if (!setRadioPowerForThermal(false)) {
11559                         thermalMitigationResult =
11560                                 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
11561                         break;
11562                     }
11563                     thermalMitigationResult =
11564                             TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
11565                     break;
11566                 default:
11567                     throw new IllegalArgumentException("the requested thermalMitigationAction does "
11568                             + "not exist. Requested action: " + thermalMitigationAction);
11569             }
11570         } catch (IllegalArgumentException e) {
11571             throw e;
11572         } catch (Exception e) {
11573             Log.e(LOG_TAG, "thermalMitigationRequest. Exception e =" + e);
11574             thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
11575         } finally {
11576             Binder.restoreCallingIdentity(identity);
11577         }
11578 
11579         if (DBG) {
11580             log("thermalMitigationRequest returning with thermalMitigationResult: "
11581                     + thermalMitigationResult);
11582         }
11583 
11584         return thermalMitigationResult;
11585     }
11586 
11587     /**
11588      * Set the GbaService Package Name that Telephony will bind to.
11589      *
11590      * @param subId The sim that the GbaService is associated with.
11591      * @param packageName The name of the package to be replaced with.
11592      * @return true if setting the GbaService to bind to succeeded, false if it did not.
11593      */
11594     @Override
setBoundGbaServiceOverride(int subId, String packageName)11595     public boolean setBoundGbaServiceOverride(int subId, String packageName) {
11596         enforceModifyPermission();
11597 
11598         final long identity = Binder.clearCallingIdentity();
11599         try {
11600             return getGbaManager(subId).overrideServicePackage(packageName);
11601         } finally {
11602             Binder.restoreCallingIdentity(identity);
11603         }
11604     }
11605 
11606     /**
11607      * Return the package name of the currently bound GbaService.
11608      *
11609      * @param subId The sim that the GbaService is associated with.
11610      * @return the package name of the GbaService configuration, null if GBA is not supported.
11611      */
11612     @Override
getBoundGbaService(int subId)11613     public String getBoundGbaService(int subId) {
11614         enforceReadPrivilegedPermission("getBoundGbaServicePackage");
11615 
11616         final long identity = Binder.clearCallingIdentity();
11617         try {
11618             return getGbaManager(subId).getServicePackage();
11619         } finally {
11620             Binder.restoreCallingIdentity(identity);
11621         }
11622     }
11623 
11624     /**
11625      * Set the release time for telephony to unbind GbaService.
11626      *
11627      * @param subId The sim that the GbaService is associated with.
11628      * @param interval The release time to unbind GbaService by millisecond.
11629      * @return true if setting the GbaService to bind to succeeded, false if it did not.
11630      */
11631     @Override
setGbaReleaseTimeOverride(int subId, int interval)11632     public boolean setGbaReleaseTimeOverride(int subId, int interval) {
11633         enforceModifyPermission();
11634 
11635         final long identity = Binder.clearCallingIdentity();
11636         try {
11637             return getGbaManager(subId).overrideReleaseTime(interval);
11638         } finally {
11639             Binder.restoreCallingIdentity(identity);
11640         }
11641     }
11642 
11643     /**
11644      * Return the release time for telephony to unbind GbaService.
11645      *
11646      * @param subId The sim that the GbaService is associated with.
11647      * @return The release time to unbind GbaService by millisecond.
11648      */
11649     @Override
getGbaReleaseTime(int subId)11650     public int getGbaReleaseTime(int subId) {
11651         enforceReadPrivilegedPermission("getGbaReleaseTime");
11652 
11653         final long identity = Binder.clearCallingIdentity();
11654         try {
11655             return getGbaManager(subId).getReleaseTime();
11656         } finally {
11657             Binder.restoreCallingIdentity(identity);
11658         }
11659     }
11660 
getGbaManager(int subId)11661     private GbaManager getGbaManager(int subId) {
11662         GbaManager instance = GbaManager.getInstance(subId);
11663         if (instance == null) {
11664             String packageName = mApp.getResources().getString(R.string.config_gba_package);
11665             int releaseTime = mApp.getResources().getInteger(R.integer.config_gba_release_time);
11666             instance = GbaManager.make(mApp, subId, packageName, releaseTime);
11667         }
11668         return instance;
11669     }
11670 
11671     /**
11672      * indicate whether the device and the carrier can support
11673      * RCS VoLTE single registration.
11674      */
11675     @Override
isRcsVolteSingleRegistrationCapable(int subId)11676     public boolean isRcsVolteSingleRegistrationCapable(int subId) {
11677         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
11678                 Binder.getCallingUid(), "isRcsVolteSingleRegistrationCapable",
11679                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
11680                 permission.READ_PRIVILEGED_PHONE_STATE);
11681 
11682         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11683             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11684         }
11685 
11686         final long identity = Binder.clearCallingIdentity();
11687         try {
11688             RcsProvisioningMonitor rpm = RcsProvisioningMonitor.getInstance();
11689             if (rpm != null) {
11690                 Boolean isCapable = rpm.isRcsVolteSingleRegistrationEnabled(subId);
11691                 if (isCapable != null) {
11692                     return isCapable;
11693                 }
11694             }
11695             throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
11696                     "service is temporarily unavailable.");
11697         } finally {
11698             Binder.restoreCallingIdentity(identity);
11699         }
11700     }
11701 
11702     /**
11703      * Register RCS provisioning callback.
11704      */
11705     @Override
registerRcsProvisioningCallback(int subId, IRcsConfigCallback callback)11706     public void registerRcsProvisioningCallback(int subId,
11707             IRcsConfigCallback callback) {
11708         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
11709                 Binder.getCallingUid(), "registerRcsProvisioningCallback",
11710                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
11711                 permission.READ_PRIVILEGED_PHONE_STATE);
11712 
11713         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11714             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11715         }
11716         if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
11717                 || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, getCurrentPackageName(),
11718                 Binder.getCallingUserHandle())) {
11719             if (!isImsAvailableOnDevice()) {
11720                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
11721                         "IMS not available on device.");
11722             }
11723         } else {
11724             enforceTelephonyFeatureWithException(getCurrentPackageName(),
11725                     FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION, "registerRcsProvisioningCallback");
11726         }
11727 
11728         final long identity = Binder.clearCallingIdentity();
11729         try {
11730             if (!RcsProvisioningMonitor.getInstance()
11731                     .registerRcsProvisioningCallback(subId, callback)) {
11732                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
11733                         "Active subscription not found.");
11734             }
11735         } finally {
11736             Binder.restoreCallingIdentity(identity);
11737         }
11738     }
11739 
11740     /**
11741      * Unregister RCS provisioning callback.
11742      */
11743     @Override
unregisterRcsProvisioningCallback(int subId, IRcsConfigCallback callback)11744     public void unregisterRcsProvisioningCallback(int subId,
11745             IRcsConfigCallback callback) {
11746         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
11747                 Binder.getCallingUid(), "unregisterRcsProvisioningCallback",
11748                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
11749                 permission.READ_PRIVILEGED_PHONE_STATE);
11750 
11751         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11752             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11753         }
11754 
11755         if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
11756                 || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, getCurrentPackageName(),
11757                 Binder.getCallingUserHandle())) {
11758             if (!isImsAvailableOnDevice()) {
11759                 // operation failed silently
11760                 Rlog.w(LOG_TAG, "IMS not available on device.");
11761                 return;
11762             }
11763         } else {
11764             enforceTelephonyFeatureWithException(getCurrentPackageName(),
11765                     FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION,
11766                     "unregisterRcsProvisioningCallback");
11767         }
11768 
11769         final long identity = Binder.clearCallingIdentity();
11770         try {
11771             RcsProvisioningMonitor.getInstance()
11772                     .unregisterRcsProvisioningCallback(subId, callback);
11773         } finally {
11774             Binder.restoreCallingIdentity(identity);
11775         }
11776     }
11777 
11778     /**
11779      * trigger RCS reconfiguration.
11780      */
triggerRcsReconfiguration(int subId)11781     public void triggerRcsReconfiguration(int subId) {
11782         TelephonyPermissions.enforceAnyPermissionGranted(mApp, Binder.getCallingUid(),
11783                 "triggerRcsReconfiguration",
11784                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
11785 
11786         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11787             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11788         }
11789         if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
11790                 || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, getCurrentPackageName(),
11791                 Binder.getCallingUserHandle())) {
11792             if (!isImsAvailableOnDevice()) {
11793                 // ProvisioningManager can not handle ServiceSpecificException.
11794                 // Throw the IllegalStateException and annotate ProvisioningManager.
11795                 throw new IllegalStateException("IMS not available on device.");
11796             }
11797         } else {
11798             enforceTelephonyFeatureWithException(getCurrentPackageName(),
11799                     FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION, "triggerRcsReconfiguration");
11800         }
11801 
11802         final long identity = Binder.clearCallingIdentity();
11803         try {
11804             RcsProvisioningMonitor.getInstance().requestReconfig(subId);
11805         } finally {
11806             Binder.restoreCallingIdentity(identity);
11807         }
11808     }
11809 
11810     /**
11811      * Provide the client configuration parameters of the RCS application.
11812      */
setRcsClientConfiguration(int subId, RcsClientConfiguration rcc)11813     public void setRcsClientConfiguration(int subId, RcsClientConfiguration rcc) {
11814         TelephonyPermissions.enforceAnyPermissionGranted(mApp, Binder.getCallingUid(),
11815                 "setRcsClientConfiguration",
11816                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
11817 
11818         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11819             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11820         }
11821         if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
11822                 || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, getCurrentPackageName(),
11823                 Binder.getCallingUserHandle())) {
11824             if (!isImsAvailableOnDevice()) {
11825                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
11826                         "IMS not available on device.");
11827             }
11828         } else {
11829             enforceTelephonyFeatureWithException(getCurrentPackageName(),
11830                     FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION, "setRcsClientConfiguration");
11831         }
11832 
11833         final long identity = Binder.clearCallingIdentity();
11834 
11835         try {
11836             IImsConfig configBinder = getImsConfig(getSlotIndex(subId), ImsFeature.FEATURE_RCS);
11837             if (configBinder == null) {
11838                 Rlog.e(LOG_TAG, "null result for setRcsClientConfiguration");
11839                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
11840                         "could not find the requested subscription");
11841             } else {
11842                 configBinder.setRcsClientConfiguration(rcc);
11843             }
11844 
11845             RcsStats.getInstance().onRcsClientProvisioningStats(subId,
11846                     RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT);
11847         } catch (RemoteException e) {
11848             Rlog.e(LOG_TAG, "fail to setRcsClientConfiguration " + e.getMessage());
11849             throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
11850                     "service is temporarily unavailable.");
11851         } finally {
11852             Binder.restoreCallingIdentity(identity);
11853         }
11854     }
11855 
11856     /**
11857      * Enables or disables the test mode for RCS VoLTE single registration.
11858      */
11859     @Override
setRcsSingleRegistrationTestModeEnabled(boolean enabled)11860     public void setRcsSingleRegistrationTestModeEnabled(boolean enabled) {
11861         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11862                 "setRcsSingleRegistrationTestModeEnabled");
11863 
11864         RcsProvisioningMonitor.getInstance().setTestModeEnabled(enabled);
11865     }
11866 
11867     /**
11868      * Gets the test mode for RCS VoLTE single registration.
11869      */
11870     @Override
getRcsSingleRegistrationTestModeEnabled()11871     public boolean getRcsSingleRegistrationTestModeEnabled() {
11872         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11873                 "getRcsSingleRegistrationTestModeEnabled");
11874 
11875         return RcsProvisioningMonitor.getInstance().getTestModeEnabled();
11876     }
11877 
11878     /**
11879      * Overrides the config of RCS VoLTE single registration enabled for the device.
11880      */
11881     @Override
setDeviceSingleRegistrationEnabledOverride(String enabledStr)11882     public void setDeviceSingleRegistrationEnabledOverride(String enabledStr) {
11883         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11884                 "setDeviceSingleRegistrationEnabledOverride");
11885         enforceModifyPermission();
11886 
11887         Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
11888                 : Boolean.parseBoolean(enabledStr);
11889         RcsProvisioningMonitor.getInstance().overrideDeviceSingleRegistrationEnabled(enabled);
11890         mApp.imsRcsController.setDeviceSingleRegistrationSupportOverride(enabled);
11891     }
11892 
11893     /**
11894      * Sends a device to device communication message.  Only usable via shell.
11895      * @param message message to send.
11896      * @param value message value.
11897      */
11898     @Override
sendDeviceToDeviceMessage(int message, int value)11899     public void sendDeviceToDeviceMessage(int message, int value) {
11900         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11901                 "sendDeviceToDeviceMessage");
11902         enforceModifyPermission();
11903 
11904         final long identity = Binder.clearCallingIdentity();
11905         try {
11906             TelephonyConnectionService service =
11907                     TelecomAccountRegistry.getInstance(null).getTelephonyConnectionService();
11908             if (service == null) {
11909                 Rlog.e(LOG_TAG, "sendDeviceToDeviceMessage: not in a call.");
11910                 return;
11911             }
11912             service.sendTestDeviceToDeviceMessage(message, value);
11913         } finally {
11914             Binder.restoreCallingIdentity(identity);
11915         }
11916     }
11917 
11918     /**
11919      * Sets the specified device to device transport active.
11920      * @param transport The transport to set active.
11921      */
11922     @Override
setActiveDeviceToDeviceTransport(@onNull String transport)11923     public void setActiveDeviceToDeviceTransport(@NonNull String transport) {
11924         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11925                 "setActiveDeviceToDeviceTransport");
11926         enforceModifyPermission();
11927 
11928         final long identity = Binder.clearCallingIdentity();
11929         try {
11930             TelephonyConnectionService service =
11931                     TelecomAccountRegistry.getInstance(null).getTelephonyConnectionService();
11932             if (service == null) {
11933                 Rlog.e(LOG_TAG, "setActiveDeviceToDeviceTransport: not in a call.");
11934                 return;
11935             }
11936             service.setActiveDeviceToDeviceTransport(transport);
11937         } finally {
11938             Binder.restoreCallingIdentity(identity);
11939         }
11940     }
11941 
11942     @Override
setDeviceToDeviceForceEnabled(boolean isForceEnabled)11943     public void setDeviceToDeviceForceEnabled(boolean isForceEnabled) {
11944         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11945                 "setDeviceToDeviceForceEnabled");
11946 
11947         final long identity = Binder.clearCallingIdentity();
11948         try {
11949             Arrays.stream(PhoneFactory.getPhones()).forEach(
11950                     p -> {
11951                         Phone thePhone = p.getImsPhone();
11952                         if (thePhone != null && thePhone instanceof ImsPhone) {
11953                             ImsPhone imsPhone = (ImsPhone) thePhone;
11954                             CallTracker tracker = imsPhone.getCallTracker();
11955                             if (tracker != null && tracker instanceof ImsPhoneCallTracker) {
11956                                 ImsPhoneCallTracker imsPhoneCallTracker =
11957                                         (ImsPhoneCallTracker) tracker;
11958                                 imsPhoneCallTracker.setDeviceToDeviceForceEnabled(isForceEnabled);
11959                             }
11960                         }
11961                     }
11962             );
11963         } finally {
11964             Binder.restoreCallingIdentity(identity);
11965         }
11966     }
11967 
11968     /**
11969      * Gets the config of RCS VoLTE single registration enabled for the device.
11970      */
11971     @Override
getDeviceSingleRegistrationEnabled()11972     public boolean getDeviceSingleRegistrationEnabled() {
11973         enforceReadPrivilegedPermission("getDeviceSingleRegistrationEnabled");
11974         return RcsProvisioningMonitor.getInstance().getDeviceSingleRegistrationEnabled();
11975     }
11976 
11977     /**
11978      * Overrides the config of RCS VoLTE single registration enabled for the carrier/subscription.
11979      */
11980     @Override
setCarrierSingleRegistrationEnabledOverride(int subId, String enabledStr)11981     public boolean setCarrierSingleRegistrationEnabledOverride(int subId, String enabledStr) {
11982         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
11983                 "setCarrierSingleRegistrationEnabledOverride");
11984         enforceModifyPermission();
11985 
11986         Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
11987                 : Boolean.parseBoolean(enabledStr);
11988         return RcsProvisioningMonitor.getInstance().overrideCarrierSingleRegistrationEnabled(
11989                 subId, enabled);
11990     }
11991 
11992     /**
11993      * Gets the config of RCS VoLTE single registration enabled for the carrier/subscription.
11994      */
11995     @Override
getCarrierSingleRegistrationEnabled(int subId)11996     public boolean getCarrierSingleRegistrationEnabled(int subId) {
11997         enforceReadPrivilegedPermission("getCarrierSingleRegistrationEnabled");
11998         return RcsProvisioningMonitor.getInstance().getCarrierSingleRegistrationEnabled(subId);
11999     }
12000 
12001     /**
12002      * Overrides the ims feature validation result
12003      */
12004     @Override
setImsFeatureValidationOverride(int subId, String enabledStr)12005     public boolean setImsFeatureValidationOverride(int subId, String enabledStr) {
12006         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12007                 "setImsFeatureValidationOverride");
12008 
12009         Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
12010                 : Boolean.parseBoolean(enabledStr);
12011         return RcsProvisioningMonitor.getInstance().overrideImsFeatureValidation(
12012                 subId, enabled);
12013     }
12014 
12015     /**
12016      * Gets the ims feature validation override value
12017      */
12018     @Override
getImsFeatureValidationOverride(int subId)12019     public boolean getImsFeatureValidationOverride(int subId) {
12020         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12021                 "getImsFeatureValidationOverride");
12022         return RcsProvisioningMonitor.getInstance().getImsFeatureValidationOverride(subId);
12023     }
12024 
12025     /**
12026      * Get the mobile provisioning url that is used to launch a browser to allow users to manage
12027      * their mobile plan.
12028      */
12029     @Override
getMobileProvisioningUrl()12030     public String getMobileProvisioningUrl() {
12031         enforceReadPrivilegedPermission("getMobileProvisioningUrl");
12032         final long identity = Binder.clearCallingIdentity();
12033         try {
12034             return getDefaultPhone().getMobileProvisioningUrl();
12035         } finally {
12036             Binder.restoreCallingIdentity(identity);
12037         }
12038     }
12039 
12040     /**
12041      * Get the EAB contact from the EAB database.
12042      */
12043     @Override
getContactFromEab(String contact)12044     public String getContactFromEab(String contact) {
12045         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getContactFromEab");
12046         enforceModifyPermission();
12047         final long identity = Binder.clearCallingIdentity();
12048         try {
12049             return EabUtil.getContactFromEab(getDefaultPhone().getContext(), contact);
12050         } finally {
12051             Binder.restoreCallingIdentity(identity);
12052         }
12053     }
12054 
12055     /**
12056      * Get the EAB capability from the EAB database.
12057      */
12058     @Override
getCapabilityFromEab(String contact)12059     public String getCapabilityFromEab(String contact) {
12060         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getCapabilityFromEab");
12061         enforceModifyPermission();
12062         final long identity = Binder.clearCallingIdentity();
12063         try {
12064             return EabUtil.getCapabilityFromEab(getDefaultPhone().getContext(), contact);
12065         } finally {
12066             Binder.restoreCallingIdentity(identity);
12067         }
12068     }
12069 
12070     /**
12071      * Remove the EAB contacts from the EAB database.
12072      */
12073     @Override
removeContactFromEab(int subId, String contacts)12074     public int removeContactFromEab(int subId, String contacts) {
12075         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "removeCapabilitiesFromEab");
12076         enforceModifyPermission();
12077         final long identity = Binder.clearCallingIdentity();
12078         try {
12079             return EabUtil.removeContactFromEab(subId, contacts, getDefaultPhone().getContext());
12080         } finally {
12081             Binder.restoreCallingIdentity(identity);
12082         }
12083     }
12084 
12085     @Override
getDeviceUceEnabled()12086     public boolean getDeviceUceEnabled() {
12087         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getDeviceUceEnabled");
12088         final long identity = Binder.clearCallingIdentity();
12089         try {
12090             return mApp.getDeviceUceEnabled();
12091         } finally {
12092             Binder.restoreCallingIdentity(identity);
12093         }
12094     }
12095 
12096     @Override
setDeviceUceEnabled(boolean isEnabled)12097     public void setDeviceUceEnabled(boolean isEnabled) {
12098         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setDeviceUceEnabled");
12099         final long identity = Binder.clearCallingIdentity();
12100         try {
12101             mApp.setDeviceUceEnabled(isEnabled);
12102         } finally {
12103             Binder.restoreCallingIdentity(identity);
12104         }
12105     }
12106 
12107     /**
12108      * Add new feature tags to the Set used to calculate the capabilities in PUBLISH.
12109      * @return current RcsContactUceCapability instance that will be used for PUBLISH.
12110      */
12111     // Used for SHELL command only right now.
12112     @Override
addUceRegistrationOverrideShell(int subId, List<String> featureTags)12113     public RcsContactUceCapability addUceRegistrationOverrideShell(int subId,
12114             List<String> featureTags) {
12115         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12116                 "addUceRegistrationOverrideShell");
12117         final long identity = Binder.clearCallingIdentity();
12118         try {
12119             return mApp.imsRcsController.addUceRegistrationOverrideShell(subId,
12120                     new ArraySet<>(featureTags));
12121         } catch (ImsException e) {
12122             throw new ServiceSpecificException(e.getCode(), e.getMessage());
12123         } finally {
12124             Binder.restoreCallingIdentity(identity);
12125         }
12126     }
12127 
12128     /**
12129      * Remove existing feature tags to the Set used to calculate the capabilities in PUBLISH.
12130      * @return current RcsContactUceCapability instance that will be used for PUBLISH.
12131      */
12132     // Used for SHELL command only right now.
12133     @Override
removeUceRegistrationOverrideShell(int subId, List<String> featureTags)12134     public RcsContactUceCapability removeUceRegistrationOverrideShell(int subId,
12135             List<String> featureTags) {
12136         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12137                 "removeUceRegistrationOverrideShell");
12138         final long identity = Binder.clearCallingIdentity();
12139         try {
12140             return mApp.imsRcsController.removeUceRegistrationOverrideShell(subId,
12141                     new ArraySet<>(featureTags));
12142         } catch (ImsException e) {
12143             throw new ServiceSpecificException(e.getCode(), e.getMessage());
12144         } finally {
12145             Binder.restoreCallingIdentity(identity);
12146         }
12147     }
12148 
12149     /**
12150      * Clear all overrides in the Set used to calculate the capabilities in PUBLISH.
12151      * @return current RcsContactUceCapability instance that will be used for PUBLISH.
12152      */
12153     // Used for SHELL command only right now.
12154     @Override
clearUceRegistrationOverrideShell(int subId)12155     public RcsContactUceCapability clearUceRegistrationOverrideShell(int subId) {
12156         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12157                 "clearUceRegistrationOverrideShell");
12158         final long identity = Binder.clearCallingIdentity();
12159         try {
12160             return mApp.imsRcsController.clearUceRegistrationOverrideShell(subId);
12161         } catch (ImsException e) {
12162             throw new ServiceSpecificException(e.getCode(), e.getMessage());
12163         } finally {
12164             Binder.restoreCallingIdentity(identity);
12165         }
12166     }
12167 
12168     /**
12169      * @return current RcsContactUceCapability instance that will be used for PUBLISH.
12170      */
12171     // Used for SHELL command only right now.
12172     @Override
getLatestRcsContactUceCapabilityShell(int subId)12173     public RcsContactUceCapability getLatestRcsContactUceCapabilityShell(int subId) {
12174         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12175                 "getLatestRcsContactUceCapabilityShell");
12176         final long identity = Binder.clearCallingIdentity();
12177         try {
12178             return mApp.imsRcsController.getLatestRcsContactUceCapabilityShell(subId);
12179         } catch (ImsException e) {
12180             throw new ServiceSpecificException(e.getCode(), e.getMessage());
12181         } finally {
12182             Binder.restoreCallingIdentity(identity);
12183         }
12184     }
12185 
12186     /**
12187      * Returns the last PIDF XML sent to the network during the last PUBLISH or "none" if the
12188      * device does not have an active PUBLISH.
12189      */
12190     // Used for SHELL command only right now.
12191     @Override
getLastUcePidfXmlShell(int subId)12192     public String getLastUcePidfXmlShell(int subId) {
12193         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "uceGetLastPidfXml");
12194         final long identity = Binder.clearCallingIdentity();
12195         try {
12196             return mApp.imsRcsController.getLastUcePidfXmlShell(subId);
12197         } catch (ImsException e) {
12198             throw new ServiceSpecificException(e.getCode(), e.getMessage());
12199         } finally {
12200             Binder.restoreCallingIdentity(identity);
12201         }
12202     }
12203 
12204     /**
12205      * Remove UCE requests cannot be sent to the network status.
12206      */
12207     // Used for SHELL command only right now.
12208     @Override
removeUceRequestDisallowedStatus(int subId)12209     public boolean removeUceRequestDisallowedStatus(int subId) {
12210         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "uceRemoveDisallowedStatus");
12211         final long identity = Binder.clearCallingIdentity();
12212         try {
12213             return mApp.imsRcsController.removeUceRequestDisallowedStatus(subId);
12214         } catch (ImsException e) {
12215             throw new ServiceSpecificException(e.getCode(), e.getMessage());
12216         } finally {
12217             Binder.restoreCallingIdentity(identity);
12218         }
12219     }
12220 
12221     /**
12222      * Remove UCE requests cannot be sent to the network status.
12223      */
12224     // Used for SHELL command only.
12225     @Override
setCapabilitiesRequestTimeout(int subId, long timeoutAfterMs)12226     public boolean setCapabilitiesRequestTimeout(int subId, long timeoutAfterMs) {
12227         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCapRequestTimeout");
12228         final long identity = Binder.clearCallingIdentity();
12229         try {
12230             return mApp.imsRcsController.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
12231         } catch (ImsException e) {
12232             throw new ServiceSpecificException(e.getCode(), e.getMessage());
12233         } finally {
12234             Binder.restoreCallingIdentity(identity);
12235         }
12236     }
12237 
12238     @Override
setSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request, String callingPackage)12239     public void setSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request,
12240             String callingPackage) {
12241         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
12242                 mApp, subId, "setSignalStrengthUpdateRequest");
12243 
12244         enforceTelephonyFeatureWithException(callingPackage,
12245                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "setSignalStrengthUpdateRequest");
12246 
12247         final int callingUid = Binder.getCallingUid();
12248         // Verify that tha callingPackage belongs to the calling UID
12249         mApp.getSystemService(AppOpsManager.class)
12250                 .checkPackage(callingUid, callingPackage);
12251 
12252         validateSignalStrengthUpdateRequest(mApp, request, callingUid);
12253 
12254         final long identity = Binder.clearCallingIdentity();
12255         try {
12256             Object result = sendRequest(CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST,
12257                     new Pair<Integer, SignalStrengthUpdateRequest>(callingUid, request), subId);
12258 
12259             if (result instanceof IllegalStateException) {
12260                 throw (IllegalStateException) result;
12261             }
12262         } finally {
12263             Binder.restoreCallingIdentity(identity);
12264         }
12265     }
12266 
12267     @Override
clearSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request, String callingPackage)12268     public void clearSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request,
12269             String callingPackage) {
12270         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
12271                 mApp, subId, "clearSignalStrengthUpdateRequest");
12272 
12273         enforceTelephonyFeatureWithException(callingPackage,
12274                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "clearSignalStrengthUpdateRequest");
12275 
12276         final int callingUid = Binder.getCallingUid();
12277         // Verify that tha callingPackage belongs to the calling UID
12278         mApp.getSystemService(AppOpsManager.class)
12279                 .checkPackage(callingUid, callingPackage);
12280 
12281         final long identity = Binder.clearCallingIdentity();
12282         try {
12283             Object result = sendRequest(CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST,
12284                     new Pair<Integer, SignalStrengthUpdateRequest>(callingUid, request), subId);
12285 
12286             if (result instanceof IllegalStateException) {
12287                 throw (IllegalStateException) result;
12288             }
12289         } finally {
12290             Binder.restoreCallingIdentity(identity);
12291         }
12292     }
12293 
validateSignalStrengthUpdateRequest(Context context, SignalStrengthUpdateRequest request, int callingUid)12294     private static void validateSignalStrengthUpdateRequest(Context context,
12295             SignalStrengthUpdateRequest request, int callingUid) {
12296         if (callingUid == Process.PHONE_UID || callingUid == Process.SYSTEM_UID) {
12297             // phone/system process do not have further restriction on request
12298             return;
12299         }
12300 
12301         // Applications has restrictions on how to use the request:
12302         // Non-system callers need permission to set mIsSystemThresholdReportingRequestedWhileIdle
12303         if (request.isSystemThresholdReportingRequestedWhileIdle()) {
12304             context.enforceCallingOrSelfPermission(
12305                     android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH,
12306                     "validateSignalStrengthUpdateRequest");
12307         }
12308 
12309         for (SignalThresholdInfo info : request.getSignalThresholdInfos()) {
12310             // Only system caller can set mHysteresisMs/mIsEnabled.
12311             if (info.getHysteresisMs() != SignalThresholdInfo.HYSTERESIS_MS_DISABLED
12312                     || info.isEnabled()) {
12313                 throw new IllegalArgumentException(
12314                         "Only system can set hide fields in SignalThresholdInfo");
12315             }
12316 
12317             // Thresholds length for each RAN need in range. This has been validated in
12318             // SignalThresholdInfo#Builder#setThreshold. Here we prevent apps calling hide method
12319             // setThresholdUnlimited (e.g. through reflection) with too short or too long thresholds
12320             final int[] thresholds = info.getThresholds();
12321             Objects.requireNonNull(thresholds);
12322             if (thresholds.length < SignalThresholdInfo.getMinimumNumberOfThresholdsAllowed()
12323                     || thresholds.length
12324                     > SignalThresholdInfo.getMaximumNumberOfThresholdsAllowed()) {
12325                 throw new IllegalArgumentException(
12326                         "thresholds length is out of range: " + thresholds.length);
12327             }
12328         }
12329     }
12330 
12331     /**
12332      * Gets the current phone capability.
12333      *
12334      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
12335      * @return the PhoneCapability which describes the data connection capability of modem.
12336      * It's used to evaluate possible phone config change, for example from single
12337      * SIM device to multi-SIM device.
12338      */
12339     @Override
getPhoneCapability()12340     public PhoneCapability getPhoneCapability() {
12341         enforceReadPrivilegedPermission("getPhoneCapability");
12342 
12343         enforceTelephonyFeatureWithException(getCurrentPackageName(),
12344                 PackageManager.FEATURE_TELEPHONY, "getPhoneCapability");
12345 
12346         final long identity = Binder.clearCallingIdentity();
12347         try {
12348             return mPhoneConfigurationManager.getCurrentPhoneCapability();
12349         } finally {
12350             Binder.restoreCallingIdentity(identity);
12351         }
12352     }
12353 
12354     /**
12355      * Prepare TelephonyManager for an unattended reboot. The reboot is
12356      * required to be done shortly after the API is invoked.
12357      */
12358     @Override
12359     @TelephonyManager.PrepareUnattendedRebootResult
prepareForUnattendedReboot()12360     public int prepareForUnattendedReboot() {
12361         WorkSource workSource = getWorkSource(Binder.getCallingUid());
12362         enforceRebootPermission();
12363 
12364         enforceTelephonyFeatureWithException(getCurrentPackageName(),
12365                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "prepareForUnattendedReboot");
12366 
12367         final long identity = Binder.clearCallingIdentity();
12368         try {
12369             return (int) sendRequest(CMD_PREPARE_UNATTENDED_REBOOT, null, workSource);
12370         } finally {
12371             Binder.restoreCallingIdentity(identity);
12372         }
12373     }
12374 
12375     /**
12376      * Request to get the current slicing configuration including URSP rules and
12377      * NSSAIs (configured, allowed and rejected).
12378      *
12379      * Requires carrier privileges or READ_PRIVILEGED_PHONE_STATE permission.
12380      */
12381     @Override
getSlicingConfig(ResultReceiver callback)12382     public void getSlicingConfig(ResultReceiver callback) {
12383         TelephonyPermissions
12384                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
12385                         mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, "getSlicingConfig");
12386 
12387         enforceTelephonyFeatureWithException(getCurrentPackageName(),
12388                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS,
12389                 "getSlicingConfig");
12390 
12391         final long identity = Binder.clearCallingIdentity();
12392         try {
12393             Phone phone = getDefaultPhone();
12394             sendRequestAsync(CMD_GET_SLICING_CONFIG, callback, phone, null);
12395         } finally {
12396             Binder.restoreCallingIdentity(identity);
12397         }
12398     }
12399 
12400     /**
12401      * Check whether the given premium capability is available for purchase from the carrier.
12402      *
12403      * @param capability The premium capability to check.
12404      * @param subId The subId to check the premium capability for.
12405      *
12406      * @return Whether the given premium capability is available to purchase.
12407      */
12408     @Override
isPremiumCapabilityAvailableForPurchase(int capability, int subId)12409     public boolean isPremiumCapabilityAvailableForPurchase(int capability, int subId) {
12410         if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
12411                 mApp, "isPremiumCapabilityAvailableForPurchase")) {
12412             log("Premium capability "
12413                     + TelephonyManager.convertPremiumCapabilityToString(capability)
12414                     + " is not available for purchase due to missing permissions.");
12415             throw new SecurityException("isPremiumCapabilityAvailableForPurchase requires "
12416                     + "permission READ_BASIC_PHONE_STATE.");
12417         }
12418 
12419         enforceTelephonyFeatureWithException(getCurrentPackageName(),
12420                 PackageManager.FEATURE_TELEPHONY_DATA, "isPremiumCapabilityAvailableForPurchase");
12421 
12422         Phone phone = getPhone(subId);
12423         if (phone == null) {
12424             loge("isPremiumCapabilityAvailableForPurchase: phone is null, subId=" + subId);
12425             return false;
12426         }
12427         final long identity = Binder.clearCallingIdentity();
12428         try {
12429             return SlicePurchaseController.getInstance(phone, mFeatureFlags)
12430                     .isPremiumCapabilityAvailableForPurchase(capability);
12431         } finally {
12432             Binder.restoreCallingIdentity(identity);
12433         }
12434     }
12435 
12436     /**
12437      * Purchase the given premium capability from the carrier.
12438      *
12439      * @param capability The premium capability to purchase.
12440      * @param callback The result of the purchase request.
12441      * @param subId The subId to purchase the premium capability for.
12442      */
12443     @Override
purchasePremiumCapability(int capability, IIntegerConsumer callback, int subId)12444     public void purchasePremiumCapability(int capability, IIntegerConsumer callback, int subId) {
12445         log("purchasePremiumCapability: capability="
12446                 + TelephonyManager.convertPremiumCapabilityToString(capability) + ", caller="
12447                 + getCurrentPackageName());
12448 
12449         if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
12450                 mApp, "purchasePremiumCapability")) {
12451             log("purchasePremiumCapability "
12452                     + TelephonyManager.convertPremiumCapabilityToString(capability)
12453                     + " failed due to missing permissions.");
12454             throw new SecurityException("purchasePremiumCapability requires permission "
12455                     + "READ_BASIC_PHONE_STATE.");
12456         } else if (!TelephonyPermissions.checkInternetPermissionNoThrow(
12457                 mApp, "purchasePremiumCapability")) {
12458             log("purchasePremiumCapability "
12459                     + TelephonyManager.convertPremiumCapabilityToString(capability)
12460                     + " failed due to missing permissions.");
12461             throw new SecurityException("purchasePremiumCapability requires permission INTERNET.");
12462         }
12463 
12464         enforceTelephonyFeatureWithException(getCurrentPackageName(),
12465                 PackageManager.FEATURE_TELEPHONY_DATA, "purchasePremiumCapability");
12466 
12467         Phone phone = getPhone(subId);
12468         if (phone == null) {
12469             try {
12470                 int result = TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_REQUEST_FAILED;
12471                 callback.accept(result);
12472                 loge("purchasePremiumCapability: phone is null, subId=" + subId);
12473             } catch (RemoteException e) {
12474                 String logStr = "Purchase premium capability "
12475                         + TelephonyManager.convertPremiumCapabilityToString(capability)
12476                         + " failed due to RemoteException handling null phone: " + e;
12477                 if (DBG) log(logStr);
12478                 AnomalyReporter.reportAnomaly(
12479                         UUID.fromString(PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID), logStr);
12480             }
12481             return;
12482         }
12483 
12484         String callingProcess;
12485         try {
12486             callingProcess = mApp.getPackageManager().getApplicationInfo(
12487                     getCurrentPackageName(), 0).processName;
12488         } catch (PackageManager.NameNotFoundException e) {
12489             callingProcess = getCurrentPackageName();
12490         }
12491 
12492         boolean isVisible = false;
12493         ActivityManager am = mApp.getSystemService(ActivityManager.class);
12494         if (am != null) {
12495             List<ActivityManager.RunningAppProcessInfo> processes = am.getRunningAppProcesses();
12496             if (processes != null) {
12497                 for (ActivityManager.RunningAppProcessInfo process : processes) {
12498                     log("purchasePremiumCapability: process " + process.processName
12499                             + " has importance " + process.importance);
12500                     if (process.processName.equals(callingProcess) && process.importance
12501                             <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
12502                         isVisible = true;
12503                         break;
12504                     }
12505                 }
12506             }
12507         }
12508 
12509         if (!isVisible) {
12510             try {
12511                 int result = TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_FOREGROUND;
12512                 callback.accept(result);
12513                 loge("purchasePremiumCapability: " + callingProcess + " is not in the foreground.");
12514             } catch (RemoteException e) {
12515                 String logStr = "Purchase premium capability "
12516                         + TelephonyManager.convertPremiumCapabilityToString(capability)
12517                         + " failed due to RemoteException handling background application: " + e;
12518                 if (DBG) log(logStr);
12519                 AnomalyReporter.reportAnomaly(
12520                         UUID.fromString(PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID), logStr);
12521             }
12522             return;
12523         }
12524 
12525         sendRequestAsync(CMD_PURCHASE_PREMIUM_CAPABILITY,
12526                 new PurchasePremiumCapabilityArgument(capability, callback), phone, null);
12527     }
12528 
12529     /**
12530      * Register an IMS connection state callback
12531      */
12532     @Override
registerImsStateCallback(int subId, int feature, IImsStateCallback cb, String callingPackage)12533     public void registerImsStateCallback(int subId, int feature, IImsStateCallback cb,
12534             String callingPackage) {
12535         if (feature == ImsFeature.FEATURE_MMTEL) {
12536             // ImsMmTelManager
12537             // The following also checks READ_PRIVILEGED_PHONE_STATE.
12538             TelephonyPermissions
12539                     .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
12540                             mApp, subId, "registerImsStateCallback");
12541         } else if (feature == ImsFeature.FEATURE_RCS) {
12542             // ImsRcsManager or SipDelegateManager
12543             TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
12544                     Binder.getCallingUid(), "registerImsStateCallback",
12545                     Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
12546                     Manifest.permission.READ_PRECISE_PHONE_STATE,
12547                     Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE,
12548                     Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
12549         }
12550 
12551         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
12552             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
12553                     "IMS not available on device.");
12554         }
12555 
12556         if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
12557             throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
12558         }
12559 
12560         ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
12561         if (controller == null) {
12562             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
12563                     "IMS not available on device.");
12564         }
12565 
12566         if (callingPackage == null) {
12567             callingPackage = getCurrentPackageName();
12568         }
12569 
12570         final long token = Binder.clearCallingIdentity();
12571         try {
12572             int slotId = getSlotIndexOrException(subId);
12573             controller.registerImsStateCallback(subId, feature, cb, callingPackage);
12574         } catch (ImsException e) {
12575             throw new ServiceSpecificException(e.getCode());
12576         } finally {
12577             Binder.restoreCallingIdentity(token);
12578         }
12579     }
12580 
12581     /**
12582      * Unregister an IMS connection state callback
12583      */
12584     @Override
unregisterImsStateCallback(IImsStateCallback cb)12585     public void unregisterImsStateCallback(IImsStateCallback cb) {
12586         final long token = Binder.clearCallingIdentity();
12587         ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
12588         if (controller == null) {
12589             return;
12590         }
12591         try {
12592             controller.unregisterImsStateCallback(cb);
12593         } finally {
12594             Binder.restoreCallingIdentity(token);
12595         }
12596     }
12597 
12598     /**
12599      * @return {@CellIdentity} last known cell identity {@CellIdentity}.
12600      *
12601      * Require {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
12602      * {@link android.Manifest.permission#ACCESS_LAST_KNOWN_CELL_ID}, otherwise throws
12603      * SecurityException.
12604      *
12605      * If there is current registered network this value will be same as the registered cell
12606      * identity. If the device goes out of service the previous cell identity is cached and
12607      * will be returned. If the cache age of the Cell identity is more than 24 hours
12608      * it will be cleared and null will be returned.
12609      *
12610      */
12611     @Override
getLastKnownCellIdentity(int subId, String callingPackage, String callingFeatureId)12612     public @Nullable CellIdentity getLastKnownCellIdentity(int subId, String callingPackage,
12613             String callingFeatureId) {
12614         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
12615         LocationAccessPolicy.LocationPermissionResult fineLocationResult =
12616                 LocationAccessPolicy.checkLocationPermission(mApp,
12617                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
12618                                 .setCallingPackage(callingPackage)
12619                                 .setCallingFeatureId(callingFeatureId)
12620                                 .setCallingPid(Binder.getCallingPid())
12621                                 .setCallingUid(Binder.getCallingUid())
12622                                 .setMethod("getLastKnownCellIdentity")
12623                                 .setLogAsInfo(true)
12624                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
12625                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
12626                                 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
12627                                 .build());
12628 
12629         boolean hasFinePermission =
12630                 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
12631         if (!hasFinePermission
12632                 || !TelephonyPermissions.checkLastKnownCellIdAccessPermission(mApp)) {
12633             throw new SecurityException("getLastKnownCellIdentity need ACCESS_FINE_LOCATION "
12634                     + "and ACCESS_LAST_KNOWN_CELL_ID permission.");
12635         }
12636 
12637         final long identity = Binder.clearCallingIdentity();
12638         try {
12639             ServiceStateTracker sst = getPhoneFromSubIdOrDefault(subId).getServiceStateTracker();
12640             if (sst == null) return null;
12641             return sst.getLastKnownCellIdentity();
12642         } finally {
12643             Binder.restoreCallingIdentity(identity);
12644         }
12645     }
12646 
12647     /**
12648      * Sets the modem service class Name that Telephony will bind to.
12649      *
12650      * @param serviceName The class name of the modem service.
12651      * @return true if the operation is succeed, otherwise false.
12652      */
setModemService(String serviceName)12653     public boolean setModemService(String serviceName) {
12654         Log.d(LOG_TAG, "setModemService - " + serviceName);
12655         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setModemService");
12656         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
12657                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
12658                 "setModemService");
12659         return mPhoneConfigurationManager.setModemService(serviceName);
12660     }
12661 
12662     /**
12663      * Return the class name of the currently bounded modem service.
12664      *
12665      * @return the class name of the modem service.
12666      */
getModemService()12667     public String getModemService() {
12668         String result;
12669         Log.d(LOG_TAG, "getModemService");
12670         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getModemService");
12671         TelephonyPermissions
12672                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
12673                         mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
12674                         "getModemService");
12675         result = mPhoneConfigurationManager.getModemService();
12676         Log.d(LOG_TAG, "result = " + result);
12677         return result;
12678     }
12679 
12680     /**
12681      * Get the aggregated satellite plmn list. This API collects plmn data from multiple sources,
12682      * including carrier config, entitlement server, and config update.
12683      *
12684      * @param subId subId The subscription ID of the carrier.
12685      *
12686      * @return List of plmns for carrier satellite service. If no plmn is available, empty list will
12687      * be returned.
12688      *
12689      * @throws SecurityException if the caller doesn't have the required permission.
12690      */
getSatellitePlmnsForCarrier(int subId)12691     @NonNull public List<String> getSatellitePlmnsForCarrier(int subId) {
12692         enforceSatelliteCommunicationPermission("getSatellitePlmnsForCarrier");
12693         final long identity = Binder.clearCallingIdentity();
12694         try {
12695             return mSatelliteController.getSatellitePlmnsForCarrier(subId);
12696         } finally {
12697             Binder.restoreCallingIdentity(identity);
12698         }
12699     }
12700 
12701     @Override
setVoiceServiceStateOverride(int subId, boolean hasService, String callingPackage)12702     public void setVoiceServiceStateOverride(int subId, boolean hasService, String callingPackage) {
12703         // Only telecom (and shell, for CTS purposes) is allowed to call this method.
12704         mApp.enforceCallingOrSelfPermission(
12705                 permission.BIND_TELECOM_CONNECTION_SERVICE, "setVoiceServiceStateOverride");
12706         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
12707 
12708         final long identity = Binder.clearCallingIdentity();
12709         try {
12710             Phone phone = getPhone(subId);
12711             if (phone == null) return;
12712             Log.i(LOG_TAG, "setVoiceServiceStateOverride: subId=" + subId + ", phone=" + phone
12713                     + ", hasService=" + hasService + ", callingPackage=" + callingPackage);
12714             phone.setVoiceServiceStateOverride(hasService);
12715         } finally {
12716             Binder.restoreCallingIdentity(identity);
12717         }
12718     }
12719 
12720     /**
12721      * set removable eSIM as default eUICC.
12722      *
12723      * @hide
12724      */
12725     @Override
setRemovableEsimAsDefaultEuicc(boolean isDefault, String callingPackage)12726     public void setRemovableEsimAsDefaultEuicc(boolean isDefault, String callingPackage) {
12727         enforceModifyPermission();
12728         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
12729 
12730         final long identity = Binder.clearCallingIdentity();
12731         try {
12732             UiccController.getInstance().setRemovableEsimAsDefaultEuicc(isDefault);
12733         }  finally {
12734             Binder.restoreCallingIdentity(identity);
12735         }
12736     }
12737 
12738     /**
12739      * Returns whether the removable eSIM is default eUICC or not.
12740      *
12741      * @hide
12742      */
12743     @Override
isRemovableEsimDefaultEuicc(String callingPackage)12744     public boolean isRemovableEsimDefaultEuicc(String callingPackage) {
12745         enforceReadPrivilegedPermission("isRemovableEsimDefaultEuicc");
12746         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
12747 
12748         final long identity = Binder.clearCallingIdentity();
12749         try {
12750             return UiccController.getInstance().isRemovableEsimDefaultEuicc();
12751         }  finally {
12752             Binder.restoreCallingIdentity(identity);
12753         }
12754     }
12755 
12756     /**
12757      * Get the component name of the default app to direct respond-via-message intent for the
12758      * user associated with this subscription, update the cache if there is no respond-via-message
12759      * application currently configured for this user.
12760      * @return component name of the app and class to direct Respond Via Message intent to, or
12761      * {@code null} if the functionality is not supported.
12762      * @hide
12763      */
12764     @Override
getDefaultRespondViaMessageApplication(int subId, boolean updateIfNeeded)12765     public @Nullable ComponentName getDefaultRespondViaMessageApplication(int subId,
12766             boolean updateIfNeeded) {
12767         enforceInteractAcrossUsersPermission("getDefaultRespondViaMessageApplication");
12768 
12769         enforceTelephonyFeatureWithException(getCurrentPackageName(),
12770                 PackageManager.FEATURE_TELEPHONY_MESSAGING,
12771                 "getDefaultRespondViaMessageApplication");
12772 
12773         Context context = getPhoneFromSubIdOrDefault(subId).getContext();
12774 
12775         UserHandle userHandle = null;
12776         final long identity = Binder.clearCallingIdentity();
12777         try {
12778             userHandle = TelephonyUtils.getSubscriptionUserHandle(context, subId);
12779         } finally {
12780             Binder.restoreCallingIdentity(identity);
12781         }
12782         return SmsApplication.getDefaultRespondViaMessageApplicationAsUser(context,
12783                 updateIfNeeded, userHandle);
12784     }
12785 
12786     /**
12787      * Set whether the device is able to connect with null ciphering or integrity
12788      * algorithms. This is a global setting and will apply to all active subscriptions
12789      * and all new subscriptions after this.
12790      *
12791      * @param enabled when true, null  cipher and integrity algorithms are allowed.
12792      * @hide
12793      */
12794     @Override
12795     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setNullCipherAndIntegrityEnabled(boolean enabled)12796     public void setNullCipherAndIntegrityEnabled(boolean enabled) {
12797         enforceModifyPermission();
12798         checkForNullCipherAndIntegritySupport();
12799 
12800         // Persist the state of our preference. Each GsmCdmaPhone instance is responsible
12801         // for listening to these preference changes and applying them immediately.
12802         SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
12803         editor.putBoolean(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED, enabled);
12804         editor.apply();
12805 
12806         for (Phone phone: PhoneFactory.getPhones()) {
12807             phone.handleNullCipherEnabledChange();
12808         }
12809     }
12810 
12811 
12812     /**
12813      * Get whether the device is able to connect with null ciphering or integrity
12814      * algorithms. Note that this retrieves the phone-global preference and not
12815      * the state of the radio.
12816      *
12817      * @throws SecurityException if {@link permission#MODIFY_PHONE_STATE} is not satisfied
12818      * @throws UnsupportedOperationException if the device does not support the minimum HAL
12819      * version for this feature.
12820      * @hide
12821      */
12822     @Override
12823     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
isNullCipherAndIntegrityPreferenceEnabled()12824     public boolean isNullCipherAndIntegrityPreferenceEnabled() {
12825         enforceReadPermission();
12826         checkForNullCipherAndIntegritySupport();
12827         return getDefaultPhone().getNullCipherAndIntegrityEnabledPreference();
12828     }
12829 
checkForNullCipherAndIntegritySupport()12830     private void checkForNullCipherAndIntegritySupport() {
12831         if (getHalVersion(HAL_SERVICE_NETWORK) < MIN_NULL_CIPHER_AND_INTEGRITY_VERSION) {
12832             throw new UnsupportedOperationException(
12833                     "Null cipher and integrity operations require HAL 2.1 or above");
12834         }
12835         if (!getDefaultPhone().isNullCipherAndIntegritySupported()) {
12836             throw new UnsupportedOperationException(
12837                     "Null cipher and integrity operations unsupported by modem");
12838         }
12839     }
12840 
checkForIdentifierDisclosureNotificationSupport()12841     private void checkForIdentifierDisclosureNotificationSupport() {
12842         if (getHalVersion(HAL_SERVICE_NETWORK) < MIN_IDENTIFIER_DISCLOSURE_VERSION) {
12843             throw new UnsupportedOperationException(
12844                     "Cellular identifier disclosure transparency operations require HAL 2.2 or "
12845                             + "above");
12846         }
12847         if (!getDefaultPhone().isIdentifierDisclosureTransparencySupported()) {
12848             throw new UnsupportedOperationException(
12849                     "Cellular identifier disclosure transparency operations unsupported by modem");
12850         }
12851     }
12852 
checkForNullCipherNotificationSupport()12853     private void checkForNullCipherNotificationSupport() {
12854         if (getHalVersion(HAL_SERVICE_NETWORK) < MIN_NULL_CIPHER_NOTIFICATION_VERSION) {
12855             throw new UnsupportedOperationException(
12856                     "Null cipher notification operations require HAL 2.2 or above");
12857         }
12858         if (!getDefaultPhone().isNullCipherNotificationSupported()) {
12859             throw new UnsupportedOperationException(
12860                     "Null cipher notification operations unsupported by modem");
12861         }
12862     }
12863 
12864     /**
12865      * Get the SIM state for the slot index.
12866      * For Remote-SIMs, this method returns {@link IccCardConstants.State#UNKNOWN}
12867      *
12868      * @return SIM state as the ordinal of {@link IccCardConstants.State}
12869      */
12870     @Override
12871     @SimState
getSimStateForSlotIndex(int slotIndex)12872     public int getSimStateForSlotIndex(int slotIndex) {
12873         enforceTelephonyFeatureWithException(getCurrentPackageName(),
12874                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSimStateForSlotIndex");
12875 
12876         IccCardConstants.State simState;
12877         if (slotIndex < 0) {
12878             simState = IccCardConstants.State.UNKNOWN;
12879         } else {
12880             Phone phone = null;
12881             try {
12882                 phone = PhoneFactory.getPhone(slotIndex);
12883             } catch (IllegalStateException e) {
12884                 // ignore
12885             }
12886             if (phone == null) {
12887                 simState = IccCardConstants.State.UNKNOWN;
12888             } else {
12889                 IccCard icc = phone.getIccCard();
12890                 if (icc == null) {
12891                     simState = IccCardConstants.State.UNKNOWN;
12892                 } else {
12893                     simState = icc.getState();
12894                 }
12895             }
12896         }
12897         return simState.ordinal();
12898     }
12899 
persistEmergencyCallDiagnosticDataInternal(@onNull String dropboxTag, boolean enableLogcat, long logcatStartTimestampMillis, boolean enableTelecomDump, boolean enableTelephonyDump)12900     private void persistEmergencyCallDiagnosticDataInternal(@NonNull String dropboxTag,
12901             boolean enableLogcat,
12902             long logcatStartTimestampMillis, boolean enableTelecomDump,
12903             boolean enableTelephonyDump) {
12904         DropBoxManager db = mApp.getSystemService(DropBoxManager.class);
12905         TelephonyManager.EmergencyCallDiagnosticData.Builder ecdDataBuilder =
12906                 new TelephonyManager.EmergencyCallDiagnosticData.Builder();
12907         ecdDataBuilder
12908                 .setTelecomDumpsysCollectionEnabled(enableTelecomDump)
12909                 .setTelephonyDumpsysCollectionEnabled(enableTelephonyDump);
12910         if (enableLogcat) {
12911             ecdDataBuilder.setLogcatCollectionStartTimeMillis(logcatStartTimestampMillis);
12912         }
12913         TelephonyManager.EmergencyCallDiagnosticData ecdData = ecdDataBuilder.build();
12914         Log.d(LOG_TAG, "persisting with Params " + ecdData.toString());
12915         DiagnosticDataCollector ddc = new DiagnosticDataCollector(Runtime.getRuntime(),
12916                 Executors.newCachedThreadPool(), db,
12917                 mApp.getSystemService(ActivityManager.class).isLowRamDevice());
12918         ddc.persistEmergencyDianosticData(new DataCollectorConfig.Adapter(), ecdData, dropboxTag);
12919     }
12920 
12921     /**
12922      * Request telephony to persist state for debugging emergency call failures.
12923      *
12924      * @param dropboxTag                 Tag to use when persisting data to dropbox service.
12925      * @param enableLogcat               whether to collect logcat output
12926      * @param logcatStartTimestampMillis timestamp from when logcat buffers would be persisted
12927      * @param enableTelecomDump          whether to collect telecom dumpsys
12928      * @param enableTelephonyDump        whether to collect telephony dumpsys
12929      */
12930     @Override
12931     @RequiresPermission(android.Manifest.permission.DUMP)
persistEmergencyCallDiagnosticData(@onNull String dropboxTag, boolean enableLogcat, long logcatStartTimestampMillis, boolean enableTelecomDump, boolean enableTelephonyDump)12932     public void persistEmergencyCallDiagnosticData(@NonNull String dropboxTag, boolean enableLogcat,
12933             long logcatStartTimestampMillis, boolean enableTelecomDump,
12934             boolean enableTelephonyDump) {
12935         // Verify that the caller has READ_DROPBOX_DATA permission.
12936         if (mTelecomFeatureFlags.telecomResolveHiddenDependencies()
12937                 && Flags.enableReadDropboxPermission()) {
12938             mApp.enforceCallingPermission(permission.READ_DROPBOX_DATA,
12939                     "persistEmergencyCallDiagnosticData");
12940         } else {
12941             // Otherwise, enforce legacy permission.
12942             mApp.enforceCallingPermission(android.Manifest.permission.DUMP,
12943                     "persistEmergencyCallDiagnosticData");
12944         }
12945         final long identity = Binder.clearCallingIdentity();
12946         try {
12947             persistEmergencyCallDiagnosticDataInternal(dropboxTag, enableLogcat,
12948                     logcatStartTimestampMillis, enableTelecomDump, enableTelephonyDump);
12949 
12950         } finally {
12951             Binder.restoreCallingIdentity(identity);
12952         }
12953     }
12954 
12955     /**
12956      * Get current cell broadcast ranges.
12957      */
12958     @Override
12959     @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
getCellBroadcastIdRanges(int subId)12960     public List<CellBroadcastIdRange> getCellBroadcastIdRanges(int subId) {
12961         mApp.enforceCallingPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS,
12962                 "getCellBroadcastIdRanges");
12963 
12964         enforceTelephonyFeatureWithException(getCurrentPackageName(),
12965                 PackageManager.FEATURE_TELEPHONY_MESSAGING, "getCellBroadcastIdRanges");
12966 
12967         final long identity = Binder.clearCallingIdentity();
12968         try {
12969             return getPhone(subId).getCellBroadcastIdRanges();
12970         } finally {
12971             Binder.restoreCallingIdentity(identity);
12972         }
12973     }
12974 
12975     /**
12976      * Set reception of cell broadcast messages with the list of the given ranges
12977      *
12978      * @param ranges the list of {@link CellBroadcastIdRange} to be enabled
12979      */
12980     @Override
12981     @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
setCellBroadcastIdRanges(int subId, @NonNull List<CellBroadcastIdRange> ranges, @Nullable IIntegerConsumer callback)12982     public void setCellBroadcastIdRanges(int subId, @NonNull List<CellBroadcastIdRange> ranges,
12983             @Nullable IIntegerConsumer callback) {
12984         mApp.enforceCallingPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS,
12985                 "setCellBroadcastIdRanges");
12986 
12987         enforceTelephonyFeatureWithException(getCurrentPackageName(),
12988                 PackageManager.FEATURE_TELEPHONY_MESSAGING, "setCellBroadcastIdRanges");
12989 
12990         final long identity = Binder.clearCallingIdentity();
12991         try {
12992             Phone phone = getPhoneFromSubId(subId);
12993             if (DBG) {
12994                 log("setCellBroadcastIdRanges for subId :" + subId + ", phone:" + phone);
12995             }
12996             phone.setCellBroadcastIdRanges(ranges, result -> {
12997                 if (callback != null) {
12998                     try {
12999                         callback.accept(result);
13000                     } catch (RemoteException e) {
13001                         Log.w(LOG_TAG, "setCellBroadcastIdRanges: callback not available.");
13002                     }
13003                 }
13004             });
13005         } finally {
13006             Binder.restoreCallingIdentity(identity);
13007         }
13008     }
13009 
13010     /**
13011      * Returns whether the device supports the domain selection service.
13012      *
13013      * @return {@code true} if the device supports the domain selection service.
13014      */
13015     @Override
isDomainSelectionSupported()13016     public boolean isDomainSelectionSupported() {
13017         mApp.enforceCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
13018                 "isDomainSelectionSupported");
13019 
13020         final long identity = Binder.clearCallingIdentity();
13021         try {
13022             return DomainSelectionResolver.getInstance().isDomainSelectionSupported();
13023         }  finally {
13024             Binder.restoreCallingIdentity(identity);
13025         }
13026     }
13027 
13028     /**
13029      * Returns whether the AOSP domain selection service is supported.
13030      *
13031      * @return {@code true} if the AOSP domain selection service is supported,
13032      *         {@code false} otherwise.
13033      */
13034     @Override
isAospDomainSelectionService()13035     public boolean isAospDomainSelectionService() {
13036         mApp.enforceCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
13037                 "isAospDomainSelectionService");
13038 
13039         final long identity = Binder.clearCallingIdentity();
13040         try {
13041             if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
13042                 String dssComponentName = mApp.getResources().getString(
13043                         R.string.config_domain_selection_service_component_name);
13044                 ComponentName componentName = ComponentName.createRelative(mApp.getPackageName(),
13045                         TelephonyDomainSelectionService.class.getName());
13046                 Log.i(LOG_TAG, "isAospDomainSelectionService dss=" + dssComponentName
13047                         + ", aosp=" + componentName.flattenToString());
13048                 return TextUtils.equals(componentName.flattenToString(), dssComponentName);
13049             }
13050         } finally {
13051             Binder.restoreCallingIdentity(identity);
13052         }
13053         return false;
13054     }
13055 
13056     /**
13057      * Request to enable or disable the satellite modem and demo mode. If the satellite modem is
13058      * enabled, this may also disable the cellular modem, and if the satellite modem is disabled,
13059      * this may also re-enable the cellular modem.
13060      *
13061      * @param subId The subId of the subscription to set satellite enabled for.
13062      * @param enableSatellite {@code true} to enable the satellite modem and
13063      *                        {@code false} to disable.
13064      * @param enableDemoMode {@code true} to enable demo mode and {@code false} to disable.
13065      * @param isEmergency {@code true} to enable emergency mode, {@code false} otherwise.
13066      * @param callback The callback to get the result of the request.
13067      *
13068      * @throws SecurityException if the caller doesn't have the required permission.
13069      */
13070     @Override
requestSatelliteEnabled(int subId, boolean enableSatellite, boolean enableDemoMode, boolean isEmergency, @NonNull IIntegerConsumer callback)13071     public void requestSatelliteEnabled(int subId, boolean enableSatellite, boolean enableDemoMode,
13072             boolean isEmergency, @NonNull IIntegerConsumer callback) {
13073         enforceSatelliteCommunicationPermission("requestSatelliteEnabled");
13074         if (enableSatellite) {
13075             ResultReceiver resultReceiver = new ResultReceiver(mMainThreadHandler) {
13076                 @Override
13077                 protected void onReceiveResult(int resultCode, Bundle resultData) {
13078                     Log.d(LOG_TAG, "Satellite access restriction resultCode=" + resultCode
13079                             + ", resultData=" + resultData);
13080                     boolean isAllowed = false;
13081                     Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(
13082                             callback::accept);
13083                     if (resultCode == SATELLITE_RESULT_SUCCESS) {
13084                         if (resultData != null
13085                                 && resultData.containsKey(KEY_SATELLITE_COMMUNICATION_ALLOWED)) {
13086                             isAllowed = resultData.getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED);
13087                         } else {
13088                             loge("KEY_SATELLITE_COMMUNICATION_ALLOWED does not exist.");
13089                         }
13090                     } else {
13091                         result.accept(resultCode);
13092                         return;
13093                     }
13094                     if (isAllowed) {
13095                         mSatelliteController.requestSatelliteEnabled(
13096                                 subId, enableSatellite, enableDemoMode, isEmergency, callback);
13097                     } else {
13098                         result.accept(SATELLITE_RESULT_ACCESS_BARRED);
13099                     }
13100                 }
13101             };
13102             mSatelliteAccessController.requestIsCommunicationAllowedForCurrentLocation(
13103                     subId, resultReceiver);
13104         } else {
13105             // No need to check if satellite is allowed at current location when disabling satellite
13106             mSatelliteController.requestSatelliteEnabled(
13107                     subId, enableSatellite, enableDemoMode, isEmergency, callback);
13108         }
13109     }
13110 
13111     /**
13112      * Request to get whether the satellite modem is enabled.
13113      *
13114      * @param subId The subId of the subscription to check whether satellite is enabled for.
13115      * @param result The result receiver that returns whether the satellite modem is enabled
13116      *               if the request is successful or an error code if the request failed.
13117      *
13118      * @throws SecurityException if the caller doesn't have the required permission.
13119      */
13120     @Override
requestIsSatelliteEnabled(int subId, @NonNull ResultReceiver result)13121     public void requestIsSatelliteEnabled(int subId, @NonNull ResultReceiver result) {
13122         enforceSatelliteCommunicationPermission("requestIsSatelliteEnabled");
13123         mSatelliteController.requestIsSatelliteEnabled(subId, result);
13124     }
13125 
13126     /**
13127      * Request to get whether the satellite service demo mode is enabled.
13128      *
13129      * @param subId The subId of the subscription to check whether the satellite demo mode
13130      *              is enabled for.
13131      * @param result The result receiver that returns whether the satellite demo mode is enabled
13132      *               if the request is successful or an error code if the request failed.
13133      *
13134      * @throws SecurityException if the caller doesn't have the required permission.
13135      */
13136     @Override
requestIsDemoModeEnabled(int subId, @NonNull ResultReceiver result)13137     public void requestIsDemoModeEnabled(int subId, @NonNull ResultReceiver result) {
13138         enforceSatelliteCommunicationPermission("requestIsDemoModeEnabled");
13139         mSatelliteController.requestIsDemoModeEnabled(subId, result);
13140     }
13141 
13142     /**
13143      * Request to get whether the satellite service is enabled with emergency mode.
13144      *
13145      * @param subId The subId of the subscription to check whether the satellite demo mode
13146      *              is enabled for.
13147      * @param result The result receiver that returns whether the satellite emergency mode is
13148      *               enabled if the request is successful or an error code if the request failed.
13149      *
13150      * @throws SecurityException if the caller doesn't have the required permission.
13151      */
13152     @Override
requestIsEmergencyModeEnabled(int subId, @NonNull ResultReceiver result)13153     public void requestIsEmergencyModeEnabled(int subId, @NonNull ResultReceiver result) {
13154         enforceSatelliteCommunicationPermission("requestIsEmergencyModeEnabled");
13155         result.send(SATELLITE_RESULT_REQUEST_NOT_SUPPORTED, null);
13156     }
13157 
13158     /**
13159      * Request to get whether the satellite service is supported on the device.
13160      *
13161      * @param subId The subId of the subscription to check satellite service support for.
13162      * @param result The result receiver that returns whether the satellite service is supported on
13163      *               the device if the request is successful or an error code if the request failed.
13164      */
13165     @Override
requestIsSatelliteSupported(int subId, @NonNull ResultReceiver result)13166     public void requestIsSatelliteSupported(int subId, @NonNull ResultReceiver result) {
13167         mSatelliteController.requestIsSatelliteSupported(subId, result);
13168     }
13169 
13170     /**
13171      * Request to get the {@link SatelliteCapabilities} of the satellite service.
13172      *
13173      * @param subId The subId of the subscription to get the satellite capabilities for.
13174      * @param result The result receiver that returns the {@link SatelliteCapabilities}
13175      *               if the request is successful or an error code if the request failed.
13176      *
13177      * @throws SecurityException if the caller doesn't have required permission.
13178      */
13179     @Override
requestSatelliteCapabilities(int subId, @NonNull ResultReceiver result)13180     public void requestSatelliteCapabilities(int subId, @NonNull ResultReceiver result) {
13181         enforceSatelliteCommunicationPermission("requestSatelliteCapabilities");
13182         mSatelliteController.requestSatelliteCapabilities(subId, result);
13183     }
13184 
13185     /**
13186      * Start receiving satellite transmission updates.
13187      * This can be called by the pointing UI when the user starts pointing to the satellite.
13188      * Modem should continue to report the pointing input as the device or satellite moves.
13189      *
13190      * @param subId The subId of the subscription to start satellite transmission updates for.
13191      * @param resultCallback The callback to get the result of the request.
13192      * @param callback The callback to notify of satellite transmission updates.
13193      *
13194      * @throws SecurityException if the caller doesn't have the required permission.
13195      */
13196     @Override
startSatelliteTransmissionUpdates(int subId, @NonNull IIntegerConsumer resultCallback, @NonNull ISatelliteTransmissionUpdateCallback callback)13197     public void startSatelliteTransmissionUpdates(int subId,
13198             @NonNull IIntegerConsumer resultCallback,
13199             @NonNull ISatelliteTransmissionUpdateCallback callback) {
13200         enforceSatelliteCommunicationPermission("startSatelliteTransmissionUpdates");
13201         mSatelliteController.startSatelliteTransmissionUpdates(subId, resultCallback, callback);
13202     }
13203 
13204     /**
13205      * Stop receiving satellite transmission updates.
13206      * This can be called by the pointing UI when the user stops pointing to the satellite.
13207      *
13208      * @param subId The subId of the subscription to stop satellite transmission updates for.
13209      * @param resultCallback The callback to get the result of the request.
13210      * @param callback The callback that was passed to {@link #startSatelliteTransmissionUpdates(
13211      *                 int, IIntegerConsumer, ISatelliteTransmissionUpdateCallback)}.
13212      *
13213      * @throws SecurityException if the caller doesn't have the required permission.
13214      */
13215     @Override
stopSatelliteTransmissionUpdates(int subId, @NonNull IIntegerConsumer resultCallback, @NonNull ISatelliteTransmissionUpdateCallback callback)13216     public void stopSatelliteTransmissionUpdates(int subId,
13217             @NonNull IIntegerConsumer resultCallback,
13218             @NonNull ISatelliteTransmissionUpdateCallback callback) {
13219         enforceSatelliteCommunicationPermission("stopSatelliteTransmissionUpdates");
13220         mSatelliteController.stopSatelliteTransmissionUpdates(subId, resultCallback, callback);
13221     }
13222 
13223     /**
13224      * Register the subscription with a satellite provider.
13225      * This is needed to register the subscription if the provider allows dynamic registration.
13226      *
13227      * @param subId The subId of the subscription to be provisioned.
13228      * @param token The token to be used as a unique identifier for provisioning with satellite
13229      *              gateway.
13230      * @param provisionData Data from the provisioning app that can be used by provisioning server
13231      * @param callback The callback to get the result of the request.
13232      *
13233      * @return The signal transport used by the caller to cancel the provision request,
13234      *         or {@code null} if the request failed.
13235      *
13236      * @throws SecurityException if the caller doesn't have the required permission.
13237      */
13238     @Override
provisionSatelliteService(int subId, @NonNull String token, @NonNull byte[] provisionData, @NonNull IIntegerConsumer callback)13239     @Nullable public ICancellationSignal provisionSatelliteService(int subId,
13240             @NonNull String token, @NonNull byte[] provisionData,
13241             @NonNull IIntegerConsumer callback) {
13242         enforceSatelliteCommunicationPermission("provisionSatelliteService");
13243         return mSatelliteController.provisionSatelliteService(subId, token, provisionData,
13244                 callback);
13245     }
13246 
13247     /**
13248      * Unregister the device/subscription with the satellite provider.
13249      * This is needed if the provider allows dynamic registration. Once deprovisioned,
13250      * {@link SatelliteProvisionStateCallback#onSatelliteProvisionStateChanged(boolean)}
13251      * should report as deprovisioned.
13252      *
13253      * @param subId The subId of the subscription to be deprovisioned.
13254      * @param token The token of the device/subscription to be deprovisioned.
13255      * @param callback The callback to get the result of the request.
13256      *
13257      * @throws SecurityException if the caller doesn't have the required permission.
13258      */
13259     @Override
deprovisionSatelliteService(int subId, @NonNull String token, @NonNull IIntegerConsumer callback)13260     public void deprovisionSatelliteService(int subId,
13261             @NonNull String token, @NonNull IIntegerConsumer callback) {
13262         enforceSatelliteCommunicationPermission("deprovisionSatelliteService");
13263         mSatelliteController.deprovisionSatelliteService(subId, token, callback);
13264     }
13265 
13266     /**
13267      * Registers for the satellite provision state changed.
13268      *
13269      * @param subId The subId of the subscription to register for provision state changed.
13270      * @param callback The callback to handle the satellite provision state changed event.
13271      *
13272      * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
13273      *
13274      * @throws SecurityException if the caller doesn't have the required permission.
13275      */
13276     @Override
registerForSatelliteProvisionStateChanged( int subId, @NonNull ISatelliteProvisionStateCallback callback)13277     @SatelliteManager.SatelliteResult public int registerForSatelliteProvisionStateChanged(
13278             int subId, @NonNull ISatelliteProvisionStateCallback callback) {
13279         enforceSatelliteCommunicationPermission("registerForSatelliteProvisionStateChanged");
13280         return mSatelliteController.registerForSatelliteProvisionStateChanged(subId, callback);
13281     }
13282 
13283     /**
13284      * Unregisters for the satellite provision state changed.
13285      * If callback was not registered before, the request will be ignored.
13286      *
13287      * @param subId The subId of the subscription to unregister for provision state changed.
13288      * @param callback The callback that was passed to
13289      * {@link #registerForSatelliteProvisionStateChanged(int, ISatelliteProvisionStateCallback)}.
13290      *
13291      * @throws SecurityException if the caller doesn't have the required permission.
13292      */
13293     @Override
unregisterForSatelliteProvisionStateChanged( int subId, @NonNull ISatelliteProvisionStateCallback callback)13294     public void unregisterForSatelliteProvisionStateChanged(
13295             int subId, @NonNull ISatelliteProvisionStateCallback callback) {
13296         enforceSatelliteCommunicationPermission("unregisterForSatelliteProvisionStateChanged");
13297         mSatelliteController.unregisterForSatelliteProvisionStateChanged(subId, callback);
13298     }
13299 
13300     /**
13301      * Request to get whether the device is provisioned with a satellite provider.
13302      *
13303      * @param subId The subId of the subscription to get whether the device is provisioned for.
13304      * @param result The result receiver that returns whether the device is provisioned with a
13305      *               satellite provider if the request is successful or an error code if the
13306      *               request failed.
13307      *
13308      * @throws SecurityException if the caller doesn't have the required permission.
13309      */
13310     @Override
requestIsSatelliteProvisioned(int subId, @NonNull ResultReceiver result)13311     public void requestIsSatelliteProvisioned(int subId, @NonNull ResultReceiver result) {
13312         enforceSatelliteCommunicationPermission("requestIsSatelliteProvisioned");
13313         mSatelliteController.requestIsSatelliteProvisioned(subId, result);
13314     }
13315 
13316     /**
13317      * Registers for modem state changed from satellite modem.
13318      *
13319      * @param subId The subId of the subscription to register for satellite modem state changed.
13320      * @param callback The callback to handle the satellite modem state changed event.
13321      *
13322      * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
13323      *
13324      * @throws SecurityException if the caller doesn't have the required permission.
13325      */
13326     @Override
registerForSatelliteModemStateChanged(int subId, @NonNull ISatelliteModemStateCallback callback)13327     @SatelliteManager.SatelliteResult public int registerForSatelliteModemStateChanged(int subId,
13328             @NonNull ISatelliteModemStateCallback callback) {
13329         enforceSatelliteCommunicationPermission("registerForSatelliteModemStateChanged");
13330         return mSatelliteController.registerForSatelliteModemStateChanged(subId, callback);
13331     }
13332 
13333     /**
13334      * Unregisters for modem state changed from satellite modem.
13335      * If callback was not registered before, the request will be ignored.
13336      *
13337      * @param subId The subId of the subscription to unregister for satellite modem state changed.
13338      * @param callback The callback that was passed to
13339      * {@link #registerForModemStateChanged(int, ISatelliteModemStateCallback)}.
13340      *
13341      * @throws SecurityException if the caller doesn't have the required permission.
13342      */
13343     @Override
unregisterForModemStateChanged(int subId, @NonNull ISatelliteModemStateCallback callback)13344     public void unregisterForModemStateChanged(int subId,
13345             @NonNull ISatelliteModemStateCallback callback) {
13346         enforceSatelliteCommunicationPermission("unregisterForModemStateChanged");
13347         mSatelliteController.unregisterForModemStateChanged(subId, callback);
13348     }
13349 
13350     /**
13351      * Register to receive incoming datagrams over satellite.
13352      *
13353      * @param subId The subId of the subscription to register for incoming satellite datagrams.
13354      * @param callback The callback to handle incoming datagrams over satellite.
13355      *
13356      * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
13357      *
13358      * @throws SecurityException if the caller doesn't have the required permission.
13359      */
13360     @Override
registerForIncomingDatagram(int subId, @NonNull ISatelliteDatagramCallback callback)13361     @SatelliteManager.SatelliteResult public int registerForIncomingDatagram(int subId,
13362             @NonNull ISatelliteDatagramCallback callback) {
13363         enforceSatelliteCommunicationPermission("registerForIncomingDatagram");
13364         return mSatelliteController.registerForIncomingDatagram(subId, callback);
13365     }
13366 
13367     /**
13368      * Unregister to stop receiving incoming datagrams over satellite.
13369      * If callback was not registered before, the request will be ignored.
13370      *
13371      * @param subId The subId of the subscription to unregister for incoming satellite datagrams.
13372      * @param callback The callback that was passed to
13373      *                 {@link #registerForIncomingDatagram(int, ISatelliteDatagramCallback)}.
13374      *
13375      * @throws SecurityException if the caller doesn't have the required permission.
13376      */
13377     @Override
unregisterForIncomingDatagram(int subId, @NonNull ISatelliteDatagramCallback callback)13378     public void unregisterForIncomingDatagram(int subId,
13379             @NonNull ISatelliteDatagramCallback callback) {
13380         enforceSatelliteCommunicationPermission("unregisterForIncomingDatagram");
13381         mSatelliteController.unregisterForIncomingDatagram(subId, callback);
13382     }
13383 
13384     /**
13385      * Poll pending satellite datagrams over satellite.
13386      *
13387      * This method requests modem to check if there are any pending datagrams to be received over
13388      * satellite. If there are any incoming datagrams, they will be received via
13389      * {@link SatelliteDatagramCallback#onSatelliteDatagramReceived(long, SatelliteDatagram, int, Consumer)})}
13390      *
13391      * @param subId The subId of the subscription used for receiving datagrams.
13392      * @param callback The callback to get {@link SatelliteManager.SatelliteResult} of the request.
13393      *
13394      * @throws SecurityException if the caller doesn't have required permission.
13395      */
pollPendingDatagrams(int subId, IIntegerConsumer callback)13396     public void pollPendingDatagrams(int subId, IIntegerConsumer callback) {
13397         enforceSatelliteCommunicationPermission("pollPendingDatagrams");
13398         mSatelliteController.pollPendingDatagrams(subId, callback);
13399     }
13400 
13401     /**
13402      * Send datagram over satellite.
13403      *
13404      * Gateway encodes SOS message or location sharing message into a datagram and passes it as
13405      * input to this method. Datagram received here will be passed down to modem without any
13406      * encoding or encryption.
13407      *
13408      * @param subId The subId of the subscription to send satellite datagrams for.
13409      * @param datagramType datagram type indicating whether the datagram is of type
13410      *                     SOS_SMS or LOCATION_SHARING.
13411      * @param datagram encoded gateway datagram which is encrypted by the caller.
13412      *                 Datagram will be passed down to modem without any encoding or encryption.
13413      * @param needFullScreenPointingUI this is used to indicate pointingUI app to open in
13414      *                                 full screen mode.
13415      * @param callback The callback to get {@link SatelliteManager.SatelliteResult} of the request.
13416      *
13417      * @throws SecurityException if the caller doesn't have required permission.
13418      */
13419     @Override
sendDatagram(int subId, @SatelliteManager.DatagramType int datagramType, @NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI, @NonNull IIntegerConsumer callback)13420     public void sendDatagram(int subId, @SatelliteManager.DatagramType int datagramType,
13421             @NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI,
13422             @NonNull IIntegerConsumer callback) {
13423         enforceSatelliteCommunicationPermission("sendDatagram");
13424         mSatelliteController.sendDatagram(subId, datagramType, datagram, needFullScreenPointingUI,
13425                 callback);
13426     }
13427 
13428     /**
13429      * Request to get whether satellite communication is allowed for the current location.
13430      *
13431      * @param subId The subId of the subscription to check whether satellite communication is
13432      *              allowed for the current location for.
13433      * @param result The result receiver that returns whether satellite communication is allowed
13434      *               for the current location if the request is successful or an error code
13435      *               if the request failed.
13436      *
13437      * @throws SecurityException if the caller doesn't have the required permission.
13438      */
13439     @Override
requestIsCommunicationAllowedForCurrentLocation(int subId, @NonNull ResultReceiver result)13440     public void requestIsCommunicationAllowedForCurrentLocation(int subId,
13441             @NonNull ResultReceiver result) {
13442         enforceSatelliteCommunicationPermission("requestIsCommunicationAllowedForCurrentLocation");
13443         mSatelliteAccessController.requestIsCommunicationAllowedForCurrentLocation(subId,
13444                 result);
13445     }
13446 
13447     /**
13448      * Request to get the time after which the satellite will be visible.
13449      *
13450      * @param subId The subId to get the time after which the satellite will be visible for.
13451      * @param result The result receiver that returns the time after which the satellite will
13452      *               be visible if the request is successful or an error code if the request failed.
13453      *
13454      * @throws SecurityException if the caller doesn't have the required permission.
13455      */
13456     @Override
requestTimeForNextSatelliteVisibility(int subId, @NonNull ResultReceiver result)13457     public void requestTimeForNextSatelliteVisibility(int subId, @NonNull ResultReceiver result) {
13458         enforceSatelliteCommunicationPermission("requestTimeForNextSatelliteVisibility");
13459         mSatelliteController.requestTimeForNextSatelliteVisibility(subId, result);
13460     }
13461 
13462     /**
13463      * Inform that Device is aligned to satellite for demo mode.
13464      *
13465      * @param subId The subId to get the time after which the satellite will be visible for.
13466      * @param isAligned {@code true} Device is aligned with the satellite for demo mode
13467      *                  {@code false} Device fails to align with the satellite for demo mode.
13468      *
13469      * @throws SecurityException if the caller doesn't have required permission.
13470      */
13471     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
13472 
setDeviceAlignedWithSatellite(int subId, @NonNull boolean isAligned)13473     public void setDeviceAlignedWithSatellite(int subId, @NonNull boolean isAligned) {
13474         enforceSatelliteCommunicationPermission("informDeviceAlignedToSatellite");
13475         mSatelliteController.setDeviceAlignedWithSatellite(subId, isAligned);
13476     }
13477 
13478     /**
13479      * Add a restriction reason for disallowing carrier supported satellite plmn scan and attach
13480      * by modem.
13481      *
13482      * @param subId The subId of the subscription to request for.
13483      * @param reason Reason for disallowing satellite communication for carrier.
13484      * @param callback Listener for the {@link SatelliteManager.SatelliteResult} result of the
13485      * operation.
13486      *
13487      * @throws SecurityException if the caller doesn't have required permission.
13488      */
addAttachRestrictionForCarrier(int subId, @SatelliteManager.SatelliteCommunicationRestrictionReason int reason, @NonNull IIntegerConsumer callback)13489     public void addAttachRestrictionForCarrier(int subId,
13490             @SatelliteManager.SatelliteCommunicationRestrictionReason int reason,
13491             @NonNull IIntegerConsumer callback) {
13492         enforceSatelliteCommunicationPermission("addAttachRestrictionForCarrier");
13493         final long identity = Binder.clearCallingIdentity();
13494         try {
13495             mSatelliteController.addAttachRestrictionForCarrier(subId, reason, callback);
13496         } finally {
13497             Binder.restoreCallingIdentity(identity);
13498         }
13499     }
13500 
13501     /**
13502      * Remove a restriction reason for disallowing carrier supported satellite plmn scan and attach
13503      * by modem.
13504      *
13505      * @param subId The subId of the subscription to request for.
13506      * @param reason Reason for disallowing satellite communication.
13507      * @param callback Listener for the {@link SatelliteManager.SatelliteResult} result of the
13508      * operation.
13509      *
13510      * @throws SecurityException if the caller doesn't have required permission.
13511      */
removeAttachRestrictionForCarrier(int subId, @SatelliteManager.SatelliteCommunicationRestrictionReason int reason, @NonNull IIntegerConsumer callback)13512     public void removeAttachRestrictionForCarrier(int subId,
13513             @SatelliteManager.SatelliteCommunicationRestrictionReason int reason,
13514             @NonNull IIntegerConsumer callback) {
13515         enforceSatelliteCommunicationPermission("removeAttachRestrictionForCarrier");
13516         final long identity = Binder.clearCallingIdentity();
13517         try {
13518             mSatelliteController.removeAttachRestrictionForCarrier(subId, reason, callback);
13519         } finally {
13520             Binder.restoreCallingIdentity(identity);
13521         }
13522     }
13523 
13524     /**
13525      * Get reasons for disallowing satellite communication, as requested by
13526      * {@link #addAttachRestrictionForCarrier(int, int, IIntegerConsumer)}.
13527      *
13528      * @param subId The subId of the subscription to request for.
13529      *
13530      * @return Integer array of reasons for disallowing satellite communication.
13531      *
13532      * @throws SecurityException if the caller doesn't have the required permission.
13533      */
getAttachRestrictionReasonsForCarrier( int subId)13534     public @NonNull int[] getAttachRestrictionReasonsForCarrier(
13535             int subId) {
13536         enforceSatelliteCommunicationPermission("getAttachRestrictionReasonsForCarrier");
13537         final long identity = Binder.clearCallingIdentity();
13538         try {
13539             Set<Integer> reasonSet =
13540                     mSatelliteController.getAttachRestrictionReasonsForCarrier(subId);
13541             return reasonSet.stream().mapToInt(i->i).toArray();
13542         } finally {
13543             Binder.restoreCallingIdentity(identity);
13544         }
13545     }
13546 
13547     /**
13548      * Request to get the signal strength of the satellite connection.
13549      *
13550      * @param subId The subId of the subscription to request for.
13551      * @param result Result receiver to get the error code of the request and the current signal
13552      * strength of the satellite connection.
13553      *
13554      * @throws SecurityException if the caller doesn't have required permission.
13555      */
13556     @Override
requestNtnSignalStrength(int subId, @NonNull ResultReceiver result)13557     public void requestNtnSignalStrength(int subId, @NonNull ResultReceiver result) {
13558         enforceSatelliteCommunicationPermission("requestNtnSignalStrength");
13559         final long identity = Binder.clearCallingIdentity();
13560         try {
13561             mSatelliteController.requestNtnSignalStrength(subId, result);
13562         } finally {
13563             Binder.restoreCallingIdentity(identity);
13564         }
13565     }
13566 
13567     /**
13568      * Registers for NTN signal strength changed from satellite modem. If the registration operation
13569      * is not successful, a {@link ServiceSpecificException} that contains
13570      * {@link SatelliteManager.SatelliteResult} will be thrown.
13571      *
13572      * @param subId The subId of the subscription to request for.
13573      * @param callback The callback to handle the NTN signal strength changed event. If the
13574      * operation is successful, {@link NtnSignalStrengthCallback#onNtnSignalStrengthChanged(
13575      * NtnSignalStrength)} will return an instance of {@link NtnSignalStrength} with a value of
13576      * {@link NtnSignalStrength.NtnSignalStrengthLevel} when the signal strength of non-terrestrial
13577      * network has changed.
13578      *
13579      * @throws SecurityException If the caller doesn't have the required permission.
13580      * @throws ServiceSpecificException If the callback registration operation fails.
13581      */
13582     @Override
registerForNtnSignalStrengthChanged(int subId, @NonNull INtnSignalStrengthCallback callback)13583     public void registerForNtnSignalStrengthChanged(int subId,
13584             @NonNull INtnSignalStrengthCallback callback) throws RemoteException {
13585         enforceSatelliteCommunicationPermission("registerForNtnSignalStrengthChanged");
13586         final long identity = Binder.clearCallingIdentity();
13587         try {
13588             mSatelliteController.registerForNtnSignalStrengthChanged(subId, callback);
13589         } finally {
13590             Binder.restoreCallingIdentity(identity);
13591         }
13592     }
13593 
13594     /**
13595      * Unregisters for NTN signal strength changed from satellite modem.
13596      * If callback was not registered before, the request will be ignored.
13597      *
13598      * @param subId The subId of the subscription to unregister for listening NTN signal strength
13599      * changed event.
13600      * @param callback The callback that was passed to
13601      * {@link #registerForNtnSignalStrengthChanged(int, INtnSignalStrengthCallback)}
13602      *
13603      * @throws SecurityException if the caller doesn't have the required permission.
13604      */
13605     @Override
unregisterForNtnSignalStrengthChanged( int subId, @NonNull INtnSignalStrengthCallback callback)13606     public void unregisterForNtnSignalStrengthChanged(
13607             int subId, @NonNull INtnSignalStrengthCallback callback) {
13608         enforceSatelliteCommunicationPermission("unregisterForNtnSignalStrengthChanged");
13609         final long identity = Binder.clearCallingIdentity();
13610         try {
13611             mSatelliteController.unregisterForNtnSignalStrengthChanged(subId, callback);
13612         } finally {
13613             Binder.restoreCallingIdentity(identity);
13614         }
13615     }
13616 
13617     /**
13618      * Registers for satellite capabilities change event from the satellite service.
13619      *
13620      * @param subId The subId of the subscription to request for.
13621      * @param callback The callback to handle the satellite capabilities changed event.
13622      *
13623      * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
13624      *
13625      * @throws SecurityException if the caller doesn't have required permission.
13626      */
13627     @Override
registerForCapabilitiesChanged( int subId, @NonNull ISatelliteCapabilitiesCallback callback)13628     @SatelliteManager.SatelliteResult public int registerForCapabilitiesChanged(
13629             int subId, @NonNull ISatelliteCapabilitiesCallback callback) {
13630         enforceSatelliteCommunicationPermission("registerForCapabilitiesChanged");
13631         final long identity = Binder.clearCallingIdentity();
13632         try {
13633             return mSatelliteController.registerForCapabilitiesChanged(subId, callback);
13634         } finally {
13635             Binder.restoreCallingIdentity(identity);
13636         }
13637     }
13638 
13639     /**
13640      * Unregisters for satellite capabilities change event from the satellite service.
13641      * If callback was not registered before, the request will be ignored.
13642      *
13643      * @param subId The subId of the subscription to unregister for satellite capabilities change.
13644      * @param callback The callback that was passed to.
13645      * {@link #registerForCapabilitiesChanged(int, ISatelliteCapabilitiesCallback)}.
13646      *
13647      * @throws SecurityException if the caller doesn't have required permission.
13648      */
13649     @Override
unregisterForCapabilitiesChanged(int subId, @NonNull ISatelliteCapabilitiesCallback callback)13650     public void unregisterForCapabilitiesChanged(int subId,
13651             @NonNull ISatelliteCapabilitiesCallback callback) {
13652         enforceSatelliteCommunicationPermission("unregisterForCapabilitiesChanged");
13653         final long identity = Binder.clearCallingIdentity();
13654         try {
13655             mSatelliteController.unregisterForCapabilitiesChanged(subId, callback);
13656         } finally {
13657             Binder.restoreCallingIdentity(identity);
13658         }
13659     }
13660 
13661     /**
13662      * Registers for the satellite supported state changed.
13663      *
13664      * @param subId The subId of the subscription to register for supported state changed.
13665      * @param callback The callback to handle the satellite supported state changed event.
13666      *
13667      * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
13668      *
13669      * @throws SecurityException if the caller doesn't have the required permission.
13670      */
13671     @Override
registerForSatelliteSupportedStateChanged( int subId, @NonNull ISatelliteSupportedStateCallback callback)13672     @SatelliteManager.SatelliteResult public int registerForSatelliteSupportedStateChanged(
13673             int subId, @NonNull ISatelliteSupportedStateCallback callback) {
13674         enforceSatelliteCommunicationPermission("registerForSatelliteSupportedStateChanged");
13675         return mSatelliteController.registerForSatelliteSupportedStateChanged(subId, callback);
13676     }
13677 
13678     /**
13679      * Unregisters for the satellite supported state changed.
13680      * If callback was not registered before, the request will be ignored.
13681      *
13682      * @param subId The subId of the subscription to unregister for supported state changed.
13683      * @param callback The callback that was passed to
13684      * {@link #registerForSatelliteSupportedStateChanged(int, ISatelliteSupportedStateCallback)}.
13685      *
13686      * @throws SecurityException if the caller doesn't have the required permission.
13687      */
13688     @Override
unregisterForSatelliteSupportedStateChanged( int subId, @NonNull ISatelliteSupportedStateCallback callback)13689     public void unregisterForSatelliteSupportedStateChanged(
13690             int subId, @NonNull ISatelliteSupportedStateCallback callback) {
13691         enforceSatelliteCommunicationPermission("unregisterForSatelliteSupportedStateChanged");
13692         mSatelliteController.unregisterForSatelliteSupportedStateChanged(subId, callback);
13693     }
13694 
13695     /**
13696      * This API can be used by only CTS to update satellite vendor service package name.
13697      *
13698      * @param servicePackageName The package name of the satellite vendor service.
13699      * @return {@code true} if the satellite vendor service is set successfully,
13700      * {@code false} otherwise.
13701      */
setSatelliteServicePackageName(String servicePackageName)13702     public boolean setSatelliteServicePackageName(String servicePackageName) {
13703         Log.d(LOG_TAG, "setSatelliteServicePackageName - " + servicePackageName);
13704         TelephonyPermissions.enforceShellOnly(
13705                 Binder.getCallingUid(), "setSatelliteServicePackageName");
13706         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
13707                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
13708                 "setSatelliteServicePackageName");
13709         return mSatelliteController.setSatelliteServicePackageName(servicePackageName);
13710     }
13711 
13712     /**
13713      * This API can be used by only CTS to update satellite gateway service package name.
13714      *
13715      * @param servicePackageName The package name of the satellite gateway service.
13716      * @return {@code true} if the satellite gateway service is set successfully,
13717      * {@code false} otherwise.
13718      */
setSatelliteGatewayServicePackageName(@ullable String servicePackageName)13719     public boolean setSatelliteGatewayServicePackageName(@Nullable String servicePackageName) {
13720         Log.d(LOG_TAG, "setSatelliteGatewayServicePackageName - " + servicePackageName);
13721         TelephonyPermissions.enforceShellOnly(
13722                 Binder.getCallingUid(), "setSatelliteGatewayServicePackageName");
13723         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
13724                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
13725                 "setSatelliteGatewayServicePackageName");
13726         return mSatelliteController.setSatelliteGatewayServicePackageName(servicePackageName);
13727     }
13728 
13729     /**
13730      * This API can be used by only CTS to update satellite pointing UI app package and class names.
13731      *
13732      * @param packageName The package name of the satellite pointing UI app.
13733      * @param className The class name of the satellite pointing UI app.
13734      * @return {@code true} if the satellite pointing UI app package and class is set successfully,
13735      * {@code false} otherwise.
13736      */
setSatellitePointingUiClassName( @ullable String packageName, @Nullable String className)13737     public boolean setSatellitePointingUiClassName(
13738             @Nullable String packageName, @Nullable String className) {
13739         Log.d(LOG_TAG, "setSatellitePointingUiClassName: packageName=" + packageName
13740                 + ", className=" + className);
13741         TelephonyPermissions.enforceShellOnly(
13742                 Binder.getCallingUid(), "setSatellitePointingUiClassName");
13743         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
13744                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
13745                 "setSatelliteGatewayServicePackageName");
13746         return mSatelliteController.setSatellitePointingUiClassName(packageName, className);
13747     }
13748 
13749     /**
13750      * This API can be used by only CTS to update the timeout duration in milliseconds that
13751      * satellite should stay at listening mode to wait for the next incoming page before disabling
13752      * listening mode.
13753      *
13754      * @param timeoutMillis The timeout duration in millisecond.
13755      * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
13756      */
setSatelliteListeningTimeoutDuration(long timeoutMillis)13757     public boolean setSatelliteListeningTimeoutDuration(long timeoutMillis) {
13758         Log.d(LOG_TAG, "setSatelliteListeningTimeoutDuration - " + timeoutMillis);
13759         TelephonyPermissions.enforceShellOnly(
13760                 Binder.getCallingUid(), "setSatelliteListeningTimeoutDuration");
13761         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
13762                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
13763                 "setSatelliteListeningTimeoutDuration");
13764         return mSatelliteController.setSatelliteListeningTimeoutDuration(timeoutMillis);
13765     }
13766 
13767     /**
13768      * This API can be used by only CTS to override the timeout durations used by the
13769      * DatagramController module.
13770      *
13771      * @param timeoutMillis The timeout duration in millisecond.
13772      * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
13773      */
setDatagramControllerTimeoutDuration( boolean reset, int timeoutType, long timeoutMillis)13774     public boolean setDatagramControllerTimeoutDuration(
13775             boolean reset, int timeoutType, long timeoutMillis) {
13776         Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration - " + timeoutMillis + ", reset="
13777                 + reset + ", timeoutMillis=" + timeoutMillis);
13778         TelephonyPermissions.enforceShellOnly(
13779                 Binder.getCallingUid(), "setDatagramControllerTimeoutDuration");
13780         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
13781                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
13782                 "setDatagramControllerTimeoutDuration");
13783         return mSatelliteController.setDatagramControllerTimeoutDuration(
13784                 reset, timeoutType, timeoutMillis);
13785     }
13786 
13787     /**
13788      * This API can be used by only CTS to override the boolean configs used by the
13789      * DatagramController module.
13790      *
13791      * @param enable Whether to enable or disable boolean config.
13792      * @return {@code true} if the boolean config is set successfully, {@code false} otherwise.
13793      */
setDatagramControllerBooleanConfig( boolean reset, int booleanType, boolean enable)13794     public boolean setDatagramControllerBooleanConfig(
13795             boolean reset, int booleanType, boolean enable) {
13796         Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: booleanType=" + booleanType
13797                 + ", reset=" + reset + ", enable=" + enable);
13798         TelephonyPermissions.enforceShellOnly(
13799                 Binder.getCallingUid(), "setDatagramControllerBooleanConfig");
13800         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
13801                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
13802                 "ssetDatagramControllerBooleanConfig");
13803         return mSatelliteController.setDatagramControllerBooleanConfig(reset, booleanType, enable);
13804     }
13805 
13806 
13807     /**
13808      * This API can be used by only CTS to override the timeout durations used by the
13809      * SatelliteController module.
13810      *
13811      * @param timeoutMillis The timeout duration in millisecond.
13812      * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
13813      */
setSatelliteControllerTimeoutDuration( boolean reset, int timeoutType, long timeoutMillis)13814     public boolean setSatelliteControllerTimeoutDuration(
13815             boolean reset, int timeoutType, long timeoutMillis) {
13816         Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration - " + timeoutMillis + ", reset="
13817                 + reset + ", timeoutMillis=" + timeoutMillis);
13818         TelephonyPermissions.enforceShellOnly(
13819                 Binder.getCallingUid(), "setSatelliteControllerTimeoutDuration");
13820         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
13821                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
13822                 "setSatelliteControllerTimeoutDuration");
13823         return mSatelliteController.setSatelliteControllerTimeoutDuration(
13824                 reset, timeoutType, timeoutMillis);
13825     }
13826 
13827     /**
13828      * This API can be used in only testing to override connectivity status in monitoring emergency
13829      * calls and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.
13830      *
13831      * @param handoverType The type of handover from emergency call to satellite messaging. Use one
13832      *                     of the following values to enable the override:
13833      *                     0 - EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS
13834      *                     1 - EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911
13835      *                     To disable the override, use -1 for handoverType.
13836      * @param delaySeconds The event EVENT_DISPLAY_EMERGENCY_MESSAGE will be sent to Dialer
13837      *                     delaySeconds after the emergency call starts.
13838      * @return {@code true} if the handover type is set successfully, {@code false} otherwise.
13839      */
setEmergencyCallToSatelliteHandoverType(int handoverType, int delaySeconds)13840     public boolean setEmergencyCallToSatelliteHandoverType(int handoverType, int delaySeconds) {
13841         Log.d(LOG_TAG, "setEmergencyCallToSatelliteHandoverType - " + handoverType);
13842         TelephonyPermissions.enforceShellOnly(
13843                 Binder.getCallingUid(), "setEmergencyCallToSatelliteHandoverType");
13844         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
13845                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
13846                 "setEmergencyCallToSatelliteHandoverType");
13847         return mSatelliteController.setEmergencyCallToSatelliteHandoverType(
13848                 handoverType, delaySeconds);
13849     }
13850 
13851     /**
13852      * This API can be used in only testing to override oem-enabled satellite provision status.
13853      *
13854      * @param reset {@code true} mean the overriding status should not be used, {@code false}
13855      *              otherwise.
13856      * @param isProvisioned The overriding provision status.
13857      * @return {@code true} if the provision status is set successfully, {@code false} otherwise.
13858      */
setOemEnabledSatelliteProvisionStatus(boolean reset, boolean isProvisioned)13859     public boolean setOemEnabledSatelliteProvisionStatus(boolean reset, boolean isProvisioned) {
13860         Log.d(LOG_TAG, "setOemEnabledSatelliteProvisionStatus - reset=" + reset
13861                 + ", isProvisioned=" + isProvisioned);
13862         TelephonyPermissions.enforceShellOnly(
13863                 Binder.getCallingUid(), "setOemEnabledSatelliteProvisionStatus");
13864         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
13865                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
13866                 "setOemEnabledSatelliteProvisionStatus");
13867         return mSatelliteController.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
13868     }
13869 
13870     /**
13871      * This API should be used by only CTS tests to forcefully set telephony country codes.
13872      *
13873      * @return {@code true} if the country code is set successfully, {@code false} otherwise.
13874      */
setCountryCodes(boolean reset, List<String> currentNetworkCountryCodes, Map cachedNetworkCountryCodes, String locationCountryCode, long locationCountryCodeTimestampNanos)13875     public boolean setCountryCodes(boolean reset, List<String> currentNetworkCountryCodes,
13876             Map cachedNetworkCountryCodes, String locationCountryCode,
13877             long locationCountryCodeTimestampNanos) {
13878         Log.d(LOG_TAG, "setCountryCodes: currentNetworkCountryCodes="
13879                 + String.join(", ", currentNetworkCountryCodes)
13880                 + ", locationCountryCode=" + locationCountryCode
13881                 + ", locationCountryCodeTimestampNanos" + locationCountryCodeTimestampNanos
13882                 + ", reset=" + reset + ", cachedNetworkCountryCodes="
13883                 + String.join(", ", cachedNetworkCountryCodes.keySet()));
13884         TelephonyPermissions.enforceShellOnly(
13885                 Binder.getCallingUid(), "setCachedLocationCountryCode");
13886         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
13887                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
13888                 "setCachedLocationCountryCode");
13889         return TelephonyCountryDetector.getInstance(getDefaultPhone().getContext()).setCountryCodes(
13890                 reset, currentNetworkCountryCodes, cachedNetworkCountryCodes, locationCountryCode,
13891                 locationCountryCodeTimestampNanos);
13892     }
13893 
13894     /**
13895      * This API should be used by only CTS tests to override the overlay configs of satellite
13896      * access controller.
13897      *
13898      * @param reset {@code true} mean the overridden configs should not be used, {@code false}
13899      *              otherwise.
13900      * @return {@code true} if the overlay configs are set successfully, {@code false} otherwise.
13901      */
setSatelliteAccessControlOverlayConfigs(boolean reset, boolean isAllowed, String s2CellFile, long locationFreshDurationNanos, List<String> satelliteCountryCodes)13902     public boolean setSatelliteAccessControlOverlayConfigs(boolean reset, boolean isAllowed,
13903             String s2CellFile, long locationFreshDurationNanos,
13904             List<String> satelliteCountryCodes) {
13905         Log.d(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: reset=" + reset
13906                 + ", isAllowed" + isAllowed + ", s2CellFile=" + s2CellFile
13907                 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
13908                 + ", satelliteCountryCodes=" + ((satelliteCountryCodes != null)
13909                 ? String.join(", ", satelliteCountryCodes) : null));
13910         TelephonyPermissions.enforceShellOnly(
13911                 Binder.getCallingUid(), "setSatelliteAccessControlOverlayConfigs");
13912         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
13913                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
13914                 "setSatelliteAccessControlOverlayConfigs");
13915         return mSatelliteAccessController.setSatelliteAccessControlOverlayConfigs(reset, isAllowed,
13916                 s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
13917     }
13918 
13919     /**
13920      * This API can be used by only CTS to override the cached value for the device overlay config
13921      * value : config_send_satellite_datagram_to_modem_in_demo_mode, which determines whether
13922      * outgoing satellite datagrams should be sent to modem in demo mode.
13923      *
13924      * @param shouldSendToModemInDemoMode Whether send datagram in demo mode should be sent to
13925      * satellite modem or not.
13926      *
13927      * @return {@code true} if the operation is successful, {@code false} otherwise.
13928      */
setShouldSendDatagramToModemInDemoMode(boolean shouldSendToModemInDemoMode)13929     public boolean setShouldSendDatagramToModemInDemoMode(boolean shouldSendToModemInDemoMode) {
13930         if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
13931             Log.d(LOG_TAG, "shouldSendDatagramToModemInDemoMode: oemEnabledSatelliteFlag is "
13932                     + "disabled");
13933             return false;
13934         }
13935         Log.d(LOG_TAG, "setShouldSendDatagramToModemInDemoMode");
13936         TelephonyPermissions.enforceShellOnly(
13937                 Binder.getCallingUid(), "setShouldSendDatagramToModemInDemoMode");
13938         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
13939                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
13940                 "setShouldSendDatagramToModemInDemoMode");
13941         return mSatelliteController.setShouldSendDatagramToModemInDemoMode(
13942                 shouldSendToModemInDemoMode);
13943     }
13944 
13945     /**
13946      * This API can be used by only CTS to set the cache whether satellite communication is allowed.
13947      *
13948      * @param state a state indicates whether satellite access allowed state should be cached and
13949      * the allowed state.
13950      * @return {@code true} if the setting is successful, {@code false} otherwise.
13951      */
setIsSatelliteCommunicationAllowedForCurrentLocationCache(String state)13952     public boolean setIsSatelliteCommunicationAllowedForCurrentLocationCache(String state) {
13953         if (!mFeatureFlags.oemEnabledSatelliteFlag()) {
13954             Log.d(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache: "
13955                     + "oemEnabledSatelliteFlag is disabled");
13956             return false;
13957         }
13958 
13959         Log.d(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache: "
13960                 + "state=" + state);
13961         TelephonyPermissions.enforceShellOnly(
13962                 Binder.getCallingUid(),
13963                 "setIsSatelliteCommunicationAllowedForCurrentLocationCache");
13964         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
13965                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
13966                 "setIsSatelliteCommunicationAllowedForCurrentLocationCache");
13967         return mSatelliteAccessController.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
13968                 state);
13969     }
13970 
13971     /**
13972      * Sets the service defined in ComponentName to be bound.
13973      *
13974      * This should only be used for testing.
13975      * @return {@code true} if the DomainSelectionService to bind to was set,
13976      *         {@code false} otherwise.
13977      */
13978     @Override
setDomainSelectionServiceOverride(ComponentName componentName)13979     public boolean setDomainSelectionServiceOverride(ComponentName componentName) {
13980         Log.i(LOG_TAG, "setDomainSelectionServiceOverride component=" + componentName);
13981 
13982         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
13983                 "setDomainSelectionServiceOverride");
13984         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
13985                 getDefaultSubscription(), "setDomainSelectionServiceOverride");
13986 
13987         final long identity = Binder.clearCallingIdentity();
13988         try {
13989             if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
13990                 return DomainSelectionResolver.getInstance()
13991                         .setDomainSelectionServiceOverride(componentName);
13992             }
13993         } finally {
13994             Binder.restoreCallingIdentity(identity);
13995         }
13996         return false;
13997     }
13998 
13999     /**
14000      * Clears the DomainSelectionService override.
14001      *
14002      * This should only be used for testing.
14003      * @return {@code true} if the DomainSelectionService override was cleared,
14004      *         {@code false} otherwise.
14005      */
14006     @Override
clearDomainSelectionServiceOverride()14007     public boolean clearDomainSelectionServiceOverride() {
14008         Log.i(LOG_TAG, "clearDomainSelectionServiceOverride");
14009 
14010         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
14011                 "clearDomainSelectionServiceOverride");
14012         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14013                 getDefaultSubscription(), "clearDomainSelectionServiceOverride");
14014 
14015         final long identity = Binder.clearCallingIdentity();
14016         try {
14017             if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
14018                 return DomainSelectionResolver.getInstance()
14019                         .clearDomainSelectionServiceOverride();
14020             }
14021         } finally {
14022             Binder.restoreCallingIdentity(identity);
14023         }
14024         return false;
14025     }
14026 
14027     /**
14028      * Enable or disable notifications sent for cellular identifier disclosure events.
14029      *
14030      * Disclosure events are defined as instances where a device has sent a cellular identifier
14031      * on the Non-access stratum (NAS) before a security context is established. As a result the
14032      * identifier is sent in the clear, which has privacy implications for the user.
14033      *
14034      * @param enable if notifications about disclosure events should be enabled
14035      * @throws SecurityException             if the caller does not have the required privileges
14036      * @throws UnsupportedOperationException if the modem does not support this feature.
14037      */
14038     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setEnableCellularIdentifierDisclosureNotifications(boolean enable)14039     public void setEnableCellularIdentifierDisclosureNotifications(boolean enable) {
14040         enforceModifyPermission();
14041         checkForIdentifierDisclosureNotificationSupport();
14042 
14043         SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
14044         editor.putBoolean(Phone.PREF_IDENTIFIER_DISCLOSURE_NOTIFICATIONS_ENABLED, enable);
14045         editor.apply();
14046 
14047         // Each phone instance is responsible for updating its respective modem immediately
14048         // after we've made a preference change.
14049         for (Phone phone : PhoneFactory.getPhones()) {
14050             phone.handleIdentifierDisclosureNotificationPreferenceChange();
14051         }
14052     }
14053 
14054     /**
14055      * Get whether or not cellular identifier disclosure notifications are enabled.
14056      *
14057      * @throws SecurityException             if the caller does not have the required privileges
14058      * @throws UnsupportedOperationException if the modem does not support this feature.
14059      */
14060     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
isCellularIdentifierDisclosureNotificationsEnabled()14061     public boolean isCellularIdentifierDisclosureNotificationsEnabled() {
14062         enforceReadPrivilegedPermission("isCellularIdentifierDisclosureNotificationEnabled");
14063         checkForIdentifierDisclosureNotificationSupport();
14064         return getDefaultPhone().getIdentifierDisclosureNotificationsPreferenceEnabled();
14065     }
14066 
14067     /**
14068      * Enables or disables notifications sent when cellular null cipher or integrity algorithms
14069      * are in use by the cellular modem.
14070      *
14071      * @throws IllegalStateException if the Telephony process is not currently available
14072      * @throws SecurityException if the caller does not have the required privileges
14073      * @throws UnsupportedOperationException if the modem does not support reporting on ciphering
14074      * and integrity algorithms in use
14075      * @hide
14076      */
14077     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setNullCipherNotificationsEnabled(boolean enable)14078     public void setNullCipherNotificationsEnabled(boolean enable) {
14079         enforceModifyPermission();
14080         checkForNullCipherNotificationSupport();
14081 
14082         SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
14083         editor.putBoolean(Phone.PREF_NULL_CIPHER_NOTIFICATIONS_ENABLED, enable);
14084         editor.apply();
14085 
14086         // Each phone instance is responsible for updating its respective modem immediately
14087         // after a preference change.
14088         for (Phone phone : PhoneFactory.getPhones()) {
14089             phone.handleNullCipherNotificationPreferenceChanged();
14090         }
14091     }
14092 
14093     /**
14094      * Get whether notifications are enabled for null cipher or integrity algorithms in use by the
14095      * cellular modem.
14096      *
14097      * @throws IllegalStateException if the Telephony process is not currently available
14098      * @throws SecurityException if the caller does not have the required privileges
14099      * @throws UnsupportedOperationException if the modem does not support reporting on ciphering
14100      * and integrity algorithms in use
14101      * @hide
14102      */
14103     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
isNullCipherNotificationsEnabled()14104     public boolean isNullCipherNotificationsEnabled() {
14105         enforceReadPrivilegedPermission("isNullCipherNotificationsEnabled");
14106         checkForNullCipherNotificationSupport();
14107         return getDefaultPhone().getNullCipherNotificationsPreferenceEnabled();
14108     }
14109 
14110     /**
14111      * Check whether the caller (or self, if not processing an IPC) can read device identifiers.
14112      *
14113      * <p>This method behaves in one of the following ways:
14114      * <ul>
14115      *     <li>return true : if the calling package has the appop permission {@link
14116      *     Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER} in the manifest </>
14117      *     <li>return true : if any one subscription has the READ_PRIVILEGED_PHONE_STATE
14118      *     permission, the calling package passes a DevicePolicyManager Device Owner / Profile
14119      *     Owner device identifier access check, or the calling package has carrier privileges</>
14120      *     <li>throw SecurityException: if the caller does not meet any of the requirements.
14121      * </ul>
14122      */
checkCallingOrSelfReadDeviceIdentifiersForAnySub(Context context, String callingPackage, @Nullable String callingFeatureId, String message)14123     private static boolean checkCallingOrSelfReadDeviceIdentifiersForAnySub(Context context,
14124             String callingPackage, @Nullable String callingFeatureId, String message) {
14125         for (Phone phone : PhoneFactory.getPhones()) {
14126             if (TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(context,
14127                     phone.getSubId(), callingPackage, callingFeatureId, message)) {
14128                 return true;
14129             }
14130         }
14131         return false;
14132     }
14133 
14134     /**
14135      * @return The subscription manager service instance.
14136      */
getSubscriptionManagerService()14137     public SubscriptionManagerService getSubscriptionManagerService() {
14138         return SubscriptionManagerService.getInstance();
14139     }
14140 
14141     /**
14142      * Class binds the consumer[callback] and carrierId.
14143      */
14144     private static class CallerCallbackInfo {
14145         private final Consumer<Integer> mConsumer;
14146         private final Set<Integer> mCarrierIds;
14147 
CallerCallbackInfo(Consumer<Integer> consumer, Set<Integer> carrierIds)14148         public CallerCallbackInfo(Consumer<Integer> consumer, Set<Integer> carrierIds) {
14149             mConsumer = consumer;
14150             mCarrierIds = carrierIds;
14151         }
14152 
getConsumer()14153         public Consumer<Integer> getConsumer() {
14154             return mConsumer;
14155         }
14156 
getCarrierIds()14157         public Set<Integer> getCarrierIds() {
14158             return mCarrierIds;
14159         }
14160     }
14161 
14162     /*
14163     * PhoneInterfaceManager is a singleton. Unit test calls the init() with context.
14164     * But the context that is passed in is unused if the phone app is already alive.
14165     * In this case PackageManager object is different in PhoneInterfaceManager and Unit test.
14166     */
14167     @VisibleForTesting
setPackageManager(PackageManager packageManager)14168     public void setPackageManager(PackageManager packageManager) {
14169         mPackageManager = packageManager;
14170     }
14171 
14172     /*
14173      * PhoneInterfaceManager is a singleton. Unit test calls the init() with context.
14174      * But the context that is passed in is unused if the phone app is already alive.
14175      * In this case PackageManager object is different in PhoneInterfaceManager and Unit test.
14176      */
14177     @VisibleForTesting
setAppOpsManager(AppOpsManager appOps)14178     public void setAppOpsManager(AppOpsManager appOps) {
14179         mAppOps = appOps;
14180     }
14181 
14182     /*
14183      * PhoneInterfaceManager is a singleton. Unit test calls the init() with FeatureFlags.
14184      * But the FeatureFlags that is passed in is unused if the phone app is already alive.
14185      * In this case FeatureFlags object is different in PhoneInterfaceManager and Unit test.
14186      */
14187     @VisibleForTesting
setFeatureFlags(FeatureFlags featureFlags)14188     public void setFeatureFlags(FeatureFlags featureFlags) {
14189         mFeatureFlags = featureFlags;
14190     }
14191 
14192     /**
14193      * Make sure the device has required telephony feature
14194      *
14195      * @throws UnsupportedOperationException if the device does not have required telephony feature
14196      */
enforceTelephonyFeatureWithException(@ullable String callingPackage, @NonNull String telephonyFeature, @NonNull String methodName)14197     private void enforceTelephonyFeatureWithException(@Nullable String callingPackage,
14198             @NonNull String telephonyFeature, @NonNull String methodName) {
14199         if (callingPackage == null || mPackageManager == null) {
14200             return;
14201         }
14202 
14203         if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis()
14204                 || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, callingPackage,
14205                 Binder.getCallingUserHandle())
14206                 || mVendorApiLevel < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
14207             // Skip to check associated telephony feature,
14208             // if compatibility change is not enabled for the current process or
14209             // the SDK version of vendor partition is less than Android V.
14210             return;
14211         }
14212 
14213         if (!mPackageManager.hasSystemFeature(telephonyFeature)) {
14214             throw new UnsupportedOperationException(
14215                     methodName + " is unsupported without " + telephonyFeature);
14216         }
14217     }
14218 
14219     /**
14220      * Registers for the satellite communication allowed state changed.
14221      *
14222      * @param subId The subId of the subscription to register for the satellite communication
14223      *              allowed state changed.
14224      * @param callback The callback to handle the satellite communication allowed
14225      *                 state changed event.
14226      *
14227      * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
14228      *
14229      * @throws SecurityException if the caller doesn't have the required permission.
14230      */
14231     @Override
registerForCommunicationAllowedStateChanged( int subId, @NonNull ISatelliteCommunicationAllowedStateCallback callback)14232     @SatelliteManager.SatelliteResult public int registerForCommunicationAllowedStateChanged(
14233             int subId, @NonNull ISatelliteCommunicationAllowedStateCallback callback) {
14234         enforceSatelliteCommunicationPermission("registerForCommunicationAllowedStateChanged");
14235         return mSatelliteAccessController.registerForCommunicationAllowedStateChanged(
14236                 subId, callback);
14237     }
14238 
14239     /**
14240      * Unregisters for the satellite communication allowed state changed.
14241      * If callback was not registered before, the request will be ignored.
14242      *
14243      * @param subId    The subId of the subscription to unregister for the satellite communication
14244      *                 allowed state changed.
14245      * @param callback The callback that was passed to
14246      *                 {@link #registerForCommunicationAllowedStateChanged(int,
14247      *                 ISatelliteCommunicationAllowedStateCallback)}.     *
14248      * @throws SecurityException if the caller doesn't have the required permission.
14249      */
14250     @Override
unregisterForCommunicationAllowedStateChanged( int subId, @NonNull ISatelliteCommunicationAllowedStateCallback callback)14251     public void unregisterForCommunicationAllowedStateChanged(
14252             int subId, @NonNull ISatelliteCommunicationAllowedStateCallback callback) {
14253         enforceSatelliteCommunicationPermission("unregisterForCommunicationAllowedStateChanged");
14254         mSatelliteAccessController.unregisterForCommunicationAllowedStateChanged(subId, callback);
14255     }
14256 
14257     /**
14258      * Request to get the {@link SatelliteSessionStats} of the satellite service.
14259      *
14260      * @param subId The subId of the subscription to the satellite session stats for.
14261      * @param result The result receiver that returns the {@link SatelliteSessionStats}
14262      *               if the request is successful or an error code if the request failed.
14263      *
14264      * @throws SecurityException if the caller doesn't have required permission.
14265      */
14266     @Override
requestSatelliteSessionStats(int subId, @NonNull ResultReceiver result)14267     public void requestSatelliteSessionStats(int subId, @NonNull ResultReceiver result) {
14268         enforceModifyPermission();
14269         enforcePackageUsageStatsPermission("requestSatelliteSessionStats");
14270         mSatelliteController.requestSatelliteSessionStats(subId, result);
14271     }
14272 }
14273