• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.phone;
18 
19 import static android.content.pm.PackageManager.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_DISALLOWED_REASON_NOT_PROVISIONED;
28 import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_NOT_SUPPORTED;
29 import static android.telephony.satellite.SatelliteManager.SATELLITE_DISALLOWED_REASON_UNSUPPORTED_DEFAULT_MSG_APP;
30 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_ACCESS_BARRED;
31 import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;
32 
33 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_CDMA;
34 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_GSM;
35 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_IMS;
36 import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
37 import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT;
38 
39 import android.Manifest;
40 import android.Manifest.permission;
41 import android.annotation.NonNull;
42 import android.annotation.Nullable;
43 import android.annotation.RequiresPermission;
44 import android.app.ActivityManager;
45 import android.app.AppOpsManager;
46 import android.app.PendingIntent;
47 import android.app.PropertyInvalidatedCache;
48 import android.app.compat.CompatChanges;
49 import android.app.role.RoleManager;
50 import android.compat.annotation.ChangeId;
51 import android.compat.annotation.EnabledSince;
52 import android.content.ActivityNotFoundException;
53 import android.content.ComponentName;
54 import android.content.ContentResolver;
55 import android.content.Context;
56 import android.content.Intent;
57 import android.content.SharedPreferences;
58 import android.content.pm.ComponentInfo;
59 import android.content.pm.PackageManager;
60 import android.net.Uri;
61 import android.os.AsyncResult;
62 import android.os.Binder;
63 import android.os.Build;
64 import android.os.Bundle;
65 import android.os.DropBoxManager;
66 import android.os.Handler;
67 import android.os.IBinder;
68 import android.os.ICancellationSignal;
69 import android.os.LocaleList;
70 import android.os.Looper;
71 import android.os.Message;
72 import android.os.Messenger;
73 import android.os.ParcelFileDescriptor;
74 import android.os.ParcelUuid;
75 import android.os.PersistableBundle;
76 import android.os.Process;
77 import android.os.RemoteException;
78 import android.os.ResultReceiver;
79 import android.os.ServiceSpecificException;
80 import android.os.SystemClock;
81 import android.os.SystemProperties;
82 import android.os.UserHandle;
83 import android.os.UserManager;
84 import android.os.WorkSource;
85 import android.preference.PreferenceManager;
86 import android.provider.DeviceConfig;
87 import android.provider.Settings;
88 import android.provider.Telephony;
89 import android.service.carrier.CarrierIdentifier;
90 import android.sysprop.TelephonyProperties;
91 import android.telecom.PhoneAccount;
92 import android.telecom.PhoneAccountHandle;
93 import android.telecom.TelecomManager;
94 import android.telephony.AccessNetworkConstants;
95 import android.telephony.ActivityStatsTechSpecificInfo;
96 import android.telephony.Annotation.ApnType;
97 import android.telephony.Annotation.DataActivityType;
98 import android.telephony.Annotation.ThermalMitigationResult;
99 import android.telephony.AnomalyReporter;
100 import android.telephony.CallForwardingInfo;
101 import android.telephony.CarrierConfigManager;
102 import android.telephony.CarrierRestrictionRules;
103 import android.telephony.CellBroadcastIdRange;
104 import android.telephony.CellIdentity;
105 import android.telephony.CellIdentityCdma;
106 import android.telephony.CellIdentityGsm;
107 import android.telephony.CellInfo;
108 import android.telephony.CellInfoGsm;
109 import android.telephony.CellInfoWcdma;
110 import android.telephony.ClientRequestStats;
111 import android.telephony.DataThrottlingRequest;
112 import android.telephony.IBootstrapAuthenticationCallback;
113 import android.telephony.ICellInfoCallback;
114 import android.telephony.IccOpenLogicalChannelResponse;
115 import android.telephony.LocationAccessPolicy;
116 import android.telephony.ModemActivityInfo;
117 import android.telephony.NeighboringCellInfo;
118 import android.telephony.NetworkScanRequest;
119 import android.telephony.PhoneCapability;
120 import android.telephony.PhoneNumberRange;
121 import android.telephony.RadioAccessFamily;
122 import android.telephony.RadioAccessSpecifier;
123 import android.telephony.ServiceState;
124 import android.telephony.SignalStrength;
125 import android.telephony.SignalStrengthUpdateRequest;
126 import android.telephony.SignalThresholdInfo;
127 import android.telephony.SubscriptionInfo;
128 import android.telephony.SubscriptionManager;
129 import android.telephony.TelephonyFrameworkInitializer;
130 import android.telephony.TelephonyHistogram;
131 import android.telephony.TelephonyManager;
132 import android.telephony.TelephonyManager.SimState;
133 import android.telephony.TelephonyScanManager;
134 import android.telephony.ThermalMitigationRequest;
135 import android.telephony.UiccCardInfo;
136 import android.telephony.UiccPortInfo;
137 import android.telephony.UiccSlotInfo;
138 import android.telephony.UiccSlotMapping;
139 import android.telephony.UssdResponse;
140 import android.telephony.VisualVoicemailSmsFilterSettings;
141 import android.telephony.data.NetworkSlicingConfig;
142 import android.telephony.emergency.EmergencyNumber;
143 import android.telephony.gba.GbaAuthRequest;
144 import android.telephony.gba.UaSecurityProtocolIdentifier;
145 import android.telephony.ims.ImsException;
146 import android.telephony.ims.ProvisioningManager;
147 import android.telephony.ims.RcsClientConfiguration;
148 import android.telephony.ims.RcsContactUceCapability;
149 import android.telephony.ims.RegistrationManager;
150 import android.telephony.ims.aidl.IFeatureProvisioningCallback;
151 import android.telephony.ims.aidl.IImsCapabilityCallback;
152 import android.telephony.ims.aidl.IImsConfig;
153 import android.telephony.ims.aidl.IImsConfigCallback;
154 import android.telephony.ims.aidl.IImsRegistration;
155 import android.telephony.ims.aidl.IImsRegistrationCallback;
156 import android.telephony.ims.aidl.IRcsConfigCallback;
157 import android.telephony.ims.feature.ImsFeature;
158 import android.telephony.ims.stub.ImsConfigImplBase;
159 import android.telephony.ims.stub.ImsRegistrationImplBase;
160 import android.telephony.satellite.INtnSignalStrengthCallback;
161 import android.telephony.satellite.ISatelliteCapabilitiesCallback;
162 import android.telephony.satellite.ISatelliteCommunicationAccessStateCallback;
163 import android.telephony.satellite.ISatelliteDatagramCallback;
164 import android.telephony.satellite.ISatelliteDisallowedReasonsCallback;
165 import android.telephony.satellite.ISatelliteModemStateCallback;
166 import android.telephony.satellite.ISatelliteProvisionStateCallback;
167 import android.telephony.satellite.ISatelliteTransmissionUpdateCallback;
168 import android.telephony.satellite.ISelectedNbIotSatelliteSubscriptionCallback;
169 import android.telephony.satellite.NtnSignalStrength;
170 import android.telephony.satellite.NtnSignalStrengthCallback;
171 import android.telephony.satellite.SatelliteCapabilities;
172 import android.telephony.satellite.SatelliteDatagram;
173 import android.telephony.satellite.SatelliteDatagramCallback;
174 import android.telephony.satellite.SatelliteManager;
175 import android.telephony.satellite.SatelliteProvisionStateCallback;
176 import android.telephony.satellite.SatelliteSubscriberInfo;
177 import android.text.TextUtils;
178 import android.util.ArraySet;
179 import android.util.EventLog;
180 import android.util.Log;
181 import android.util.Pair;
182 
183 import com.android.ims.ImsManager;
184 import com.android.ims.internal.IImsServiceFeatureCallback;
185 import com.android.ims.rcs.uce.eab.EabUtil;
186 import com.android.internal.annotations.VisibleForTesting;
187 import com.android.internal.telephony.CallForwardInfo;
188 import com.android.internal.telephony.CallManager;
189 import com.android.internal.telephony.CallStateException;
190 import com.android.internal.telephony.CallTracker;
191 import com.android.internal.telephony.CarrierPrivilegesTracker;
192 import com.android.internal.telephony.CarrierResolver;
193 import com.android.internal.telephony.CellNetworkScanResult;
194 import com.android.internal.telephony.CommandException;
195 import com.android.internal.telephony.CommandsInterface;
196 import com.android.internal.telephony.GbaManager;
197 import com.android.internal.telephony.GsmCdmaPhone;
198 import com.android.internal.telephony.HalVersion;
199 import com.android.internal.telephony.IBooleanConsumer;
200 import com.android.internal.telephony.ICallForwardingInfoCallback;
201 import com.android.internal.telephony.IImsStateCallback;
202 import com.android.internal.telephony.IIntegerConsumer;
203 import com.android.internal.telephony.INumberVerificationCallback;
204 import com.android.internal.telephony.ITelephony;
205 import com.android.internal.telephony.IccCard;
206 import com.android.internal.telephony.IccCardConstants;
207 import com.android.internal.telephony.IccLogicalChannelRequest;
208 import com.android.internal.telephony.LocaleTracker;
209 import com.android.internal.telephony.NetworkScanRequestTracker;
210 import com.android.internal.telephony.OperatorInfo;
211 import com.android.internal.telephony.Phone;
212 import com.android.internal.telephony.PhoneConfigurationManager;
213 import com.android.internal.telephony.PhoneConstantConversions;
214 import com.android.internal.telephony.PhoneConstants;
215 import com.android.internal.telephony.PhoneFactory;
216 import com.android.internal.telephony.ProxyController;
217 import com.android.internal.telephony.RIL;
218 import com.android.internal.telephony.RILConstants;
219 import com.android.internal.telephony.RadioInterfaceCapabilityController;
220 import com.android.internal.telephony.ServiceStateTracker;
221 import com.android.internal.telephony.SmsApplication;
222 import com.android.internal.telephony.SmsController;
223 import com.android.internal.telephony.SmsPermissions;
224 import com.android.internal.telephony.TelephonyCountryDetector;
225 import com.android.internal.telephony.TelephonyIntents;
226 import com.android.internal.telephony.TelephonyPermissions;
227 import com.android.internal.telephony.configupdate.TelephonyConfigUpdateInstallReceiver;
228 import com.android.internal.telephony.data.DataUtils;
229 import com.android.internal.telephony.domainselection.DomainSelectionResolver;
230 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
231 import com.android.internal.telephony.euicc.EuiccConnector;
232 import com.android.internal.telephony.flags.FeatureFlags;
233 import com.android.internal.telephony.ims.ImsResolver;
234 import com.android.internal.telephony.imsphone.ImsPhone;
235 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
236 import com.android.internal.telephony.metrics.RcsStats;
237 import com.android.internal.telephony.metrics.TelephonyMetrics;
238 import com.android.internal.telephony.satellite.SatelliteController;
239 import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
240 import com.android.internal.telephony.subscription.SubscriptionManagerService;
241 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
242 import com.android.internal.telephony.uicc.IccIoResult;
243 import com.android.internal.telephony.uicc.IccUtils;
244 import com.android.internal.telephony.uicc.SIMRecords;
245 import com.android.internal.telephony.uicc.UiccCard;
246 import com.android.internal.telephony.uicc.UiccCardApplication;
247 import com.android.internal.telephony.uicc.UiccController;
248 import com.android.internal.telephony.uicc.UiccPort;
249 import com.android.internal.telephony.uicc.UiccProfile;
250 import com.android.internal.telephony.uicc.UiccSlot;
251 import com.android.internal.telephony.util.LocaleUtils;
252 import com.android.internal.telephony.util.TelephonyUtils;
253 import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
254 import com.android.internal.util.FunctionalUtils;
255 import com.android.internal.util.HexDump;
256 import com.android.phone.callcomposer.CallComposerPictureManager;
257 import com.android.phone.callcomposer.CallComposerPictureTransfer;
258 import com.android.phone.callcomposer.ImageData;
259 import com.android.phone.satellite.accesscontrol.SatelliteAccessController;
260 import com.android.phone.satellite.entitlement.SatelliteEntitlementController;
261 import com.android.phone.settings.PickSmsSubscriptionActivity;
262 import com.android.phone.slice.SlicePurchaseController;
263 import com.android.phone.utils.CarrierAllowListInfo;
264 import com.android.phone.vvm.PhoneAccountHandleConverter;
265 import com.android.phone.vvm.RemoteVvmTaskManager;
266 import com.android.phone.vvm.VisualVoicemailSettingsUtil;
267 import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
268 import com.android.server.feature.flags.Flags;
269 import com.android.services.telephony.TelecomAccountRegistry;
270 import com.android.services.telephony.TelephonyConnectionService;
271 import com.android.services.telephony.domainselection.TelephonyDomainSelectionService;
272 import com.android.telephony.Rlog;
273 
274 import java.io.ByteArrayOutputStream;
275 import java.io.FileDescriptor;
276 import java.io.IOException;
277 import java.io.InputStream;
278 import java.io.PrintWriter;
279 import java.util.ArrayList;
280 import java.util.Arrays;
281 import java.util.Collection;
282 import java.util.Collections;
283 import java.util.HashMap;
284 import java.util.HashSet;
285 import java.util.List;
286 import java.util.Locale;
287 import java.util.Map;
288 import java.util.NoSuchElementException;
289 import java.util.Objects;
290 import java.util.Set;
291 import java.util.UUID;
292 import java.util.concurrent.Executors;
293 import java.util.concurrent.atomic.AtomicBoolean;
294 import java.util.function.Consumer;
295 
296 /**
297  * Implementation of the ITelephony interface.
298  */
299 public class PhoneInterfaceManager extends ITelephony.Stub {
300     private static final String LOG_TAG = "PhoneInterfaceManager";
301     private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
302     private static final boolean DBG_LOC = false;
303     private static final boolean DBG_MERGE = false;
304 
305     // Message codes used with mMainThreadHandler
306     private static final int CMD_HANDLE_PIN_MMI = 1;
307     private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
308     private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
309     private static final int CMD_OPEN_CHANNEL = 9;
310     private static final int EVENT_OPEN_CHANNEL_DONE = 10;
311     private static final int CMD_CLOSE_CHANNEL = 11;
312     private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
313     private static final int CMD_NV_READ_ITEM = 13;
314     private static final int EVENT_NV_READ_ITEM_DONE = 14;
315     private static final int CMD_NV_WRITE_ITEM = 15;
316     private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
317     private static final int CMD_NV_WRITE_CDMA_PRL = 17;
318     private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
319     private static final int CMD_RESET_MODEM_CONFIG = 19;
320     private static final int EVENT_RESET_MODEM_CONFIG_DONE = 20;
321     private static final int CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK = 21;
322     private static final int EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE = 22;
323     private static final int CMD_SEND_ENVELOPE = 25;
324     private static final int EVENT_SEND_ENVELOPE_DONE = 26;
325     private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
326     private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
327     private static final int CMD_EXCHANGE_SIM_IO = 31;
328     private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
329     private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
330     private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
331     private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
332     private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
333     private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
334     private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
335     private static final int CMD_PERFORM_NETWORK_SCAN = 39;
336     private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
337     private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
338     private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
339     private static final int CMD_SET_ALLOWED_CARRIERS = 43;
340     private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
341     private static final int CMD_GET_ALLOWED_CARRIERS = 45;
342     private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
343     private static final int CMD_HANDLE_USSD_REQUEST = 47;
344     private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
345     private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
346     private static final int CMD_SWITCH_SLOTS = 50;
347     private static final int EVENT_SWITCH_SLOTS_DONE = 51;
348     private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
349     private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
350     private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
351     private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
352     private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
353     private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
354     private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
355     private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
356     private static final int CMD_GET_ALL_CELL_INFO = 60;
357     private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
358     private static final int CMD_GET_CELL_LOCATION = 62;
359     private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
360     private static final int CMD_MODEM_REBOOT = 64;
361     private static final int EVENT_CMD_MODEM_REBOOT_DONE = 65;
362     private static final int CMD_REQUEST_CELL_INFO_UPDATE = 66;
363     private static final int EVENT_REQUEST_CELL_INFO_UPDATE_DONE = 67;
364     private static final int CMD_REQUEST_ENABLE_MODEM = 68;
365     private static final int EVENT_ENABLE_MODEM_DONE = 69;
366     private static final int CMD_GET_MODEM_STATUS = 70;
367     private static final int EVENT_GET_MODEM_STATUS_DONE = 71;
368     private static final int CMD_SET_FORBIDDEN_PLMNS = 72;
369     private static final int EVENT_SET_FORBIDDEN_PLMNS_DONE = 73;
370     private static final int CMD_ERASE_MODEM_CONFIG = 74;
371     private static final int EVENT_ERASE_MODEM_CONFIG_DONE = 75;
372     private static final int CMD_CHANGE_ICC_LOCK_PASSWORD = 76;
373     private static final int EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE = 77;
374     private static final int CMD_SET_ICC_LOCK_ENABLED = 78;
375     private static final int EVENT_SET_ICC_LOCK_ENABLED_DONE = 79;
376     private static final int CMD_SET_SYSTEM_SELECTION_CHANNELS = 80;
377     private static final int EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE = 81;
378     private static final int MSG_NOTIFY_USER_ACTIVITY = 82;
379     private static final int CMD_GET_CALL_FORWARDING = 83;
380     private static final int EVENT_GET_CALL_FORWARDING_DONE = 84;
381     private static final int CMD_SET_CALL_FORWARDING = 85;
382     private static final int EVENT_SET_CALL_FORWARDING_DONE = 86;
383     private static final int CMD_GET_CALL_WAITING = 87;
384     private static final int EVENT_GET_CALL_WAITING_DONE = 88;
385     private static final int CMD_SET_CALL_WAITING = 89;
386     private static final int EVENT_SET_CALL_WAITING_DONE = 90;
387     private static final int CMD_ENABLE_NR_DUAL_CONNECTIVITY = 91;
388     private static final int EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE = 92;
389     private static final int CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED = 93;
390     private static final int EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE = 94;
391     private static final int CMD_GET_CDMA_SUBSCRIPTION_MODE = 95;
392     private static final int EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE = 96;
393     private static final int CMD_GET_SYSTEM_SELECTION_CHANNELS = 97;
394     private static final int EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE = 98;
395     private static final int CMD_SET_DATA_THROTTLING = 99;
396     private static final int EVENT_SET_DATA_THROTTLING_DONE = 100;
397     private static final int CMD_SET_SIM_POWER = 101;
398     private static final int EVENT_SET_SIM_POWER_DONE = 102;
399     private static final int CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST = 103;
400     private static final int EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE = 104;
401     private static final int CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST = 105;
402     private static final int EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE = 106;
403     private static final int CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON = 107;
404     private static final int EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE = 108;
405     private static final int CMD_PREPARE_UNATTENDED_REBOOT = 109;
406     private static final int CMD_GET_SLICING_CONFIG = 110;
407     private static final int EVENT_GET_SLICING_CONFIG_DONE = 111;
408     private static final int CMD_ERASE_DATA_SHARED_PREFERENCES = 112;
409     private static final int CMD_ENABLE_VONR = 113;
410     private static final int EVENT_ENABLE_VONR_DONE = 114;
411     private static final int CMD_IS_VONR_ENABLED = 115;
412     private static final int EVENT_IS_VONR_ENABLED_DONE = 116;
413     private static final int CMD_PURCHASE_PREMIUM_CAPABILITY = 117;
414     private static final int EVENT_PURCHASE_PREMIUM_CAPABILITY_DONE = 118;
415 
416     // Parameters of select command.
417     private static final int SELECT_COMMAND = 0xA4;
418     private static final int SELECT_P1 = 0x04;
419     private static final int SELECT_P2 = 0;
420     private static final int SELECT_P3 = 0x10;
421 
422     // Toggling null cipher and integrity support was added in IRadioNetwork 2.1
423     private static final int MIN_NULL_CIPHER_AND_INTEGRITY_VERSION = 201;
424     // Cellular identifier disclosure transparency was added in IRadioNetwork 2.2
425     private static final int MIN_IDENTIFIER_DISCLOSURE_VERSION = 202;
426     // Null cipher notification support was added in IRadioNetwork 2.2
427     private static final int MIN_NULL_CIPHER_NOTIFICATION_VERSION = 202;
428 
429     /** The singleton instance. */
430     private static PhoneInterfaceManager sInstance;
431     private static List<String> sThermalMitigationAllowlistedPackages = new ArrayList<>();
432 
433     private final PhoneGlobals mApp;
434     private FeatureFlags mFeatureFlags;
435     private com.android.server.telecom.flags.FeatureFlags mTelecomFeatureFlags;
436     private final CallManager mCM;
437     private final ImsResolver mImsResolver;
438 
439     private final SatelliteController mSatelliteController;
440     private final SatelliteAccessController mSatelliteAccessController;
441     private final UserManager mUserManager;
442     private final MainThreadHandler mMainThreadHandler;
443     private final SharedPreferences mTelephonySharedPreferences;
444     private final PhoneConfigurationManager mPhoneConfigurationManager;
445     private final RadioInterfaceCapabilityController mRadioInterfaceCapabilities;
446     private AppOpsManager mAppOps;
447     private PackageManager mPackageManager;
448     private final int mVendorApiLevel;
449 
450     @Nullable
451     private ComponentName mTestEuiccUiComponent;
452 
453     /** User Activity */
454     private final AtomicBoolean mNotifyUserActivity;
455     private static final int USER_ACTIVITY_NOTIFICATION_DELAY = 200;
456     private final Set<Integer> mCarrierPrivilegeTestOverrideSubIds = new ArraySet<>();
457 
458     private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
459     private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
460     private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
461     private static final String PREF_PROVISION_IMS_MMTEL_PREFIX = "provision_ims_mmtel_";
462 
463     // String to store multi SIM allowed
464     private static final String PREF_MULTI_SIM_RESTRICTED = "multisim_restricted";
465 
466     // The AID of ISD-R.
467     private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
468 
469     private NetworkScanRequestTracker mNetworkScanRequestTracker;
470 
471     private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
472     private static final int MANUFACTURER_CODE_LENGTH = 8;
473 
474     private static final int SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS = -1;
475     private static final int MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE = -2;
476 
477     private static final String PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID =
478             "24bf97a6-e8a6-44d8-a6a4-255d7548733c";
479 
480     /**
481      * Experiment flag to enable erase modem config on reset network, default value is false
482      */
483     public static final String RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED =
484             "reset_network_erase_modem_config_enabled";
485 
486     private static final int BLOCKING_REQUEST_DEFAULT_TIMEOUT_MS = 2000; // 2 seconds
487 
488     private static final int MODEM_ACTIVITY_TIME_OFFSET_CORRECTION_MS = 50;
489 
490     private static final int LINE1_NUMBER_MAX_LEN = 50;
491 
492     /**
493      * With support for MEP(multiple enabled profile) in Android T, a SIM card can have more than
494      * one ICCID active at the same time.
495      * Apps should use below API signatures if targeting SDK is T and beyond.
496      *
497      * @hide
498      */
499     @ChangeId
500     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
501     public static final long GET_API_SIGNATURES_FROM_UICC_PORT_INFO = 202110963L;
502 
503     /**
504      * Apps targeting on Android T and beyond will get exception whenever icc close channel
505      * operation fails.
506      */
507     @ChangeId
508     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
509     public static final long ICC_CLOSE_CHANNEL_EXCEPTION_ON_FAILURE = 208739934L;
510 
511     /**
512      * A request object to use for transmitting data to an ICC.
513      */
514     private static final class IccAPDUArgument {
515         public int channel, cla, command, p1, p2, p3;
516         public String data;
517 
IccAPDUArgument(int channel, int cla, int command, int p1, int p2, int p3, String data)518         public IccAPDUArgument(int channel, int cla, int command,
519                 int p1, int p2, int p3, String data) {
520             this.channel = channel;
521             this.cla = cla;
522             this.command = command;
523             this.p1 = p1;
524             this.p2 = p2;
525             this.p3 = p3;
526             this.data = data;
527         }
528     }
529 
530     /**
531      * A request object to use for transmitting data to an ICC.
532      */
533     private static final class ManualNetworkSelectionArgument {
534         public OperatorInfo operatorInfo;
535         public boolean persistSelection;
536 
ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection)537         public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
538             this.operatorInfo = operatorInfo;
539             this.persistSelection = persistSelection;
540         }
541     }
542 
543     private static final class PurchasePremiumCapabilityArgument {
544         public @TelephonyManager.PremiumCapability int capability;
545         public @NonNull IIntegerConsumer callback;
546 
PurchasePremiumCapabilityArgument(@elephonyManager.PremiumCapability int capability, @NonNull IIntegerConsumer callback)547         PurchasePremiumCapabilityArgument(@TelephonyManager.PremiumCapability int capability,
548                 @NonNull IIntegerConsumer callback) {
549             this.capability = capability;
550             this.callback = callback;
551         }
552     }
553 
554     /**
555      * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
556      * request after sending. The main thread will notify the request when it is complete.
557      */
558     private static final class MainThreadRequest {
559         /** The argument to use for the request */
560         public Object argument;
561         /** The result of the request that is run on the main thread */
562         public Object result;
563         // The subscriber id that this request applies to. Defaults to
564         // SubscriptionManager.INVALID_SUBSCRIPTION_ID
565         public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
566 
567         // In cases where subId is unavailable, the caller needs to specify the phone.
568         public Phone phone;
569 
570         public WorkSource workSource;
571 
MainThreadRequest(Object argument)572         public MainThreadRequest(Object argument) {
573             this.argument = argument;
574         }
575 
MainThreadRequest(Object argument, Phone phone, WorkSource workSource)576         MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
577             this.argument = argument;
578             if (phone != null) {
579                 this.phone = phone;
580             }
581             this.workSource = workSource;
582         }
583 
MainThreadRequest(Object argument, Integer subId, WorkSource workSource)584         MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
585             this.argument = argument;
586             if (subId != null) {
587                 this.subId = subId;
588             }
589             this.workSource = workSource;
590         }
591     }
592 
593     private static final class IncomingThirdPartyCallArgs {
594         public final ComponentName component;
595         public final String callId;
596         public final String callerDisplayName;
597 
IncomingThirdPartyCallArgs(ComponentName component, String callId, String callerDisplayName)598         public IncomingThirdPartyCallArgs(ComponentName component, String callId,
599                 String callerDisplayName) {
600             this.component = component;
601             this.callId = callId;
602             this.callerDisplayName = callerDisplayName;
603         }
604     }
605 
606     /**
607      * A handler that processes messages on the main thread in the phone process. Since many
608      * of the Phone calls are not thread safe this is needed to shuttle the requests from the
609      * inbound binder threads to the main thread in the phone process.  The Binder thread
610      * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
611      * on, which will be notified when the operation completes and will contain the result of the
612      * request.
613      *
614      * <p>If a MainThreadRequest object is provided in the msg.obj field,
615      * note that request.result must be set to something non-null for the calling thread to
616      * unblock.
617      */
618     private final class MainThreadHandler extends Handler {
619         @Override
handleMessage(Message msg)620         public void handleMessage(Message msg) {
621             MainThreadRequest request;
622             Message onCompleted;
623             AsyncResult ar;
624             UiccPort uiccPort;
625             IccAPDUArgument iccArgument;
626             final Phone defaultPhone = getDefaultPhone();
627 
628             switch (msg.what) {
629                 case CMD_HANDLE_USSD_REQUEST: {
630                     request = (MainThreadRequest) msg.obj;
631                     final Phone phone = getPhoneFromRequest(request);
632                     Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
633                     String ussdRequest = ussdObject.first;
634                     ResultReceiver wrappedCallback = ussdObject.second;
635 
636                     if (!isUssdApiAllowed(request.subId)) {
637                         // Carrier does not support use of this API, return failure.
638                         Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
639                         UssdResponse response = new UssdResponse(ussdRequest, null);
640                         Bundle returnData = new Bundle();
641                         returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
642                         wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
643 
644                         request.result = true;
645                         notifyRequester(request);
646                         return;
647                     }
648 
649                     try {
650                         request.result = phone != null
651                                 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
652                     } catch (CallStateException cse) {
653                         request.result = false;
654                     }
655                     // Wake up the requesting thread
656                     notifyRequester(request);
657                     break;
658                 }
659 
660                 case CMD_HANDLE_PIN_MMI: {
661                     request = (MainThreadRequest) msg.obj;
662                     final Phone phone = getPhoneFromRequest(request);
663                     request.result = phone != null ?
664                             getPhoneFromRequest(request).handlePinMmi((String) request.argument)
665                             : false;
666                     // Wake up the requesting thread
667                     notifyRequester(request);
668                     break;
669                 }
670 
671                 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
672                     request = (MainThreadRequest) msg.obj;
673                     iccArgument = (IccAPDUArgument) request.argument;
674                     uiccPort = getUiccPortFromRequest(request);
675                     if (uiccPort == null) {
676                         loge("iccTransmitApduLogicalChannel: No UICC");
677                         request.result = new IccIoResult(0x6F, 0, (byte[]) null);
678                         notifyRequester(request);
679                     } else {
680                         onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
681                                 request);
682                         uiccPort.iccTransmitApduLogicalChannel(
683                                 iccArgument.channel, iccArgument.cla, iccArgument.command,
684                                 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
685                                 onCompleted);
686                     }
687                     break;
688 
689                 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
690                     ar = (AsyncResult) msg.obj;
691                     request = (MainThreadRequest) ar.userObj;
692                     if (ar.exception == null && ar.result != null) {
693                         request.result = ar.result;
694                     } else {
695                         request.result = new IccIoResult(0x6F, 0, (byte[]) null);
696                         if (ar.result == null) {
697                             loge("iccTransmitApduLogicalChannel: Empty response");
698                         } else if (ar.exception instanceof CommandException) {
699                             loge("iccTransmitApduLogicalChannel: CommandException: " +
700                                     ar.exception);
701                         } else {
702                             loge("iccTransmitApduLogicalChannel: Unknown exception");
703                         }
704                     }
705                     notifyRequester(request);
706                     break;
707 
708                 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
709                     request = (MainThreadRequest) msg.obj;
710                     iccArgument = (IccAPDUArgument) request.argument;
711                     uiccPort = getUiccPortFromRequest(request);
712                     if (uiccPort == null) {
713                         loge("iccTransmitApduBasicChannel: No UICC");
714                         request.result = new IccIoResult(0x6F, 0, (byte[]) null);
715                         notifyRequester(request);
716                     } else {
717                         onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
718                                 request);
719                         uiccPort.iccTransmitApduBasicChannel(
720                                 iccArgument.cla, iccArgument.command, iccArgument.p1,
721                                 iccArgument.p2,
722                                 iccArgument.p3, iccArgument.data, onCompleted);
723                     }
724                     break;
725 
726                 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
727                     ar = (AsyncResult) msg.obj;
728                     request = (MainThreadRequest) ar.userObj;
729                     if (ar.exception == null && ar.result != null) {
730                         request.result = ar.result;
731                     } else {
732                         request.result = new IccIoResult(0x6F, 0, (byte[]) null);
733                         if (ar.result == null) {
734                             loge("iccTransmitApduBasicChannel: Empty response");
735                         } else if (ar.exception instanceof CommandException) {
736                             loge("iccTransmitApduBasicChannel: CommandException: " +
737                                     ar.exception);
738                         } else {
739                             loge("iccTransmitApduBasicChannel: Unknown exception");
740                         }
741                     }
742                     notifyRequester(request);
743                     break;
744 
745                 case CMD_EXCHANGE_SIM_IO:
746                     request = (MainThreadRequest) msg.obj;
747                     iccArgument = (IccAPDUArgument) request.argument;
748                     uiccPort = getUiccPortFromRequest(request);
749                     if (uiccPort == null) {
750                         loge("iccExchangeSimIO: No UICC");
751                         request.result = new IccIoResult(0x6F, 0, (byte[]) null);
752                         notifyRequester(request);
753                     } else {
754                         onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
755                                 request);
756                         uiccPort.iccExchangeSimIO(iccArgument.cla, /* fileID */
757                                 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
758                                 iccArgument.data, onCompleted);
759                     }
760                     break;
761 
762                 case EVENT_EXCHANGE_SIM_IO_DONE:
763                     ar = (AsyncResult) msg.obj;
764                     request = (MainThreadRequest) ar.userObj;
765                     if (ar.exception == null && ar.result != null) {
766                         request.result = ar.result;
767                     } else {
768                         request.result = new IccIoResult(0x6f, 0, (byte[]) null);
769                     }
770                     notifyRequester(request);
771                     break;
772 
773                 case CMD_SEND_ENVELOPE:
774                     request = (MainThreadRequest) msg.obj;
775                     uiccPort = getUiccPortFromRequest(request);
776                     if (uiccPort == null) {
777                         loge("sendEnvelopeWithStatus: No UICC");
778                         request.result = new IccIoResult(0x6F, 0, (byte[]) null);
779                         notifyRequester(request);
780                     } else {
781                         onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
782                         uiccPort.sendEnvelopeWithStatus((String) request.argument, onCompleted);
783                     }
784                     break;
785 
786                 case EVENT_SEND_ENVELOPE_DONE:
787                     ar = (AsyncResult) msg.obj;
788                     request = (MainThreadRequest) ar.userObj;
789                     if (ar.exception == null && ar.result != null) {
790                         request.result = ar.result;
791                     } else {
792                         request.result = new IccIoResult(0x6F, 0, (byte[]) null);
793                         if (ar.result == null) {
794                             loge("sendEnvelopeWithStatus: Empty response");
795                         } else if (ar.exception instanceof CommandException) {
796                             loge("sendEnvelopeWithStatus: CommandException: " +
797                                     ar.exception);
798                         } else {
799                             loge("sendEnvelopeWithStatus: exception:" + ar.exception);
800                         }
801                     }
802                     notifyRequester(request);
803                     break;
804 
805                 case CMD_OPEN_CHANNEL:
806                     request = (MainThreadRequest) msg.obj;
807                     uiccPort = getUiccPortFromRequest(request);
808                     IccLogicalChannelRequest openChannelRequest =
809                             (IccLogicalChannelRequest) request.argument;
810                     if (uiccPort == null) {
811                         loge("iccOpenLogicalChannel: No UICC");
812                         request.result = new IccOpenLogicalChannelResponse(-1,
813                                 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
814                         notifyRequester(request);
815                     } else {
816                         onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
817                         uiccPort.iccOpenLogicalChannel(openChannelRequest.aid,
818                                 openChannelRequest.p2, onCompleted);
819                     }
820                     break;
821 
822                 case EVENT_OPEN_CHANNEL_DONE:
823                     ar = (AsyncResult) msg.obj;
824                     request = (MainThreadRequest) ar.userObj;
825                     IccOpenLogicalChannelResponse openChannelResp;
826                     if (ar.exception == null && ar.result != null) {
827                         int[] result = (int[]) ar.result;
828                         int channelId = result[0];
829                         byte[] selectResponse = null;
830                         if (result.length > 1) {
831                             selectResponse = new byte[result.length - 1];
832                             for (int i = 1; i < result.length; ++i) {
833                                 selectResponse[i - 1] = (byte) result[i];
834                             }
835                         }
836                         openChannelResp = new IccOpenLogicalChannelResponse(channelId,
837                                 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
838 
839                         uiccPort = getUiccPortFromRequest(request);
840                         if (uiccPort == null) {
841                             loge("EVENT_OPEN_CHANNEL_DONE: UiccPort is null");
842                         } else {
843                             IccLogicalChannelRequest channelRequest =
844                                     (IccLogicalChannelRequest) request.argument;
845                             channelRequest.channel = channelId;
846                             uiccPort.onLogicalChannelOpened(channelRequest);
847                         }
848                     } else {
849                         if (ar.result == null) {
850                             loge("iccOpenLogicalChannel: Empty response");
851                         }
852                         if (ar.exception != null) {
853                             loge("iccOpenLogicalChannel: Exception: " + ar.exception);
854                         }
855 
856                         int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
857                         if (ar.exception instanceof CommandException) {
858                             CommandException.Error error =
859                                     ((CommandException) (ar.exception)).getCommandError();
860                             if (error == CommandException.Error.MISSING_RESOURCE) {
861                                 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
862                             } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
863                                 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
864                             }
865                         }
866                         openChannelResp = new IccOpenLogicalChannelResponse(
867                                 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
868                     }
869                     request.result = openChannelResp;
870                     notifyRequester(request);
871                     break;
872 
873                 case CMD_CLOSE_CHANNEL:
874                     request = (MainThreadRequest) msg.obj;
875                     uiccPort = getUiccPortFromRequest(request);
876                     if (uiccPort == null) {
877                         loge("iccCloseLogicalChannel: No UICC");
878                         request.result = new IllegalArgumentException(
879                                 "iccCloseLogicalChannel: No UICC");
880                         notifyRequester(request);
881                     } else {
882                         onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
883                         uiccPort.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
884                     }
885                     break;
886 
887                 case EVENT_CLOSE_CHANNEL_DONE:
888                     ar = (AsyncResult) msg.obj;
889                     request = (MainThreadRequest) ar.userObj;
890                     if (ar.exception == null) {
891                         request.result = true;
892                         uiccPort = getUiccPortFromRequest(request);
893                         if (uiccPort == null) {
894                             loge("EVENT_CLOSE_CHANNEL_DONE: UiccPort is null");
895                         } else {
896                             final int channelId = (Integer) request.argument;
897                             uiccPort.onLogicalChannelClosed(channelId);
898                         }
899                     } else {
900                         request.result = false;
901                         Exception exception = null;
902                         if (ar.exception instanceof CommandException) {
903                             loge("iccCloseLogicalChannel: CommandException: " + ar.exception);
904                             CommandException.Error error =
905                                     ((CommandException) (ar.exception)).getCommandError();
906                             if (error == CommandException.Error.INVALID_ARGUMENTS) {
907                                 // should only throw exceptions from the binder threads.
908                                 exception = new IllegalArgumentException(
909                                         "iccCloseLogicalChannel: invalid argument ");
910                             }
911                         } else {
912                             loge("iccCloseLogicalChannel: Unknown exception");
913                         }
914                         request.result = (exception != null) ? exception :
915                                 new IllegalStateException(
916                                         "exception from modem to close iccLogical Channel");
917                     }
918                     notifyRequester(request);
919                     break;
920 
921                 case CMD_NV_READ_ITEM:
922                     request = (MainThreadRequest) msg.obj;
923                     onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
924                     defaultPhone.nvReadItem((Integer) request.argument, onCompleted,
925                             request.workSource);
926                     break;
927 
928                 case EVENT_NV_READ_ITEM_DONE:
929                     ar = (AsyncResult) msg.obj;
930                     request = (MainThreadRequest) ar.userObj;
931                     if (ar.exception == null && ar.result != null) {
932                         request.result = ar.result;     // String
933                     } else {
934                         request.result = "";
935                         if (ar.result == null) {
936                             loge("nvReadItem: Empty response");
937                         } else if (ar.exception instanceof CommandException) {
938                             loge("nvReadItem: CommandException: " +
939                                     ar.exception);
940                         } else {
941                             loge("nvReadItem: Unknown exception");
942                         }
943                     }
944                     notifyRequester(request);
945                     break;
946 
947                 case CMD_NV_WRITE_ITEM:
948                     request = (MainThreadRequest) msg.obj;
949                     onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
950                     Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
951                     defaultPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
952                             request.workSource);
953                     break;
954 
955                 case EVENT_NV_WRITE_ITEM_DONE:
956                     handleNullReturnEvent(msg, "nvWriteItem");
957                     break;
958 
959                 case CMD_NV_WRITE_CDMA_PRL:
960                     if (mFeatureFlags.cleanupCdma()) break;
961                     request = (MainThreadRequest) msg.obj;
962                     onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
963                     defaultPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
964                     break;
965 
966                 case EVENT_NV_WRITE_CDMA_PRL_DONE:
967                     if (mFeatureFlags.cleanupCdma()) break;
968                     handleNullReturnEvent(msg, "nvWriteCdmaPrl");
969                     break;
970 
971                 case CMD_RESET_MODEM_CONFIG:
972                     request = (MainThreadRequest) msg.obj;
973                     onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
974                     defaultPhone.resetModemConfig(onCompleted);
975                     break;
976 
977                 case EVENT_RESET_MODEM_CONFIG_DONE:
978                     handleNullReturnEvent(msg, "resetModemConfig");
979                     break;
980 
981                 case CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED: {
982                     request = (MainThreadRequest) msg.obj;
983                     onCompleted = obtainMessage(EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE,
984                             request);
985                     Phone phone = getPhoneFromRequest(request);
986                     if (phone != null) {
987                         phone.isNrDualConnectivityEnabled(onCompleted, request.workSource);
988                     } else {
989                         loge("isNRDualConnectivityEnabled: No phone object");
990                         request.result = false;
991                         notifyRequester(request);
992                     }
993                     break;
994                 }
995 
996                 case EVENT_IS_NR_DUAL_CONNECTIVITY_ENABLED_DONE:
997                     ar = (AsyncResult) msg.obj;
998                     request = (MainThreadRequest) ar.userObj;
999                     if (ar.exception == null && ar.result != null) {
1000                         request.result = ar.result;
1001                     } else {
1002                         // request.result must be set to something non-null
1003                         // for the calling thread to unblock
1004                         if (ar.result != null) {
1005                             request.result = ar.result;
1006                         } else {
1007                             request.result = false;
1008                         }
1009                         if (ar.result == null) {
1010                             loge("isNRDualConnectivityEnabled: Empty response");
1011                         } else if (ar.exception instanceof CommandException) {
1012                             loge("isNRDualConnectivityEnabled: CommandException: "
1013                                     + ar.exception);
1014                         } else {
1015                             loge("isNRDualConnectivityEnabled: Unknown exception");
1016                         }
1017                     }
1018                     notifyRequester(request);
1019                     break;
1020 
1021                 case CMD_IS_VONR_ENABLED: {
1022                     request = (MainThreadRequest) msg.obj;
1023                     onCompleted = obtainMessage(EVENT_IS_VONR_ENABLED_DONE,
1024                             request);
1025                     Phone phone = getPhoneFromRequest(request);
1026                     if (phone != null) {
1027                         phone.isVoNrEnabled(onCompleted, request.workSource);
1028                     } else {
1029                         loge("isVoNrEnabled: No phone object");
1030                         request.result = false;
1031                         notifyRequester(request);
1032                     }
1033                     break;
1034                 }
1035 
1036                 case EVENT_IS_VONR_ENABLED_DONE:
1037                     ar = (AsyncResult) msg.obj;
1038                     request = (MainThreadRequest) ar.userObj;
1039                     if (ar.exception == null && ar.result != null) {
1040                         request.result = ar.result;
1041                     } else {
1042                         // request.result must be set to something non-null
1043                         // for the calling thread to unblock
1044                         if (ar.result != null) {
1045                             request.result = ar.result;
1046                         } else {
1047                             request.result = false;
1048                         }
1049                         if (ar.result == null) {
1050                             loge("isVoNrEnabled: Empty response");
1051                         } else if (ar.exception instanceof CommandException) {
1052                             loge("isVoNrEnabled: CommandException: "
1053                                     + ar.exception);
1054                         } else {
1055                             loge("isVoNrEnabled: Unknown exception");
1056                         }
1057                     }
1058                     notifyRequester(request);
1059                     break;
1060 
1061                 case CMD_ENABLE_NR_DUAL_CONNECTIVITY: {
1062                     request = (MainThreadRequest) msg.obj;
1063                     onCompleted = obtainMessage(EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE, request);
1064                     Phone phone = getPhoneFromRequest(request);
1065                     if (phone != null) {
1066                         phone.setNrDualConnectivityState((int) request.argument, onCompleted,
1067                                 request.workSource);
1068                     } else {
1069                         loge("enableNrDualConnectivity: No phone object");
1070                         request.result =
1071                                 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
1072                         notifyRequester(request);
1073                     }
1074                     break;
1075                 }
1076 
1077                 case EVENT_ENABLE_NR_DUAL_CONNECTIVITY_DONE: {
1078                     ar = (AsyncResult) msg.obj;
1079                     request = (MainThreadRequest) ar.userObj;
1080                     if (ar.exception == null) {
1081                         request.result =
1082                                 TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_SUCCESS;
1083                     } else {
1084                         request.result =
1085                                 TelephonyManager
1086                                         .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_ERROR;
1087                         if (ar.exception instanceof CommandException) {
1088                             CommandException.Error error =
1089                                     ((CommandException) (ar.exception)).getCommandError();
1090                             if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1091                                 request.result =
1092                                         TelephonyManager
1093                                                 .ENABLE_NR_DUAL_CONNECTIVITY_RADIO_NOT_AVAILABLE;
1094                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1095                                 request.result =
1096                                         TelephonyManager
1097                                                 .ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED;
1098                             }
1099                             loge("enableNrDualConnectivity" + ": CommandException: "
1100                                     + ar.exception);
1101                         } else {
1102                             loge("enableNrDualConnectivity" + ": Unknown exception");
1103                         }
1104                     }
1105                     notifyRequester(request);
1106                     break;
1107                 }
1108 
1109                 case CMD_ENABLE_VONR: {
1110                     request = (MainThreadRequest) msg.obj;
1111                     onCompleted = obtainMessage(EVENT_ENABLE_VONR_DONE, request);
1112                     Phone phone = getPhoneFromRequest(request);
1113                     if (phone != null) {
1114                         phone.setVoNrEnabled((boolean) request.argument, onCompleted,
1115                                 request.workSource);
1116                     } else {
1117                         loge("setVoNrEnabled: No phone object");
1118                         request.result =
1119                                 TelephonyManager.ENABLE_VONR_RADIO_NOT_AVAILABLE;
1120                         notifyRequester(request);
1121                     }
1122                     break;
1123                 }
1124 
1125                 case EVENT_ENABLE_VONR_DONE: {
1126                     ar = (AsyncResult) msg.obj;
1127                     request = (MainThreadRequest) ar.userObj;
1128                     if (ar.exception == null) {
1129                         request.result = TelephonyManager.ENABLE_VONR_SUCCESS;
1130                     } else {
1131                         request.result = TelephonyManager.ENABLE_VONR_RADIO_ERROR;
1132                         if (ar.exception instanceof CommandException) {
1133                             CommandException.Error error =
1134                                     ((CommandException) (ar.exception)).getCommandError();
1135                             if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1136                                 request.result = TelephonyManager.ENABLE_VONR_RADIO_NOT_AVAILABLE;
1137                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1138                                 request.result = TelephonyManager.ENABLE_VONR_REQUEST_NOT_SUPPORTED;
1139                             } else {
1140                                 request.result = TelephonyManager.ENABLE_VONR_RADIO_ERROR;
1141                             }
1142                             loge("setVoNrEnabled" + ": CommandException: "
1143                                     + ar.exception);
1144                         } else {
1145                             loge("setVoNrEnabled" + ": Unknown exception");
1146                         }
1147                     }
1148                     notifyRequester(request);
1149                     break;
1150                 }
1151 
1152                 case CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK:
1153                     request = (MainThreadRequest) msg.obj;
1154                     onCompleted = obtainMessage(EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE,
1155                             request);
1156                     getPhoneFromRequest(request).getAllowedNetworkTypesBitmask(onCompleted);
1157                     break;
1158 
1159                 case EVENT_GET_ALLOWED_NETWORK_TYPES_BITMASK_DONE:
1160                     ar = (AsyncResult) msg.obj;
1161                     request = (MainThreadRequest) ar.userObj;
1162                     if (ar.exception == null && ar.result != null) {
1163                         request.result = ar.result;     // Integer
1164                     } else {
1165                         // request.result must be set to something non-null
1166                         // for the calling thread to unblock
1167                         request.result = new int[]{-1};
1168                         if (ar.result == null) {
1169                             loge("getAllowedNetworkTypesBitmask: Empty response");
1170                         } else if (ar.exception instanceof CommandException) {
1171                             loge("getAllowedNetworkTypesBitmask: CommandException: "
1172                                     + ar.exception);
1173                         } else {
1174                             loge("getAllowedNetworkTypesBitmask: Unknown exception");
1175                         }
1176                     }
1177                     notifyRequester(request);
1178                     break;
1179 
1180                 case CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON:
1181                     request = (MainThreadRequest) msg.obj;
1182                     onCompleted = obtainMessage(EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE,
1183                             request);
1184                     Pair<Integer, Long> reasonWithNetworkTypes =
1185                             (Pair<Integer, Long>) request.argument;
1186                     getPhoneFromRequest(request).setAllowedNetworkTypes(
1187                             reasonWithNetworkTypes.first,
1188                             reasonWithNetworkTypes.second,
1189                             onCompleted);
1190                     break;
1191 
1192                 case EVENT_SET_ALLOWED_NETWORK_TYPES_FOR_REASON_DONE:
1193                     handleNullReturnEvent(msg, "setAllowedNetworkTypesForReason");
1194                     break;
1195 
1196                 case CMD_SET_VOICEMAIL_NUMBER:
1197                     request = (MainThreadRequest) msg.obj;
1198                     onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
1199                     Pair<String, String> tagNum = (Pair<String, String>) request.argument;
1200                     getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
1201                             onCompleted);
1202                     break;
1203 
1204                 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
1205                     handleNullReturnEvent(msg, "setVoicemailNumber");
1206                     break;
1207 
1208                 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
1209                     request = (MainThreadRequest) msg.obj;
1210                     onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
1211                             request);
1212                     getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
1213                     break;
1214 
1215                 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
1216                     handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
1217                     break;
1218 
1219                 case CMD_PERFORM_NETWORK_SCAN:
1220                     request = (MainThreadRequest) msg.obj;
1221                     onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
1222                     getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
1223                     break;
1224 
1225                 case CMD_GET_CALL_FORWARDING: {
1226                     request = (MainThreadRequest) msg.obj;
1227                     onCompleted = obtainMessage(EVENT_GET_CALL_FORWARDING_DONE, request);
1228                     Pair<Integer, TelephonyManager.CallForwardingInfoCallback> args =
1229                             (Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
1230                                     request.argument;
1231                     int callForwardingReason = args.first;
1232                     request.phone.getCallForwardingOption(callForwardingReason, onCompleted);
1233                     break;
1234                 }
1235                 case EVENT_GET_CALL_FORWARDING_DONE: {
1236                     ar = (AsyncResult) msg.obj;
1237                     request = (MainThreadRequest) ar.userObj;
1238                     TelephonyManager.CallForwardingInfoCallback callback =
1239                             ((Pair<Integer, TelephonyManager.CallForwardingInfoCallback>)
1240                                     request.argument).second;
1241                     if (ar.exception == null && ar.result != null) {
1242                         CallForwardingInfo callForwardingInfo = null;
1243                         CallForwardInfo[] callForwardInfos = (CallForwardInfo[]) ar.result;
1244                         for (CallForwardInfo callForwardInfo : callForwardInfos) {
1245                             // Service Class is a bit mask per 3gpp 27.007. Search for
1246                             // any service for voice call.
1247                             if ((callForwardInfo.serviceClass
1248                                     & CommandsInterface.SERVICE_CLASS_VOICE) > 0) {
1249                                 callForwardingInfo = new CallForwardingInfo(
1250                                         callForwardInfo.status
1251                                                 == CommandsInterface.CF_ACTION_ENABLE,
1252                                         callForwardInfo.reason,
1253                                         callForwardInfo.number,
1254                                         callForwardInfo.timeSeconds);
1255                                 break;
1256                             }
1257                         }
1258                         // Didn't find a call forward info for voice call.
1259                         if (callForwardingInfo == null) {
1260                             callForwardingInfo = new CallForwardingInfo(false /* enabled */,
1261                                     0 /* reason */, null /* number */, 0 /* timeout */);
1262                         }
1263                         callback.onCallForwardingInfoAvailable(callForwardingInfo);
1264                     } else {
1265                         if (ar.result == null) {
1266                             loge("EVENT_GET_CALL_FORWARDING_DONE: Empty response");
1267                         }
1268                         if (ar.exception != null) {
1269                             loge("EVENT_GET_CALL_FORWARDING_DONE: Exception: " + ar.exception);
1270                         }
1271                         int errorCode = TelephonyManager
1272                                 .CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN;
1273                         if (ar.exception instanceof CommandException) {
1274                             CommandException.Error error =
1275                                     ((CommandException) (ar.exception)).getCommandError();
1276                             if (error == CommandException.Error.FDN_CHECK_FAILURE) {
1277                                 errorCode = TelephonyManager
1278                                         .CallForwardingInfoCallback.RESULT_ERROR_FDN_CHECK_FAILURE;
1279                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1280                                 errorCode = TelephonyManager
1281                                         .CallForwardingInfoCallback.RESULT_ERROR_NOT_SUPPORTED;
1282                             }
1283                         }
1284                         callback.onError(errorCode);
1285                     }
1286                     break;
1287                 }
1288 
1289                 case CMD_SET_CALL_FORWARDING: {
1290                     request = (MainThreadRequest) msg.obj;
1291                     onCompleted = obtainMessage(EVENT_SET_CALL_FORWARDING_DONE, request);
1292                     request = (MainThreadRequest) msg.obj;
1293                     CallForwardingInfo callForwardingInfoToSet =
1294                             ((Pair<CallForwardingInfo, Consumer<Integer>>)
1295                                     request.argument).first;
1296                     request.phone.setCallForwardingOption(
1297                             callForwardingInfoToSet.isEnabled()
1298                                     ? CommandsInterface.CF_ACTION_REGISTRATION
1299                                     : CommandsInterface.CF_ACTION_DISABLE,
1300                             callForwardingInfoToSet.getReason(),
1301                             callForwardingInfoToSet.getNumber(),
1302                             callForwardingInfoToSet.getTimeoutSeconds(), onCompleted);
1303                     break;
1304                 }
1305 
1306                 case EVENT_SET_CALL_FORWARDING_DONE: {
1307                     ar = (AsyncResult) msg.obj;
1308                     request = (MainThreadRequest) ar.userObj;
1309                     Consumer<Integer> callback =
1310                             ((Pair<CallForwardingInfo, Consumer<Integer>>)
1311                                     request.argument).second;
1312                     if (ar.exception != null) {
1313                         loge("setCallForwarding exception: " + ar.exception);
1314                         int errorCode = TelephonyManager.CallForwardingInfoCallback
1315                                 .RESULT_ERROR_UNKNOWN;
1316                         if (ar.exception instanceof CommandException) {
1317                             CommandException.Error error =
1318                                     ((CommandException) (ar.exception)).getCommandError();
1319                             if (error == CommandException.Error.FDN_CHECK_FAILURE) {
1320                                 errorCode = TelephonyManager.CallForwardingInfoCallback
1321                                         .RESULT_ERROR_FDN_CHECK_FAILURE;
1322                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1323                                 errorCode = TelephonyManager.CallForwardingInfoCallback
1324                                         .RESULT_ERROR_NOT_SUPPORTED;
1325                             }
1326                         }
1327                         callback.accept(errorCode);
1328                     } else {
1329                         callback.accept(TelephonyManager.CallForwardingInfoCallback.RESULT_SUCCESS);
1330                     }
1331                     break;
1332                 }
1333 
1334                 case CMD_GET_CALL_WAITING: {
1335                     request = (MainThreadRequest) msg.obj;
1336                     onCompleted = obtainMessage(EVENT_GET_CALL_WAITING_DONE, request);
1337                     getPhoneFromRequest(request).getCallWaiting(onCompleted);
1338                     break;
1339                 }
1340 
1341                 case EVENT_GET_CALL_WAITING_DONE: {
1342                     ar = (AsyncResult) msg.obj;
1343                     request = (MainThreadRequest) ar.userObj;
1344                     Consumer<Integer> callback = (Consumer<Integer>) request.argument;
1345                     int callWaitingStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
1346                     if (ar.exception == null && ar.result != null) {
1347                         int[] callForwardResults = (int[]) ar.result;
1348                         // Service Class is a bit mask per 3gpp 27.007.
1349                         // Search for any service for voice call.
1350                         if (callForwardResults.length > 1
1351                                 && ((callForwardResults[1]
1352                                 & CommandsInterface.SERVICE_CLASS_VOICE) > 0)) {
1353                             callWaitingStatus = callForwardResults[0] == 0
1354                                     ? TelephonyManager.CALL_WAITING_STATUS_DISABLED
1355                                     : TelephonyManager.CALL_WAITING_STATUS_ENABLED;
1356                         } else {
1357                             callWaitingStatus = TelephonyManager.CALL_WAITING_STATUS_DISABLED;
1358                         }
1359                     } else {
1360                         if (ar.result == null) {
1361                             loge("EVENT_GET_CALL_WAITING_DONE: Empty response");
1362                         }
1363                         if (ar.exception != null) {
1364                             loge("EVENT_GET_CALL_WAITING_DONE: Exception: " + ar.exception);
1365                         }
1366                         if (ar.exception instanceof CommandException) {
1367                             CommandException.Error error =
1368                                     ((CommandException) (ar.exception)).getCommandError();
1369                             if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1370                                 callWaitingStatus =
1371                                         TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED;
1372                             } else if (error == CommandException.Error.FDN_CHECK_FAILURE) {
1373                                 callWaitingStatus =
1374                                         TelephonyManager.CALL_WAITING_STATUS_FDN_CHECK_FAILURE;
1375                             }
1376                         }
1377                     }
1378                     callback.accept(callWaitingStatus);
1379                     break;
1380                 }
1381 
1382                 case CMD_SET_CALL_WAITING: {
1383                     request = (MainThreadRequest) msg.obj;
1384                     onCompleted = obtainMessage(EVENT_SET_CALL_WAITING_DONE, request);
1385                     boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1386                     getPhoneFromRequest(request).setCallWaiting(enable, onCompleted);
1387                     break;
1388                 }
1389 
1390                 case EVENT_SET_CALL_WAITING_DONE: {
1391                     ar = (AsyncResult) msg.obj;
1392                     request = (MainThreadRequest) ar.userObj;
1393                     boolean enable = ((Pair<Boolean, Consumer<Integer>>) request.argument).first;
1394                     Consumer<Integer> callback =
1395                             ((Pair<Boolean, Consumer<Integer>>) request.argument).second;
1396                     if (ar.exception != null) {
1397                         loge("setCallWaiting exception: " + ar.exception);
1398                         if (ar.exception instanceof CommandException) {
1399                             CommandException.Error error =
1400                                     ((CommandException) (ar.exception)).getCommandError();
1401                             if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1402                                 callback.accept(TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED);
1403                             } else if (error == CommandException.Error.FDN_CHECK_FAILURE) {
1404                                 callback.accept(
1405                                         TelephonyManager.CALL_WAITING_STATUS_FDN_CHECK_FAILURE);
1406                             } else {
1407                                 callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1408                             }
1409                         } else {
1410                             callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
1411                         }
1412                     } else {
1413                         callback.accept(enable ? TelephonyManager.CALL_WAITING_STATUS_ENABLED
1414                                 : TelephonyManager.CALL_WAITING_STATUS_DISABLED);
1415                     }
1416                     break;
1417                 }
1418                 case EVENT_PERFORM_NETWORK_SCAN_DONE:
1419                     ar = (AsyncResult) msg.obj;
1420                     request = (MainThreadRequest) ar.userObj;
1421                     CellNetworkScanResult cellScanResult;
1422                     if (ar.exception == null && ar.result != null) {
1423                         cellScanResult = new CellNetworkScanResult(
1424                                 CellNetworkScanResult.STATUS_SUCCESS,
1425                                 (List<OperatorInfo>) ar.result);
1426                     } else {
1427                         if (ar.result == null) {
1428                             loge("getCellNetworkScanResults: Empty response");
1429                         }
1430                         if (ar.exception != null) {
1431                             loge("getCellNetworkScanResults: Exception: " + ar.exception);
1432                         }
1433                         int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
1434                         if (ar.exception instanceof CommandException) {
1435                             CommandException.Error error =
1436                                     ((CommandException) (ar.exception)).getCommandError();
1437                             if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
1438                                 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
1439                             } else if (error == CommandException.Error.GENERIC_FAILURE) {
1440                                 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
1441                             }
1442                         }
1443                         cellScanResult = new CellNetworkScanResult(errorCode, null);
1444                     }
1445                     request.result = cellScanResult;
1446                     notifyRequester(request);
1447                     break;
1448 
1449                 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
1450                     request = (MainThreadRequest) msg.obj;
1451                     ManualNetworkSelectionArgument selArg =
1452                             (ManualNetworkSelectionArgument) request.argument;
1453                     onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
1454                             request);
1455                     getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
1456                             selArg.persistSelection, onCompleted);
1457                     break;
1458 
1459                 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
1460                     ar = (AsyncResult) msg.obj;
1461                     request = (MainThreadRequest) ar.userObj;
1462                     if (ar.exception == null) {
1463                         request.result = true;
1464                     } else {
1465                         request.result = false;
1466                         loge("setNetworkSelectionModeManual " + ar.exception);
1467                     }
1468                     notifyRequester(request);
1469                     mApp.onNetworkSelectionChanged(request.subId);
1470                     break;
1471 
1472                 case CMD_GET_MODEM_ACTIVITY_INFO:
1473                     request = (MainThreadRequest) msg.obj;
1474                     onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
1475                     if (defaultPhone != null) {
1476                         defaultPhone.getModemActivityInfo(onCompleted, request.workSource);
1477                     } else {
1478                         ResultReceiver result = (ResultReceiver) request.argument;
1479                         Bundle bundle = new Bundle();
1480                         bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY,
1481                                 new ModemActivityInfo(0, 0, 0,
1482                                         new int[ModemActivityInfo.getNumTxPowerLevels()], 0));
1483                         result.send(0, bundle);
1484                     }
1485                     break;
1486 
1487                 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE: {
1488                     ar = (AsyncResult) msg.obj;
1489                     request = (MainThreadRequest) ar.userObj;
1490                     ResultReceiver result = (ResultReceiver) request.argument;
1491                     int error = 0;
1492                     ModemActivityInfo ret = null;
1493                     if (mLastModemActivityInfo == null) {
1494                         mLastModemActivitySpecificInfo = new ActivityStatsTechSpecificInfo[1];
1495                         mLastModemActivitySpecificInfo[0] =
1496                                 new ActivityStatsTechSpecificInfo(
1497                                         0,
1498                                         0,
1499                                         new int[ModemActivityInfo.getNumTxPowerLevels()],
1500                                         0);
1501                         mLastModemActivityInfo =
1502                                 new ModemActivityInfo(0, 0, 0, mLastModemActivitySpecificInfo);
1503                     }
1504 
1505                     if (ar.exception == null && ar.result != null) {
1506                         // Update the last modem activity info and the result of the request.
1507                         ModemActivityInfo info = (ModemActivityInfo) ar.result;
1508                         if (isModemActivityInfoValid(info)) {
1509                             mergeModemActivityInfo(info);
1510                         } else {
1511                             loge("queryModemActivityInfo: invalid response");
1512                         }
1513                         // This is needed to decouple ret from mLastModemActivityInfo
1514                         // We don't want to return mLastModemActivityInfo which is updated
1515                         // inside mergeModemActivityInfo()
1516                         ret = new ModemActivityInfo(
1517                                 mLastModemActivityInfo.getTimestampMillis(),
1518                                 mLastModemActivityInfo.getSleepTimeMillis(),
1519                                 mLastModemActivityInfo.getIdleTimeMillis(),
1520                                 deepCopyModemActivitySpecificInfo(mLastModemActivitySpecificInfo));
1521 
1522                     } else {
1523                         if (ar.result == null) {
1524                             loge("queryModemActivityInfo: Empty response");
1525                             error = TelephonyManager.ModemActivityInfoException
1526                                     .ERROR_INVALID_INFO_RECEIVED;
1527                         } else if (ar.exception instanceof CommandException) {
1528                             loge("queryModemActivityInfo: CommandException: " + ar.exception);
1529                             error = TelephonyManager.ModemActivityInfoException
1530                                     .ERROR_MODEM_RESPONSE_ERROR;
1531                         } else {
1532                             loge("queryModemActivityInfo: Unknown exception");
1533                             error = TelephonyManager.ModemActivityInfoException
1534                                     .ERROR_UNKNOWN;
1535                         }
1536                     }
1537                     Bundle bundle = new Bundle();
1538                     if (ret != null) {
1539                         bundle.putParcelable(
1540                                 TelephonyManager.MODEM_ACTIVITY_RESULT_KEY,
1541                                 ret);
1542                     } else {
1543                         bundle.putInt(TelephonyManager.EXCEPTION_RESULT_KEY, error);
1544                     }
1545                     result.send(0, bundle);
1546                     notifyRequester(request);
1547                     break;
1548                 }
1549 
1550                 case CMD_SET_ALLOWED_CARRIERS: {
1551                     request = (MainThreadRequest) msg.obj;
1552                     CarrierRestrictionRules argument =
1553                             (CarrierRestrictionRules) request.argument;
1554                     onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
1555                     defaultPhone.setAllowedCarriers(argument, onCompleted, request.workSource);
1556                     break;
1557                 }
1558 
1559                 case EVENT_SET_ALLOWED_CARRIERS_DONE:
1560                     ar = (AsyncResult) msg.obj;
1561                     request = (MainThreadRequest) ar.userObj;
1562                     if (ar.exception == null && ar.result != null) {
1563                         request.result = ar.result;
1564                     } else {
1565                         request.result = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
1566                         if (ar.exception instanceof CommandException) {
1567                             loge("setAllowedCarriers: CommandException: " + ar.exception);
1568                             CommandException.Error error =
1569                                     ((CommandException) (ar.exception)).getCommandError();
1570                             if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1571                                 request.result =
1572                                         TelephonyManager.SET_CARRIER_RESTRICTION_NOT_SUPPORTED;
1573                             }
1574                         } else {
1575                             loge("setAllowedCarriers: Unknown exception");
1576                         }
1577                     }
1578                     notifyRequester(request);
1579                     break;
1580 
1581                 case CMD_GET_ALLOWED_CARRIERS:
1582                     request = (MainThreadRequest) msg.obj;
1583                     onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
1584                     defaultPhone.getAllowedCarriers(onCompleted, request.workSource);
1585                     break;
1586 
1587                 case EVENT_GET_ALLOWED_CARRIERS_DONE:
1588                     ar = (AsyncResult) msg.obj;
1589                     request = (MainThreadRequest) ar.userObj;
1590                     if (ar.exception == null && ar.result != null) {
1591                         request.result = ar.result;
1592                     } else {
1593                         request.result = new IllegalStateException(
1594                                 "Failed to get carrier restrictions");
1595                         if (ar.result == null) {
1596                             loge("getAllowedCarriers: Empty response");
1597                         } else if (ar.exception instanceof CommandException) {
1598                             loge("getAllowedCarriers: CommandException: " +
1599                                     ar.exception);
1600                         } else {
1601                             loge("getAllowedCarriers: Unknown exception");
1602                         }
1603                     }
1604                     if (request.argument != null) {
1605                         // This is for the implementation of carrierRestrictionStatus.
1606                         CallerCallbackInfo callbackInfo = (CallerCallbackInfo) request.argument;
1607                         Consumer<Integer> callback = callbackInfo.getConsumer();
1608                         Set<Integer> callerCarrierIds = callbackInfo.getCarrierIds();
1609                         int lockStatus = TelephonyManager.CARRIER_RESTRICTION_STATUS_UNKNOWN;
1610                         if (ar.exception == null && ar.result instanceof CarrierRestrictionRules) {
1611                             CarrierRestrictionRules carrierRestrictionRules =
1612                                     (CarrierRestrictionRules) ar.result;
1613                             int carrierId = -1;
1614                             try {
1615                                 CarrierIdentifier carrierIdentifier =
1616                                         carrierRestrictionRules.getAllowedCarriers().get(0);
1617                                 carrierId = CarrierResolver.getCarrierIdFromIdentifier(mApp,
1618                                         carrierIdentifier);
1619                             } catch (NullPointerException | IndexOutOfBoundsException ex) {
1620                                 Rlog.e(LOG_TAG, "CarrierIdentifier exception = " + ex);
1621                             }
1622                             lockStatus = carrierRestrictionRules.getCarrierRestrictionStatus();
1623                             int restrictedStatus =
1624                                     TelephonyManager.CARRIER_RESTRICTION_STATUS_RESTRICTED;
1625                             if (carrierId != -1 && callerCarrierIds.contains(carrierId) &&
1626                                     lockStatus == restrictedStatus) {
1627                                 lockStatus = TelephonyManager
1628                                         .CARRIER_RESTRICTION_STATUS_RESTRICTED_TO_CALLER;
1629                             }
1630                         } else {
1631                             Rlog.e(LOG_TAG,
1632                                     "getCarrierRestrictionStatus: exception ex = " + ar.exception);
1633                         }
1634                         callback.accept(lockStatus);
1635                     } else {
1636                         // This is for the implementation of getAllowedCarriers.
1637                         notifyRequester(request);
1638                     }
1639                     break;
1640 
1641                 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
1642                     ar = (AsyncResult) msg.obj;
1643                     request = (MainThreadRequest) ar.userObj;
1644                     if (ar.exception == null && ar.result != null) {
1645                         request.result = ar.result;
1646                     } else {
1647                         request.result = new IllegalArgumentException(
1648                                 "Failed to retrieve Forbidden Plmns");
1649                         if (ar.result == null) {
1650                             loge("getForbiddenPlmns: Empty response");
1651                         } else {
1652                             loge("getForbiddenPlmns: Unknown exception");
1653                         }
1654                     }
1655                     notifyRequester(request);
1656                     break;
1657 
1658                 case CMD_GET_FORBIDDEN_PLMNS:
1659                     request = (MainThreadRequest) msg.obj;
1660                     uiccPort = getUiccPortFromRequest(request);
1661                     if (uiccPort == null) {
1662                         loge("getForbiddenPlmns() UiccPort is null");
1663                         request.result = new IllegalArgumentException(
1664                                 "getForbiddenPlmns() UiccPort is null");
1665                         notifyRequester(request);
1666                         break;
1667                     }
1668                     Integer appType = (Integer) request.argument;
1669                     UiccCardApplication uiccApp = uiccPort.getApplicationByType(appType);
1670                     if (uiccApp == null) {
1671                         loge("getForbiddenPlmns() no app with specified type -- "
1672                                 + appType);
1673                         request.result = new IllegalArgumentException("Failed to get UICC App");
1674                         notifyRequester(request);
1675                         break;
1676                     } else {
1677                         if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
1678                                 + " specified type -- " + appType);
1679                     }
1680                     onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
1681                     ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
1682                             onCompleted);
1683                     break;
1684 
1685                 case CMD_SWITCH_SLOTS:
1686                     request = (MainThreadRequest) msg.obj;
1687                     List<UiccSlotMapping> slotMapping = (List<UiccSlotMapping>) request.argument;
1688                     onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
1689                     UiccController.getInstance().switchSlots(slotMapping, onCompleted);
1690                     break;
1691 
1692                 case EVENT_SWITCH_SLOTS_DONE:
1693                     ar = (AsyncResult) msg.obj;
1694                     request = (MainThreadRequest) ar.userObj;
1695                     request.result = (ar.exception == null);
1696                     notifyRequester(request);
1697                     break;
1698                 case CMD_GET_NETWORK_SELECTION_MODE:
1699                     request = (MainThreadRequest) msg.obj;
1700                     onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
1701                     getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
1702                     break;
1703 
1704                 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
1705                     ar = (AsyncResult) msg.obj;
1706                     request = (MainThreadRequest) ar.userObj;
1707                     if (ar.exception != null) {
1708                         request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
1709                     } else {
1710                         int mode = ((int[]) ar.result)[0];
1711                         if (mode == 0) {
1712                             request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
1713                         } else {
1714                             request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
1715                         }
1716                     }
1717                     notifyRequester(request);
1718                     break;
1719                 case CMD_GET_CDMA_ROAMING_MODE:
1720                     if (mFeatureFlags.cleanupCdma()) break;
1721                     request = (MainThreadRequest) msg.obj;
1722                     onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
1723                     getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
1724                     break;
1725                 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
1726                     if (mFeatureFlags.cleanupCdma()) break;
1727                     ar = (AsyncResult) msg.obj;
1728                     request = (MainThreadRequest) ar.userObj;
1729                     if (ar.exception != null) {
1730                         request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
1731                     } else {
1732                         request.result = ((int[]) ar.result)[0];
1733                     }
1734                     notifyRequester(request);
1735                     break;
1736                 case CMD_SET_CDMA_ROAMING_MODE:
1737                     if (mFeatureFlags.cleanupCdma()) break;
1738                     request = (MainThreadRequest) msg.obj;
1739                     onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
1740                     int mode = (int) request.argument;
1741                     getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
1742                     break;
1743                 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
1744                     if (mFeatureFlags.cleanupCdma()) break;
1745                     ar = (AsyncResult) msg.obj;
1746                     request = (MainThreadRequest) ar.userObj;
1747                     request.result = ar.exception == null;
1748                     notifyRequester(request);
1749                     break;
1750                 case CMD_GET_CDMA_SUBSCRIPTION_MODE:
1751                     if (mFeatureFlags.cleanupCdma()) break;
1752                     request = (MainThreadRequest) msg.obj;
1753                     onCompleted = obtainMessage(EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1754                     getPhoneFromRequest(request).queryCdmaSubscriptionMode(onCompleted);
1755                     break;
1756                 case EVENT_GET_CDMA_SUBSCRIPTION_MODE_DONE:
1757                     if (mFeatureFlags.cleanupCdma()) break;
1758                     ar = (AsyncResult) msg.obj;
1759                     request = (MainThreadRequest) ar.userObj;
1760                     if (ar.exception != null) {
1761                         request.result = TelephonyManager.CDMA_SUBSCRIPTION_RUIM_SIM;
1762                     } else {
1763                         request.result = ((int[]) ar.result)[0];
1764                     }
1765                     notifyRequester(request);
1766                     break;
1767                 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
1768                     if (mFeatureFlags.cleanupCdma()) break;
1769                     request = (MainThreadRequest) msg.obj;
1770                     onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1771                     int subscriptionMode = (int) request.argument;
1772                     getPhoneFromRequest(request).setCdmaSubscriptionMode(
1773                             subscriptionMode, onCompleted);
1774                     break;
1775                 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
1776                     if (mFeatureFlags.cleanupCdma()) break;
1777                     ar = (AsyncResult) msg.obj;
1778                     request = (MainThreadRequest) ar.userObj;
1779                     request.result = ar.exception == null;
1780                     notifyRequester(request);
1781                     break;
1782                 case CMD_GET_ALL_CELL_INFO:
1783                     request = (MainThreadRequest) msg.obj;
1784                     onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
1785                     request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
1786                     break;
1787                 case EVENT_GET_ALL_CELL_INFO_DONE:
1788                     ar = (AsyncResult) msg.obj;
1789                     request = (MainThreadRequest) ar.userObj;
1790                     // If a timeout occurs, the response will be null
1791                     request.result = (ar.exception == null && ar.result != null)
1792                             ? ar.result : new ArrayList<CellInfo>();
1793                     synchronized (request) {
1794                         request.notifyAll();
1795                     }
1796                     break;
1797                 case CMD_REQUEST_CELL_INFO_UPDATE:
1798                     request = (MainThreadRequest) msg.obj;
1799                     request.phone.requestCellInfoUpdate(request.workSource,
1800                             obtainMessage(EVENT_REQUEST_CELL_INFO_UPDATE_DONE, request));
1801                     break;
1802                 case EVENT_REQUEST_CELL_INFO_UPDATE_DONE:
1803                     ar = (AsyncResult) msg.obj;
1804                     request = (MainThreadRequest) ar.userObj;
1805                     ICellInfoCallback cb = (ICellInfoCallback) request.argument;
1806                     try {
1807                         if (ar.exception != null) {
1808                             Log.e(LOG_TAG, "Exception retrieving CellInfo=" + ar.exception);
1809                             cb.onError(
1810                                     TelephonyManager.CellInfoCallback.ERROR_MODEM_ERROR,
1811                                     ar.exception.getClass().getName(),
1812                                     ar.exception.toString());
1813                         } else if (ar.result == null) {
1814                             Log.w(LOG_TAG, "Timeout Waiting for CellInfo!");
1815                             cb.onError(TelephonyManager.CellInfoCallback.ERROR_TIMEOUT, null, null);
1816                         } else {
1817                             // use the result as returned
1818                             cb.onCellInfo((List<CellInfo>) ar.result);
1819                         }
1820                     } catch (RemoteException re) {
1821                         Log.w(LOG_TAG, "Discarded CellInfo due to Callback RemoteException");
1822                     }
1823                     break;
1824                 case CMD_GET_CELL_LOCATION: {
1825                     request = (MainThreadRequest) msg.obj;
1826                     WorkSource ws = (WorkSource) request.argument;
1827                     Phone phone = getPhoneFromRequest(request);
1828                     phone.getCellIdentity(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
1829                     break;
1830                 }
1831                 case EVENT_GET_CELL_LOCATION_DONE: {
1832                     ar = (AsyncResult) msg.obj;
1833                     request = (MainThreadRequest) ar.userObj;
1834                     if (ar.exception == null) {
1835                         request.result = ar.result;
1836                     } else {
1837                         Phone phone = getPhoneFromRequest(request);
1838                         request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
1839                                 ? new CellIdentityCdma() : new CellIdentityGsm();
1840                     }
1841 
1842                     synchronized (request) {
1843                         request.notifyAll();
1844                     }
1845                     break;
1846                 }
1847                 case CMD_MODEM_REBOOT:
1848                     request = (MainThreadRequest) msg.obj;
1849                     onCompleted = obtainMessage(EVENT_CMD_MODEM_REBOOT_DONE, request);
1850                     defaultPhone.rebootModem(onCompleted);
1851                     break;
1852                 case EVENT_CMD_MODEM_REBOOT_DONE:
1853                     handleNullReturnEvent(msg, "rebootModem");
1854                     break;
1855                 case CMD_REQUEST_ENABLE_MODEM: {
1856                     request = (MainThreadRequest) msg.obj;
1857                     boolean enable = (boolean) request.argument;
1858                     onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
1859                     onCompleted.arg1 = enable ? 1 : 0;
1860                     PhoneConfigurationManager.getInstance()
1861                             .enablePhone(request.phone, enable, onCompleted);
1862                     break;
1863                 }
1864                 case EVENT_ENABLE_MODEM_DONE: {
1865                     ar = (AsyncResult) msg.obj;
1866                     request = (MainThreadRequest) ar.userObj;
1867                     request.result = (ar.exception == null);
1868                     int phoneId = request.phone.getPhoneId();
1869                     //update the cache as modem status has changed
1870                     if ((boolean) request.result) {
1871                         mPhoneConfigurationManager.addToPhoneStatusCache(phoneId, msg.arg1 == 1);
1872                         updateModemStateMetrics();
1873                     } else {
1874                         Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1875                                 + ar.exception);
1876                     }
1877                     notifyRequester(request);
1878                     break;
1879                 }
1880                 case CMD_GET_MODEM_STATUS:
1881                     request = (MainThreadRequest) msg.obj;
1882                     onCompleted = obtainMessage(EVENT_GET_MODEM_STATUS_DONE, request);
1883                     PhoneConfigurationManager.getInstance()
1884                             .getPhoneStatusFromModem(request.phone, onCompleted);
1885                     break;
1886                 case EVENT_GET_MODEM_STATUS_DONE:
1887                     ar = (AsyncResult) msg.obj;
1888                     request = (MainThreadRequest) ar.userObj;
1889                     int id = request.phone.getPhoneId();
1890                     if (ar.exception == null && ar.result != null) {
1891                         request.result = ar.result;
1892                         //update the cache as modem status has changed
1893                         mPhoneConfigurationManager.addToPhoneStatusCache(id,
1894                                 (boolean) request.result);
1895                     } else {
1896                         // Return true if modem status cannot be retrieved. For most cases,
1897                         // modem status is on. And for older version modems, GET_MODEM_STATUS
1898                         // and disable modem are not supported. Modem is always on.
1899                         // TODO: this should be fixed in R to support a third
1900                         // status UNKNOWN b/131631629
1901                         request.result = true;
1902                         Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1903                                 + ar.exception);
1904                     }
1905                     notifyRequester(request);
1906                     break;
1907                 case CMD_SET_SYSTEM_SELECTION_CHANNELS: {
1908                     request = (MainThreadRequest) msg.obj;
1909                     onCompleted = obtainMessage(EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1910                     Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1911                             (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1912                     request.phone.setSystemSelectionChannels(args.first, onCompleted);
1913                     break;
1914                 }
1915                 case EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE: {
1916                     ar = (AsyncResult) msg.obj;
1917                     request = (MainThreadRequest) ar.userObj;
1918                     Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1919                             (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1920                     args.second.accept(ar.exception == null);
1921                     notifyRequester(request);
1922                     break;
1923                 }
1924                 case CMD_GET_SYSTEM_SELECTION_CHANNELS: {
1925                     request = (MainThreadRequest) msg.obj;
1926                     onCompleted = obtainMessage(EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1927                     Phone phone = getPhoneFromRequest(request);
1928                     if (phone != null) {
1929                         phone.getSystemSelectionChannels(onCompleted);
1930                     } else {
1931                         loge("getSystemSelectionChannels: No phone object");
1932                         request.result = new ArrayList<RadioAccessSpecifier>();
1933                         notifyRequester(request);
1934                     }
1935                     break;
1936                 }
1937                 case EVENT_GET_SYSTEM_SELECTION_CHANNELS_DONE:
1938                     ar = (AsyncResult) msg.obj;
1939                     request = (MainThreadRequest) ar.userObj;
1940                     if (ar.exception == null && ar.result != null) {
1941                         request.result = ar.result;
1942                     } else {
1943                         request.result = new IllegalStateException(
1944                                 "Failed to retrieve system selecton channels");
1945                         if (ar.result == null) {
1946                             loge("getSystemSelectionChannels: Empty response");
1947                         } else {
1948                             loge("getSystemSelectionChannels: Unknown exception");
1949                         }
1950                     }
1951                     notifyRequester(request);
1952                     break;
1953                 case EVENT_SET_FORBIDDEN_PLMNS_DONE:
1954                     ar = (AsyncResult) msg.obj;
1955                     request = (MainThreadRequest) ar.userObj;
1956                     if (ar.exception == null && ar.result != null) {
1957                         request.result = ar.result;
1958                     } else {
1959                         request.result = -1;
1960                         loge("Failed to set Forbidden Plmns");
1961                         if (ar.result == null) {
1962                             loge("setForbidenPlmns: Empty response");
1963                         } else if (ar.exception != null) {
1964                             loge("setForbiddenPlmns: Exception: " + ar.exception);
1965                             request.result = -1;
1966                         } else {
1967                             loge("setForbiddenPlmns: Unknown exception");
1968                         }
1969                     }
1970                     notifyRequester(request);
1971                     break;
1972                 case CMD_SET_FORBIDDEN_PLMNS:
1973                     request = (MainThreadRequest) msg.obj;
1974                     uiccPort = getUiccPortFromRequest(request);
1975                     if (uiccPort == null) {
1976                         loge("setForbiddenPlmns: UiccPort is null");
1977                         request.result = -1;
1978                         notifyRequester(request);
1979                         break;
1980                     }
1981                     Pair<Integer, List<String>> setFplmnsArgs =
1982                             (Pair<Integer, List<String>>) request.argument;
1983                     appType = setFplmnsArgs.first;
1984                     List<String> fplmns = setFplmnsArgs.second;
1985                     uiccApp = uiccPort.getApplicationByType(appType);
1986                     if (uiccApp == null) {
1987                         loge("setForbiddenPlmns: no app with specified type -- " + appType);
1988                         request.result = -1;
1989                         loge("Failed to get UICC App");
1990                         notifyRequester(request);
1991                     } else {
1992                         onCompleted = obtainMessage(EVENT_SET_FORBIDDEN_PLMNS_DONE, request);
1993                         ((SIMRecords) uiccApp.getIccRecords())
1994                                 .setForbiddenPlmns(onCompleted, fplmns);
1995                     }
1996                     break;
1997                 case CMD_ERASE_MODEM_CONFIG:
1998                     request = (MainThreadRequest) msg.obj;
1999                     onCompleted = obtainMessage(EVENT_ERASE_MODEM_CONFIG_DONE, request);
2000                     defaultPhone.eraseModemConfig(onCompleted);
2001                     break;
2002                 case EVENT_ERASE_MODEM_CONFIG_DONE:
2003                     handleNullReturnEvent(msg, "eraseModemConfig");
2004                     break;
2005 
2006                 case CMD_ERASE_DATA_SHARED_PREFERENCES:
2007                     request = (MainThreadRequest) msg.obj;
2008                     request.result = defaultPhone.eraseDataInSharedPreferences();
2009                     notifyRequester(request);
2010                     break;
2011 
2012                 case CMD_CHANGE_ICC_LOCK_PASSWORD:
2013                     request = (MainThreadRequest) msg.obj;
2014                     onCompleted = obtainMessage(EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE, request);
2015                     Pair<String, String> changed = (Pair<String, String>) request.argument;
2016                     getPhoneFromRequest(request).getIccCard().changeIccLockPassword(
2017                             changed.first, changed.second, onCompleted);
2018                     break;
2019                 case EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE:
2020                     ar = (AsyncResult) msg.obj;
2021                     request = (MainThreadRequest) ar.userObj;
2022                     if (ar.exception == null) {
2023                         request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
2024                         // If the operation is successful, update the PIN storage
2025                         Pair<String, String> passwords = (Pair<String, String>) request.argument;
2026                         int phoneId = getPhoneFromRequest(request).getPhoneId();
2027                         UiccController.getInstance().getPinStorage()
2028                                 .storePin(passwords.second, phoneId);
2029                     } else {
2030                         request.result = msg.arg1;
2031                     }
2032                     notifyRequester(request);
2033                     break;
2034 
2035                 case CMD_SET_ICC_LOCK_ENABLED: {
2036                     request = (MainThreadRequest) msg.obj;
2037                     onCompleted = obtainMessage(EVENT_SET_ICC_LOCK_ENABLED_DONE, request);
2038                     Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
2039                     getPhoneFromRequest(request).getIccCard().setIccLockEnabled(
2040                             enabled.first, enabled.second, onCompleted);
2041                     break;
2042                 }
2043                 case EVENT_SET_ICC_LOCK_ENABLED_DONE:
2044                     ar = (AsyncResult) msg.obj;
2045                     request = (MainThreadRequest) ar.userObj;
2046                     if (ar.exception == null) {
2047                         request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
2048                         // If the operation is successful, update the PIN storage
2049                         Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
2050                         int phoneId = getPhoneFromRequest(request).getPhoneId();
2051                         if (enabled.first) {
2052                             UiccController.getInstance().getPinStorage()
2053                                     .storePin(enabled.second, phoneId);
2054                         } else {
2055                             UiccController.getInstance().getPinStorage().clearPin(phoneId);
2056                         }
2057                     } else {
2058                         request.result = msg.arg1;
2059                     }
2060 
2061 
2062                     notifyRequester(request);
2063                     break;
2064 
2065                 case MSG_NOTIFY_USER_ACTIVITY:
2066                     removeMessages(MSG_NOTIFY_USER_ACTIVITY);
2067                     Intent intent = new Intent(TelephonyIntents.ACTION_USER_ACTIVITY_NOTIFICATION);
2068                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
2069                     getDefaultPhone().getContext().sendBroadcastAsUser(
2070                             intent, UserHandle.ALL, permission.USER_ACTIVITY);
2071                     break;
2072 
2073                 case CMD_SET_DATA_THROTTLING: {
2074                     request = (MainThreadRequest) msg.obj;
2075                     onCompleted = obtainMessage(EVENT_SET_DATA_THROTTLING_DONE, request);
2076                     DataThrottlingRequest dataThrottlingRequest =
2077                             (DataThrottlingRequest) request.argument;
2078                     Phone phone = getPhoneFromRequest(request);
2079                     if (phone != null) {
2080                         phone.setDataThrottling(onCompleted,
2081                                 request.workSource, dataThrottlingRequest.getDataThrottlingAction(),
2082                                 dataThrottlingRequest.getCompletionDurationMillis());
2083                     } else {
2084                         loge("setDataThrottling: No phone object");
2085                         request.result =
2086                                 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
2087                         notifyRequester(request);
2088                     }
2089 
2090                     break;
2091                 }
2092                 case EVENT_SET_DATA_THROTTLING_DONE:
2093                     ar = (AsyncResult) msg.obj;
2094                     request = (MainThreadRequest) ar.userObj;
2095 
2096                     if (ar.exception == null) {
2097                         request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
2098                     } else if (ar.exception instanceof CommandException) {
2099                         loge("setDataThrottling: CommandException: " + ar.exception);
2100                         CommandException.Error error =
2101                                 ((CommandException) (ar.exception)).getCommandError();
2102 
2103                         if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
2104                             request.result = TelephonyManager
2105                                     .THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
2106                         } else if (error == CommandException.Error.INVALID_ARGUMENTS) {
2107                             request.result = SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS;
2108                         } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
2109                             request.result = MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE;
2110                         } else {
2111                             request.result =
2112                                     TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
2113                         }
2114                     } else {
2115                         request.result = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
2116                     }
2117                     Log.w(LOG_TAG, "DataThrottlingResult = " + request.result);
2118                     notifyRequester(request);
2119                     break;
2120 
2121                 case CMD_SET_SIM_POWER: {
2122                     request = (MainThreadRequest) msg.obj;
2123                     onCompleted = obtainMessage(EVENT_SET_SIM_POWER_DONE, request);
2124                     request = (MainThreadRequest) msg.obj;
2125                     int stateToSet =
2126                             ((Pair<Integer, IIntegerConsumer>)
2127                                     request.argument).first;
2128                     request.phone.setSimPowerState(stateToSet, onCompleted, request.workSource);
2129                     break;
2130                 }
2131                 case EVENT_SET_SIM_POWER_DONE: {
2132                     ar = (AsyncResult) msg.obj;
2133                     request = (MainThreadRequest) ar.userObj;
2134                     IIntegerConsumer callback =
2135                             ((Pair<Integer, IIntegerConsumer>) request.argument).second;
2136                     if (ar.exception != null) {
2137                         loge("setSimPower exception: " + ar.exception);
2138                         int errorCode = TelephonyManager.CallForwardingInfoCallback
2139                                 .RESULT_ERROR_UNKNOWN;
2140                         if (ar.exception instanceof CommandException) {
2141                             CommandException.Error error =
2142                                     ((CommandException) (ar.exception)).getCommandError();
2143                             if (error == CommandException.Error.SIM_ERR) {
2144                                 errorCode = TelephonyManager.SET_SIM_POWER_STATE_SIM_ERROR;
2145                             } else if (error == CommandException.Error.INVALID_ARGUMENTS) {
2146                                 errorCode = TelephonyManager.SET_SIM_POWER_STATE_ALREADY_IN_STATE;
2147                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
2148                                 errorCode = TelephonyManager.SET_SIM_POWER_STATE_NOT_SUPPORTED;
2149                             } else {
2150                                 errorCode = TelephonyManager.SET_SIM_POWER_STATE_MODEM_ERROR;
2151                             }
2152                         }
2153                         try {
2154                             callback.accept(errorCode);
2155                         } catch (RemoteException e) {
2156                             // Ignore if the remote process is no longer available to call back.
2157                             Log.w(LOG_TAG, "setSimPower: callback not available.");
2158                         }
2159                     } else {
2160                         try {
2161                             callback.accept(TelephonyManager.SET_SIM_POWER_STATE_SUCCESS);
2162                         } catch (RemoteException e) {
2163                             // Ignore if the remote process is no longer available to call back.
2164                             Log.w(LOG_TAG, "setSimPower: callback not available.");
2165                         }
2166                     }
2167                     break;
2168                 }
2169                 case CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST: {
2170                     request = (MainThreadRequest) msg.obj;
2171 
2172                     final Phone phone = getPhoneFromRequest(request);
2173                     if (phone == null || phone.getServiceStateTracker() == null) {
2174                         request.result = new IllegalStateException("Phone or SST is null");
2175                         notifyRequester(request);
2176                         break;
2177                     }
2178 
2179                     Pair<Integer, SignalStrengthUpdateRequest> pair =
2180                             (Pair<Integer, SignalStrengthUpdateRequest>) request.argument;
2181                     onCompleted = obtainMessage(EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE,
2182                             request);
2183                     phone.getSignalStrengthController().setSignalStrengthUpdateRequest(
2184                             request.subId, pair.first /*callingUid*/,
2185                             pair.second /*request*/, onCompleted);
2186                     break;
2187                 }
2188                 case EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE: {
2189                     ar = (AsyncResult) msg.obj;
2190                     request = (MainThreadRequest) ar.userObj;
2191                     // request.result will be the exception of ar if present, true otherwise.
2192                     // Be cautious not to leave result null which will wait() forever
2193                     request.result = ar.exception != null ? ar.exception : true;
2194                     notifyRequester(request);
2195                     break;
2196                 }
2197                 case CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST: {
2198                     request = (MainThreadRequest) msg.obj;
2199 
2200                     Phone phone = getPhoneFromRequest(request);
2201                     if (phone == null || phone.getServiceStateTracker() == null) {
2202                         request.result = new IllegalStateException("Phone or SST is null");
2203                         notifyRequester(request);
2204                         break;
2205                     }
2206 
2207                     Pair<Integer, SignalStrengthUpdateRequest> pair =
2208                             (Pair<Integer, SignalStrengthUpdateRequest>) request.argument;
2209                     onCompleted = obtainMessage(EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE,
2210                             request);
2211                     phone.getSignalStrengthController().clearSignalStrengthUpdateRequest(
2212                             request.subId, pair.first /*callingUid*/,
2213                             pair.second /*request*/, onCompleted);
2214                     break;
2215                 }
2216                 case EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST_DONE: {
2217                     ar = (AsyncResult) msg.obj;
2218                     request = (MainThreadRequest) ar.userObj;
2219                     request.result = ar.exception != null ? ar.exception : true;
2220                     notifyRequester(request);
2221                     break;
2222                 }
2223 
2224                 case CMD_GET_SLICING_CONFIG: {
2225                     request = (MainThreadRequest) msg.obj;
2226                     onCompleted = obtainMessage(EVENT_GET_SLICING_CONFIG_DONE, request);
2227                     request.phone.getSlicingConfig(onCompleted);
2228                     break;
2229                 }
2230                 case EVENT_GET_SLICING_CONFIG_DONE: {
2231                     ar = (AsyncResult) msg.obj;
2232                     request = (MainThreadRequest) ar.userObj;
2233                     ResultReceiver result = (ResultReceiver) request.argument;
2234 
2235                     NetworkSlicingConfig slicingConfig = null;
2236                     Bundle bundle = new Bundle();
2237                     int resultCode = 0;
2238                     if (ar.exception != null) {
2239                         Log.e(LOG_TAG, "Exception retrieving slicing configuration="
2240                                 + ar.exception);
2241                         resultCode = TelephonyManager.NetworkSlicingException.ERROR_MODEM_ERROR;
2242                     } else if (ar.result == null) {
2243                         Log.w(LOG_TAG, "Timeout Waiting for slicing configuration!");
2244                         resultCode = TelephonyManager.NetworkSlicingException.ERROR_TIMEOUT;
2245                     } else {
2246                         // use the result as returned
2247                         resultCode = TelephonyManager.NetworkSlicingException.SUCCESS;
2248                         slicingConfig = (NetworkSlicingConfig) ar.result;
2249                     }
2250 
2251                     if (slicingConfig == null) {
2252                         slicingConfig = new NetworkSlicingConfig();
2253                     }
2254                     bundle.putParcelable(TelephonyManager.KEY_SLICING_CONFIG_HANDLE, slicingConfig);
2255                     result.send(resultCode, bundle);
2256                     notifyRequester(request);
2257                     break;
2258                 }
2259 
2260                 case CMD_PURCHASE_PREMIUM_CAPABILITY: {
2261                     request = (MainThreadRequest) msg.obj;
2262                     onCompleted = obtainMessage(EVENT_PURCHASE_PREMIUM_CAPABILITY_DONE, request);
2263                     PurchasePremiumCapabilityArgument arg =
2264                             (PurchasePremiumCapabilityArgument) request.argument;
2265                     SlicePurchaseController.getInstance(request.phone, mFeatureFlags)
2266                             .purchasePremiumCapability(arg.capability, onCompleted);
2267                     break;
2268                 }
2269 
2270                 case EVENT_PURCHASE_PREMIUM_CAPABILITY_DONE: {
2271                     ar = (AsyncResult) msg.obj;
2272                     request = (MainThreadRequest) ar.userObj;
2273                     PurchasePremiumCapabilityArgument arg =
2274                             (PurchasePremiumCapabilityArgument) request.argument;
2275                     try {
2276                         int result = (int) ar.result;
2277                         arg.callback.accept(result);
2278                         log("purchasePremiumCapability: capability="
2279                                 + TelephonyManager.convertPremiumCapabilityToString(arg.capability)
2280                                 + ", result="
2281                                 + TelephonyManager.convertPurchaseResultToString(result));
2282                     } catch (RemoteException e) {
2283                         String logStr = "Purchase premium capability "
2284                                 + TelephonyManager.convertPremiumCapabilityToString(arg.capability)
2285                                 + " failed: " + e;
2286                         if (DBG) log(logStr);
2287                         AnomalyReporter.reportAnomaly(
2288                                 UUID.fromString(PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID), logStr);
2289                     }
2290                     break;
2291                 }
2292 
2293                 case CMD_PREPARE_UNATTENDED_REBOOT:
2294                     request = (MainThreadRequest) msg.obj;
2295                     request.result =
2296                             UiccController.getInstance().getPinStorage()
2297                                     .prepareUnattendedReboot(request.workSource);
2298                     notifyRequester(request);
2299                     break;
2300 
2301                 default:
2302                     Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
2303                     break;
2304             }
2305         }
2306 
notifyRequester(MainThreadRequest request)2307         private void notifyRequester(MainThreadRequest request) {
2308             synchronized (request) {
2309                 request.notifyAll();
2310             }
2311         }
2312 
handleNullReturnEvent(Message msg, String command)2313         private void handleNullReturnEvent(Message msg, String command) {
2314             AsyncResult ar = (AsyncResult) msg.obj;
2315             MainThreadRequest request = (MainThreadRequest) ar.userObj;
2316             if (ar.exception == null) {
2317                 request.result = true;
2318             } else {
2319                 request.result = false;
2320                 if (ar.exception instanceof CommandException) {
2321                     loge(command + ": CommandException: " + ar.exception);
2322                 } else {
2323                     loge(command + ": Unknown exception");
2324                 }
2325             }
2326             notifyRequester(request);
2327         }
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)2335     private Object sendRequest(int command, Object argument) {
2336         return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null,
2337                 null, -1 /*timeoutInMs*/);
2338     }
2339 
2340     /**
2341      * Posts the specified command to be executed on the main thread,
2342      * waits for the request to complete, and returns the result.
2343      * @see #sendRequestAsync
2344      */
sendRequest(int command, Object argument, WorkSource workSource)2345     private Object sendRequest(int command, Object argument, WorkSource workSource) {
2346         return sendRequest(command, argument,  SubscriptionManager.INVALID_SUBSCRIPTION_ID,
2347                 null, workSource, -1 /*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, Integer subId)2355     private Object sendRequest(int command, Object argument, Integer subId) {
2356         return sendRequest(command, argument, subId, null, null, -1 /*timeoutInMs*/);
2357     }
2358 
2359     /**
2360      * Posts the specified command to be executed on the main thread,
2361      * waits for the request to complete for at most {@code timeoutInMs}, and returns the result
2362      * if not timeout or null otherwise.
2363      * @see #sendRequestAsync
2364      */
sendRequest(int command, Object argument, Integer subId, long timeoutInMs)2365     private @Nullable Object sendRequest(int command, Object argument, Integer subId,
2366             long timeoutInMs) {
2367         return sendRequest(command, argument, subId, null, null, timeoutInMs);
2368     }
2369 
2370     /**
2371      * Posts the specified command to be executed on the main thread,
2372      * waits for the request to complete, and returns the result.
2373      * @see #sendRequestAsync
2374      */
sendRequest(int command, Object argument, int subId, WorkSource workSource)2375     private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
2376         return sendRequest(command, argument, subId, null, workSource, -1 /*timeoutInMs*/);
2377     }
2378 
2379     /**
2380      * Posts the specified command to be executed on the main thread,
2381      * waits for the request to complete, and returns the result.
2382      * @see #sendRequestAsync
2383      */
sendRequest(int command, Object argument, Phone phone, WorkSource workSource)2384     private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
2385         return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone,
2386                 workSource, -1 /*timeoutInMs*/);
2387     }
2388 
2389     /**
2390      * Posts the specified command to be executed on the main thread. If {@code timeoutInMs} is
2391      * negative, waits for the request to complete, and returns the result. Otherwise, wait for
2392      * maximum of {@code timeoutInMs} milliseconds, interrupt and return null.
2393      * @see #sendRequestAsync
2394      */
sendRequest(int command, Object argument, Integer subId, Phone phone, WorkSource workSource, long timeoutInMs)2395     private @Nullable Object sendRequest(int command, Object argument, Integer subId, Phone phone,
2396             WorkSource workSource, long timeoutInMs) {
2397         if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
2398             throw new RuntimeException("This method will deadlock if called from the main thread.");
2399         }
2400 
2401         MainThreadRequest request = null;
2402         if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
2403             throw new IllegalArgumentException("subId and phone cannot both be specified!");
2404         } else if (phone != null) {
2405             request = new MainThreadRequest(argument, phone, workSource);
2406         } else {
2407             request = new MainThreadRequest(argument, subId, workSource);
2408         }
2409 
2410         Message msg = mMainThreadHandler.obtainMessage(command, request);
2411         msg.sendToTarget();
2412 
2413 
2414         synchronized (request) {
2415             if (timeoutInMs >= 0) {
2416                 // Wait for at least timeoutInMs before returning null request result
2417                 long now = SystemClock.elapsedRealtime();
2418                 long deadline = now + timeoutInMs;
2419                 while (request.result == null && now < deadline) {
2420                     try {
2421                         request.wait(deadline - now);
2422                     } catch (InterruptedException e) {
2423                         // Do nothing, go back and check if request is completed or timeout
2424                     } finally {
2425                         now = SystemClock.elapsedRealtime();
2426                     }
2427                 }
2428             } else {
2429                 // Wait for the request to complete
2430                 while (request.result == null) {
2431                     try {
2432                         request.wait();
2433                     } catch (InterruptedException e) {
2434                         // Do nothing, go back and wait until the request is complete
2435                     }
2436                 }
2437             }
2438         }
2439         if (request.result == null) {
2440             Log.wtf(LOG_TAG,
2441                     "sendRequest: Blocking command timed out. Something has gone terribly wrong.");
2442         }
2443         return request.result;
2444     }
2445 
2446     /**
2447      * Asynchronous ("fire and forget") version of sendRequest():
2448      * Posts the specified command to be executed on the main thread, and
2449      * returns immediately.
2450      * @see #sendRequest
2451      */
sendRequestAsync(int command)2452     private void sendRequestAsync(int command) {
2453         mMainThreadHandler.sendEmptyMessage(command);
2454     }
2455 
2456     /**
2457      * Same as {@link #sendRequestAsync(int)} except it takes an argument.
2458      * @see {@link #sendRequest(int)}
2459      */
sendRequestAsync(int command, Object argument)2460     private void sendRequestAsync(int command, Object argument) {
2461         sendRequestAsync(command, argument, null, null);
2462     }
2463 
2464     /**
2465      * Same as {@link #sendRequestAsync(int,Object)} except it takes a Phone and WorkSource.
2466      * @see {@link #sendRequest(int,Object)}
2467      */
sendRequestAsync( int command, Object argument, Phone phone, WorkSource workSource)2468     private void sendRequestAsync(
2469             int command, Object argument, Phone phone, WorkSource workSource) {
2470         MainThreadRequest request = new MainThreadRequest(argument, phone, workSource);
2471         Message msg = mMainThreadHandler.obtainMessage(command, request);
2472         msg.sendToTarget();
2473     }
2474 
2475     /**
2476      * Initialize the singleton PhoneInterfaceManager instance.
2477      * This is only done once, at startup, from PhoneApp.onCreate().
2478      */
init(PhoneGlobals app, FeatureFlags featureFlags)2479     /* package */ static PhoneInterfaceManager init(PhoneGlobals app, FeatureFlags featureFlags) {
2480         synchronized (PhoneInterfaceManager.class) {
2481             if (sInstance == null) {
2482                 sInstance = new PhoneInterfaceManager(app, featureFlags);
2483             } else {
2484                 Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
2485             }
2486             return sInstance;
2487         }
2488     }
2489 
2490     /** Private constructor; @see init() */
PhoneInterfaceManager(PhoneGlobals app, FeatureFlags featureFlags)2491     private PhoneInterfaceManager(PhoneGlobals app, FeatureFlags featureFlags) {
2492         mApp = app;
2493         mFeatureFlags = featureFlags;
2494         mTelecomFeatureFlags = new com.android.server.telecom.flags.FeatureFlagsImpl();
2495         mCM = PhoneGlobals.getInstance().mCM;
2496         mImsResolver = ImsResolver.getInstance();
2497         mSatelliteController = SatelliteController.getInstance();
2498         mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
2499         mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
2500         mMainThreadHandler = new MainThreadHandler();
2501         mTelephonySharedPreferences = PreferenceManager.getDefaultSharedPreferences(mApp);
2502         mNetworkScanRequestTracker = new NetworkScanRequestTracker();
2503         mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
2504         mRadioInterfaceCapabilities = RadioInterfaceCapabilityController.getInstance();
2505         mNotifyUserActivity = new AtomicBoolean(false);
2506         mPackageManager = app.getPackageManager();
2507         mSatelliteAccessController = SatelliteAccessController.getOrCreateInstance(
2508                 getDefaultPhone().getContext(), featureFlags);
2509         mVendorApiLevel = SystemProperties.getInt(
2510                 "ro.vendor.api_level", Build.VERSION.DEVICE_INITIAL_SDK_INT);
2511 
2512         PropertyInvalidatedCache.invalidateCache(TelephonyManager.CACHE_KEY_PHONE_ACCOUNT_TO_SUBID);
2513         publish();
2514         CarrierAllowListInfo.loadInstance(mApp);
2515 
2516         // Create the SatelliteEntitlementController singleton, for using the get the
2517         // entitlementStatus for satellite service.
2518         SatelliteEntitlementController.make(mApp, mFeatureFlags);
2519     }
2520 
2521     @VisibleForTesting
getSharedPreferences()2522     public SharedPreferences getSharedPreferences() {
2523         return mTelephonySharedPreferences;
2524     }
2525 
2526     /**
2527      * Get the default phone for this device.
2528      */
2529     @VisibleForTesting
getDefaultPhone()2530     public Phone getDefaultPhone() {
2531         Phone thePhone = getPhone(getDefaultSubscription());
2532         return (thePhone != null) ? thePhone : PhoneFactory.getDefaultPhone();
2533     }
2534 
publish()2535     private void publish() {
2536         if (DBG) log("publish: " + this);
2537 
2538         TelephonyFrameworkInitializer
2539                 .getTelephonyServiceManager()
2540                 .getTelephonyServiceRegisterer()
2541                 .register(this);
2542     }
2543 
getPhoneFromRequest(MainThreadRequest request)2544     private Phone getPhoneFromRequest(MainThreadRequest request) {
2545         if (request.phone != null) {
2546             return request.phone;
2547         } else {
2548             return getPhoneFromSubId(request.subId);
2549         }
2550     }
2551 
getPhoneFromSubId(int subId)2552     private Phone getPhoneFromSubId(int subId) {
2553         return (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
2554                 ? getDefaultPhone() : getPhone(subId);
2555     }
2556 
2557     /**
2558      * Get phone object associated with a subscription.
2559      * Return default phone if phone object associated with subscription is null
2560      * @param subId - subscriptionId
2561      * @return phone object associated with a subscription or default phone if null.
2562      */
getPhoneFromSubIdOrDefault(int subId)2563     private @NonNull Phone getPhoneFromSubIdOrDefault(int subId) {
2564         Phone phone = getPhoneFromSubId(subId);
2565         if (phone == null) {
2566             loge("Called with invalid subId: " + subId + ". Retrying with default phone.");
2567             phone = getDefaultPhone();
2568         }
2569         return phone;
2570     }
2571 
2572     @Nullable
getUiccPortFromRequest(@onNull MainThreadRequest request)2573     private UiccPort getUiccPortFromRequest(@NonNull MainThreadRequest request) {
2574         Phone phone = getPhoneFromRequest(request);
2575         return phone == null ? null :
2576                 UiccController.getInstance().getUiccPort(phone.getPhoneId());
2577     }
2578 
2579     /**
2580      * @param subId The sub Id that associates the phone. If the device has no active SIM, passing
2581      *              in {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} or any sub <=
2582      *              {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} will return {@code null}.
2583      * @return The Phone associated the sub Id
2584      */
getPhone(int subId)2585     private @Nullable Phone getPhone(int subId) {
2586         return PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId));
2587     }
2588 
sendEraseModemConfig(@onNull Phone phone)2589     private void sendEraseModemConfig(@NonNull Phone phone) {
2590         int cmd = mFeatureFlags.cleanupCdma() ? CMD_MODEM_REBOOT : CMD_ERASE_MODEM_CONFIG;
2591         Boolean success = (Boolean) sendRequest(cmd, null);
2592         if (DBG) log("eraseModemConfig:" + ' ' + (success ? "ok" : "fail"));
2593     }
2594 
sendEraseDataInSharedPreferences(@onNull Phone phone)2595     private void sendEraseDataInSharedPreferences(@NonNull Phone phone) {
2596         Boolean success = (Boolean) sendRequest(CMD_ERASE_DATA_SHARED_PREFERENCES, null);
2597         if (DBG) log("eraseDataInSharedPreferences:" + ' ' + (success ? "ok" : "fail"));
2598     }
2599 
isImsAvailableOnDevice()2600     private boolean isImsAvailableOnDevice() {
2601         PackageManager pm = getDefaultPhone().getContext().getPackageManager();
2602         if (pm == null) {
2603             // For some reason package manger is not available.. This will fail internally anyway,
2604             // so do not throw error and allow.
2605             return true;
2606         }
2607         return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS, 0);
2608     }
2609 
dial(String number)2610     public void dial(String number) {
2611         enforceTelephonyFeatureWithException(getCurrentPackageName(),
2612                 PackageManager.FEATURE_TELEPHONY_CALLING, "dial");
2613 
2614         dialForSubscriber(getPreferredVoiceSubscription(), number);
2615     }
2616 
dialForSubscriber(int subId, String number)2617     public void dialForSubscriber(int subId, String number) {
2618         if (DBG) log("dial: " + number);
2619         // No permission check needed here: This is just a wrapper around the
2620         // ACTION_DIAL intent, which is available to any app since it puts up
2621         // the UI before it does anything.
2622 
2623         final long identity = Binder.clearCallingIdentity();
2624         try {
2625             String url = createTelUrl(number);
2626             if (url == null) {
2627                 return;
2628             }
2629 
2630             // PENDING: should we just silently fail if phone is offhook or ringing?
2631             PhoneConstants.State state = mCM.getState(subId);
2632             if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
2633                 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
2634                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2635                 mApp.startActivityAsUser(intent, UserHandle.CURRENT);
2636             }
2637         } finally {
2638             Binder.restoreCallingIdentity(identity);
2639         }
2640     }
2641 
call(String callingPackage, String number)2642     public void call(String callingPackage, String number) {
2643         callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
2644     }
2645 
callForSubscriber(int subId, String callingPackage, String number)2646     public void callForSubscriber(int subId, String callingPackage, String number) {
2647         if (DBG) log("call: " + number);
2648 
2649         // This is just a wrapper around the ACTION_CALL intent, but we still
2650         // need to do a permission check since we're calling startActivityAsUser()
2651         // from the context of the phone app.
2652         enforceCallPermission();
2653 
2654         if (mAppOps.noteOp(AppOpsManager.OPSTR_CALL_PHONE, Binder.getCallingUid(), callingPackage)
2655                 != AppOpsManager.MODE_ALLOWED) {
2656             return;
2657         }
2658 
2659         enforceTelephonyFeatureWithException(callingPackage,
2660                 PackageManager.FEATURE_TELEPHONY_CALLING, "call");
2661 
2662         final long identity = Binder.clearCallingIdentity();
2663         try {
2664             String url = createTelUrl(number);
2665             if (url == null) {
2666                 return;
2667             }
2668 
2669             boolean isValid = false;
2670             final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
2671             if (slist != null) {
2672                 for (SubscriptionInfo subInfoRecord : slist) {
2673                     if (subInfoRecord.getSubscriptionId() == subId) {
2674                         isValid = true;
2675                         break;
2676                     }
2677                 }
2678             }
2679             if (!isValid) {
2680                 return;
2681             }
2682 
2683             Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
2684             intent.putExtra(SUBSCRIPTION_KEY, subId);
2685             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2686             mApp.startActivityAsUser(intent, UserHandle.CURRENT);
2687         } finally {
2688             Binder.restoreCallingIdentity(identity);
2689         }
2690     }
2691 
supplyPinForSubscriber(int subId, String pin)2692     public boolean supplyPinForSubscriber(int subId, String pin) {
2693         int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
2694         return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
2695     }
2696 
supplyPukForSubscriber(int subId, String puk, String pin)2697     public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
2698         int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
2699         return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
2700     }
2701 
supplyPinReportResultForSubscriber(int subId, String pin)2702     public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
2703         enforceModifyPermission();
2704 
2705         enforceTelephonyFeatureWithException(getCurrentPackageName(),
2706                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
2707                 "supplyPinReportResultForSubscriber");
2708 
2709         final long identity = Binder.clearCallingIdentity();
2710         try {
2711             Phone phone = getPhone(subId);
2712             final UnlockSim checkSimPin = new UnlockSim(phone.getPhoneId(), phone.getIccCard());
2713             checkSimPin.start();
2714             return checkSimPin.unlockSim(null, pin);
2715         } finally {
2716             Binder.restoreCallingIdentity(identity);
2717         }
2718     }
2719 
supplyPukReportResultForSubscriber(int subId, String puk, String pin)2720     public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
2721         enforceModifyPermission();
2722 
2723         enforceTelephonyFeatureWithException(getCurrentPackageName(),
2724                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "supplyPukForSubscriber");
2725 
2726         final long identity = Binder.clearCallingIdentity();
2727         try {
2728             Phone phone = getPhone(subId);
2729             final UnlockSim checkSimPuk = new UnlockSim(phone.getPhoneId(), phone.getIccCard());
2730             checkSimPuk.start();
2731             return checkSimPuk.unlockSim(puk, pin);
2732         } finally {
2733             Binder.restoreCallingIdentity(identity);
2734         }
2735     }
2736 
2737     /**
2738      * Helper thread to turn async call to SimCard#supplyPin into
2739      * a synchronous one.
2740      */
2741     private static class UnlockSim extends Thread {
2742 
2743         private final IccCard mSimCard;
2744         private final int mPhoneId;
2745 
2746         private boolean mDone = false;
2747         private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
2748         private int mRetryCount = -1;
2749 
2750         // For replies from SimCard interface
2751         private Handler mHandler;
2752 
2753         // For async handler to identify request type
2754         private static final int SUPPLY_PIN_COMPLETE = 100;
2755         private static final int SUPPLY_PIN_DELAYED  = 101;
2756         private static final int SUPPLY_PIN_DELAYED_TIMER_IN_MILLIS = 10000;
2757         private static final UUID SUPPLY_PIN_UUID = UUID.fromString(
2758                 "d3768135-4323-491d-a6c8-bda01fc89040");
2759 
UnlockSim(int phoneId, IccCard simCard)2760         UnlockSim(int phoneId, IccCard simCard) {
2761             mPhoneId = phoneId;
2762             mSimCard = simCard;
2763         }
2764 
2765         @Override
run()2766         public void run() {
2767             Looper.prepare();
2768             synchronized (UnlockSim.this) {
2769                 mHandler = new Handler() {
2770                     @Override
2771                     public void handleMessage(Message msg) {
2772                         AsyncResult ar = (AsyncResult) msg.obj;
2773                         switch (msg.what) {
2774                             case SUPPLY_PIN_COMPLETE:
2775                                 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
2776                                 synchronized (UnlockSim.this) {
2777                                     mRetryCount = msg.arg1;
2778                                     if (ar.exception != null) {
2779                                         CommandException.Error error = null;
2780                                         if (ar.exception instanceof CommandException) {
2781                                             error = ((CommandException) (ar.exception))
2782                                                     .getCommandError();
2783                                         }
2784                                         if (error == CommandException.Error.PASSWORD_INCORRECT) {
2785                                             mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
2786                                         } else if (error == CommandException.Error.ABORTED) {
2787                                             /* When UiccCardApp dispose, handle message and return
2788                                              exception */
2789                                             mResult = PhoneConstants.PIN_OPERATION_ABORTED;
2790                                         } else {
2791                                             mResult = PhoneConstants.PIN_GENERAL_FAILURE;
2792                                         }
2793                                     } else {
2794                                         mResult = PhoneConstants.PIN_RESULT_SUCCESS;
2795                                     }
2796                                     mDone = true;
2797                                     removeMessages(SUPPLY_PIN_DELAYED);
2798                                     UnlockSim.this.notifyAll();
2799                                 }
2800                                 break;
2801                             case SUPPLY_PIN_DELAYED:
2802                                 if(!mDone) {
2803                                     String logStr = "Delay in receiving SIM PIN response ";
2804                                     if (DBG) log(logStr);
2805                                     AnomalyReporter.reportAnomaly(SUPPLY_PIN_UUID, logStr);
2806                                 }
2807                                 break;
2808                         }
2809                     }
2810                 };
2811                 UnlockSim.this.notifyAll();
2812             }
2813             Looper.loop();
2814         }
2815 
2816         /*
2817          * Use PIN or PUK to unlock SIM card
2818          *
2819          * If PUK is null, unlock SIM card with PIN
2820          *
2821          * If PUK is not null, unlock SIM card with PUK and set PIN code
2822          *
2823          * Besides, since it is reused in class level, the thread's looper will be stopped to avoid
2824          * its thread leak.
2825          */
unlockSim(String puk, String pin)2826         synchronized int[] unlockSim(String puk, String pin) {
2827 
2828             while (mHandler == null) {
2829                 try {
2830                     wait();
2831                 } catch (InterruptedException e) {
2832                     Thread.currentThread().interrupt();
2833                 }
2834             }
2835             Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
2836 
2837             if (puk == null) {
2838                 mSimCard.supplyPin(pin, callback);
2839             } else {
2840                 mSimCard.supplyPuk(puk, pin, callback);
2841             }
2842 
2843             while (!mDone) {
2844                 try {
2845                     Log.d(LOG_TAG, "wait for done");
2846                     mHandler.sendEmptyMessageDelayed(SUPPLY_PIN_DELAYED,
2847                             SUPPLY_PIN_DELAYED_TIMER_IN_MILLIS);
2848                     wait();
2849                 } catch (InterruptedException e) {
2850                     // Restore the interrupted status
2851                     Thread.currentThread().interrupt();
2852                 }
2853             }
2854             Log.d(LOG_TAG, "done");
2855             int[] resultArray = new int[2];
2856             resultArray[0] = mResult;
2857             resultArray[1] = mRetryCount;
2858 
2859             if (mResult == PhoneConstants.PIN_RESULT_SUCCESS && pin.length() > 0) {
2860                 UiccController.getInstance().getPinStorage().storePin(pin, mPhoneId);
2861             }
2862             // This instance is no longer reused, so quit its thread's looper.
2863             mHandler.getLooper().quitSafely();
2864 
2865             return resultArray;
2866         }
2867     }
2868 
2869     /**
2870      * This method has been removed due to privacy and stability concerns.
2871      */
2872     @Override
updateServiceLocation()2873     public void updateServiceLocation() {
2874         Log.e(LOG_TAG, "Call to unsupported method updateServiceLocation()");
2875         return;
2876     }
2877 
2878     @Override
updateServiceLocationWithPackageName(String callingPackage)2879     public void updateServiceLocationWithPackageName(String callingPackage) {
2880         mApp.getSystemService(AppOpsManager.class)
2881                 .checkPackage(Binder.getCallingUid(), callingPackage);
2882 
2883         final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
2884         if (targetSdk > android.os.Build.VERSION_CODES.R) {
2885             // Callers targeting S have no business invoking this method.
2886             return;
2887         }
2888 
2889         LocationAccessPolicy.LocationPermissionResult locationResult =
2890                 LocationAccessPolicy.checkLocationPermission(mApp,
2891                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
2892                                 .setCallingPackage(callingPackage)
2893                                 .setCallingFeatureId(null)
2894                                 .setCallingPid(Binder.getCallingPid())
2895                                 .setCallingUid(Binder.getCallingUid())
2896                                 .setMethod("updateServiceLocation")
2897                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2898                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2899                                 .build());
2900         // Apps that lack location permission have no business calling this method;
2901         // however, because no permission was declared in the public API, denials must
2902         // all be "soft".
2903         switch (locationResult) {
2904             case DENIED_HARD: /* fall through */
2905             case DENIED_SOFT:
2906                 return;
2907         }
2908 
2909         WorkSource workSource = getWorkSource(Binder.getCallingUid());
2910         final long identity = Binder.clearCallingIdentity();
2911         try {
2912             getPhoneFromSubIdOrDefault(getDefaultSubscription()).updateServiceLocation(workSource);
2913         } finally {
2914             Binder.restoreCallingIdentity(identity);
2915         }
2916     }
2917 
2918     @Deprecated
2919     @Override
isRadioOn(String callingPackage)2920     public boolean isRadioOn(String callingPackage) {
2921         return isRadioOnWithFeature(callingPackage, null);
2922     }
2923 
2924 
2925     @Override
isRadioOnWithFeature(String callingPackage, String callingFeatureId)2926     public boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId) {
2927         return isRadioOnForSubscriberWithFeature(getDefaultSubscription(), callingPackage,
2928                 callingFeatureId);
2929     }
2930 
2931     @Deprecated
2932     @Override
isRadioOnForSubscriber(int subId, String callingPackage)2933     public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
2934         return isRadioOnForSubscriberWithFeature(subId, callingPackage, null);
2935     }
2936 
2937     @Override
isRadioOnForSubscriberWithFeature(int subId, String callingPackage, String callingFeatureId)2938     public boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage,
2939             String callingFeatureId) {
2940         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2941                 mApp, subId, callingPackage, callingFeatureId, "isRadioOnForSubscriber")) {
2942             return false;
2943         }
2944 
2945         enforceTelephonyFeatureWithException(callingPackage,
2946                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "isRadioOnWithFeature");
2947 
2948         final long identity = Binder.clearCallingIdentity();
2949         try {
2950             return isRadioOnForSubscriber(subId);
2951         } finally {
2952             Binder.restoreCallingIdentity(identity);
2953         }
2954     }
2955 
isRadioOnForSubscriber(int subId)2956     private boolean isRadioOnForSubscriber(int subId) {
2957         final long identity = Binder.clearCallingIdentity();
2958         try {
2959             final Phone phone = getPhone(subId);
2960             if (phone != null) {
2961                 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
2962             } else {
2963                 return false;
2964             }
2965         } finally {
2966             Binder.restoreCallingIdentity(identity);
2967         }
2968     }
2969 
toggleRadioOnOff()2970     public void toggleRadioOnOff() {
2971         toggleRadioOnOffForSubscriber(getDefaultSubscription());
2972     }
2973 
toggleRadioOnOffForSubscriber(int subId)2974     public void toggleRadioOnOffForSubscriber(int subId) {
2975         enforceModifyPermission();
2976 
2977         enforceTelephonyFeatureWithException(getCurrentPackageName(),
2978                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "toggleRadioOnOffForSubscriber");
2979 
2980         final long identity = Binder.clearCallingIdentity();
2981         try {
2982             final Phone phone = getPhone(subId);
2983             if (phone != null) {
2984                 phone.setRadioPower(!isRadioOnForSubscriber(subId));
2985             }
2986         } finally {
2987             Binder.restoreCallingIdentity(identity);
2988         }
2989     }
2990 
setRadio(boolean turnOn)2991     public boolean setRadio(boolean turnOn) {
2992         return setRadioForSubscriber(getDefaultSubscription(), turnOn);
2993     }
2994 
setRadioForSubscriber(int subId, boolean turnOn)2995     public boolean setRadioForSubscriber(int subId, boolean turnOn) {
2996         enforceModifyPermission();
2997 
2998         final long identity = Binder.clearCallingIdentity();
2999         try {
3000             final Phone phone = getPhone(subId);
3001             if (phone == null) {
3002                 return false;
3003             }
3004             if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
3005                 toggleRadioOnOffForSubscriber(subId);
3006             }
3007             return true;
3008         } finally {
3009             Binder.restoreCallingIdentity(identity);
3010         }
3011     }
3012 
needMobileRadioShutdown()3013     public boolean needMobileRadioShutdown() {
3014         enforceReadPrivilegedPermission("needMobileRadioShutdown");
3015 
3016         if (!mApp.getResources().getBoolean(
3017                 com.android.internal.R.bool.config_force_phone_globals_creation)) {
3018             enforceTelephonyFeatureWithException(getCurrentPackageName(),
3019                     PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "needMobileRadioShutdown");
3020         }
3021 
3022         /*
3023          * If any of the Radios are available, it will need to be
3024          * shutdown. So return true if any Radio is available.
3025          */
3026         final long identity = Binder.clearCallingIdentity();
3027         try {
3028             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3029                 Phone phone = PhoneFactory.getPhone(i);
3030                 if (phone != null && phone.isRadioAvailable()) return true;
3031             }
3032             logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
3033             return false;
3034         } finally {
3035             Binder.restoreCallingIdentity(identity);
3036         }
3037     }
3038 
3039     @Override
shutdownMobileRadios()3040     public void shutdownMobileRadios() {
3041         enforceModifyPermission();
3042 
3043         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3044                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "shutdownMobileRadios");
3045 
3046         final long identity = Binder.clearCallingIdentity();
3047         try {
3048             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3049                 logv("Shutting down Phone " + i);
3050                 shutdownRadioUsingPhoneId(i);
3051             }
3052         } finally {
3053             Binder.restoreCallingIdentity(identity);
3054         }
3055     }
3056 
shutdownRadioUsingPhoneId(int phoneId)3057     private void shutdownRadioUsingPhoneId(int phoneId) {
3058         Phone phone = PhoneFactory.getPhone(phoneId);
3059         if (phone != null && phone.isRadioAvailable()) {
3060             phone.shutdownRadio();
3061         }
3062     }
3063 
setRadioPower(boolean turnOn)3064     public boolean setRadioPower(boolean turnOn) {
3065         enforceModifyPermission();
3066 
3067         if (!turnOn) {
3068             log("setRadioPower off: callingPackage=" + getCurrentPackageName());
3069         }
3070 
3071         final long identity = Binder.clearCallingIdentity();
3072         try {
3073             final Phone defaultPhone = PhoneFactory.getDefaultPhone();
3074             if (defaultPhone != null) {
3075                 defaultPhone.setRadioPower(turnOn);
3076                 return true;
3077             } else {
3078                 loge("There's no default phone.");
3079                 return false;
3080             }
3081         } finally {
3082             Binder.restoreCallingIdentity(identity);
3083         }
3084     }
3085 
setRadioPowerForSubscriber(int subId, boolean turnOn)3086     public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
3087         enforceModifyPermission();
3088 
3089         if (!turnOn) {
3090             log("setRadioPowerForSubscriber off: subId=" + subId
3091                     + ",callingPackage=" + getCurrentPackageName());
3092         }
3093         final long identity = Binder.clearCallingIdentity();
3094         try {
3095             final Phone phone = getPhone(subId);
3096             if (phone != null) {
3097                 phone.setRadioPower(turnOn);
3098                 return true;
3099             } else {
3100                 return false;
3101             }
3102         } finally {
3103             Binder.restoreCallingIdentity(identity);
3104         }
3105     }
3106 
3107     /**
3108      * Vote on powering off the radio for a reason. The radio will be turned on only when there is
3109      * no reason to power it off. When any of the voters want to power it off, it will be turned
3110      * off. In case of emergency, the radio will be turned on even if there are some reasons for
3111      * powering it off, and these radio off votes will be cleared.
3112      * Multiple apps can vote for the same reason and the last vote will take effect. Each app is
3113      * responsible for its vote. A powering-off vote of a reason will be maintained until it is
3114      * cleared by calling {@link clearRadioPowerOffForReason} for that reason, or an emergency call
3115      * is made, or the device is rebooted. When an app comes backup from a crash, it needs to make
3116      * sure if its vote is as expected. An app can use the API {@link getRadioPowerOffReasons} to
3117      * check its vote.
3118      *
3119      * @param subId The subscription ID.
3120      * @param reason The reason for powering off radio.
3121      * @return true on success and false on failure.
3122      */
requestRadioPowerOffForReason(int subId, @TelephonyManager.RadioPowerReason int reason)3123     public boolean requestRadioPowerOffForReason(int subId,
3124             @TelephonyManager.RadioPowerReason int reason) {
3125         enforceModifyPermission();
3126 
3127         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3128                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "requestRadioPowerOffForReason");
3129 
3130         log("requestRadioPowerOffForReason: subId=" + subId
3131                 + ",reason=" + reason + ",callingPackage=" + getCurrentPackageName());
3132         final long identity = Binder.clearCallingIdentity();
3133         try {
3134             boolean result = false;
3135             for (Phone phone : PhoneFactory.getPhones()) {
3136                 result = true;
3137                 phone.setRadioPowerForReason(false, reason);
3138             }
3139             if (!result) {
3140                 loge("requestRadioPowerOffForReason: no phone exists");
3141             }
3142             return result;
3143         } finally {
3144             Binder.restoreCallingIdentity(identity);
3145         }
3146     }
3147 
3148     /**
3149      * Remove the vote on powering off the radio for a reason, as requested by
3150      * {@link requestRadioPowerOffForReason}.
3151      *
3152      * @param subId The subscription ID.
3153      * @param reason The reason for powering off radio.
3154      * @return true on success and false on failure.
3155      */
clearRadioPowerOffForReason(int subId, @TelephonyManager.RadioPowerReason int reason)3156     public boolean clearRadioPowerOffForReason(int subId,
3157             @TelephonyManager.RadioPowerReason int reason) {
3158         enforceModifyPermission();
3159 
3160         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3161                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "clearRadioPowerOffForReason");
3162 
3163         final long identity = Binder.clearCallingIdentity();
3164         try {
3165             boolean result = false;
3166             for (Phone phone : PhoneFactory.getPhones()) {
3167                 result = true;
3168                 phone.setRadioPowerForReason(true, reason);
3169             }
3170             if (!result) {
3171                 loge("clearRadioPowerOffForReason: no phone exists");
3172             }
3173             return result;
3174         } finally {
3175             Binder.restoreCallingIdentity(identity);
3176         }
3177     }
3178 
3179     /**
3180      * Get reasons for powering off radio, as requested by {@link requestRadioPowerOffForReason}.
3181      *
3182      * @param subId The subscription ID.
3183      * @param callingPackage The package making the call.
3184      * @param callingFeatureId The feature in the package.
3185      * @return List of reasons for powering off radio.
3186      */
getRadioPowerOffReasons(int subId, String callingPackage, String callingFeatureId)3187     public List getRadioPowerOffReasons(int subId, String callingPackage, String callingFeatureId) {
3188         enforceReadPrivilegedPermission("getRadioPowerOffReasons");
3189 
3190         enforceTelephonyFeatureWithException(callingPackage,
3191                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getRadioPowerOffReasons");
3192 
3193         final long identity = Binder.clearCallingIdentity();
3194         List result = new ArrayList();
3195         try {
3196             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId,
3197                     callingPackage, callingFeatureId, "getRadioPowerOffReasons")) {
3198                 return result;
3199             }
3200 
3201             final Phone phone = getPhoneFromSubIdOrDefault(subId);
3202             if (phone != null) {
3203                 result.addAll(phone.getRadioPowerOffReasons());
3204             } else {
3205                 loge("getRadioPowerOffReasons: phone is null");
3206             }
3207         } finally {
3208             Binder.restoreCallingIdentity(identity);
3209         }
3210         return result;
3211     }
3212 
3213     // FIXME: subId version needed
3214     @Override
enableDataConnectivity(String callingPackage)3215     public boolean enableDataConnectivity(String callingPackage) {
3216         enforceModifyPermission();
3217 
3218         enforceTelephonyFeatureWithException(callingPackage,
3219                 PackageManager.FEATURE_TELEPHONY_DATA, "enableDataConnectivity");
3220 
3221         final long identity = Binder.clearCallingIdentity();
3222         try {
3223             int subId = SubscriptionManager.getDefaultDataSubscriptionId();
3224             final Phone phone = getPhone(subId);
3225             if (phone != null && phone.getDataSettingsManager() != null) {
3226                 phone.getDataSettingsManager().setDataEnabled(
3227                         TelephonyManager.DATA_ENABLED_REASON_USER, true, callingPackage);
3228                 return true;
3229             } else {
3230                 return false;
3231             }
3232         } finally {
3233             Binder.restoreCallingIdentity(identity);
3234         }
3235     }
3236 
3237     // FIXME: subId version needed
3238     @Override
disableDataConnectivity(String callingPackage)3239     public boolean disableDataConnectivity(String callingPackage) {
3240         enforceModifyPermission();
3241 
3242         enforceTelephonyFeatureWithException(callingPackage,
3243                 PackageManager.FEATURE_TELEPHONY_DATA, "disableDataConnectivity");
3244 
3245         final long identity = Binder.clearCallingIdentity();
3246         try {
3247             int subId = SubscriptionManager.getDefaultDataSubscriptionId();
3248             final Phone phone = getPhone(subId);
3249             if (phone != null && phone.getDataSettingsManager() != null) {
3250                 phone.getDataSettingsManager().setDataEnabled(
3251                         TelephonyManager.DATA_ENABLED_REASON_USER, false, callingPackage);
3252                 return true;
3253             } else {
3254                 return false;
3255             }
3256         } finally {
3257             Binder.restoreCallingIdentity(identity);
3258         }
3259     }
3260 
3261     @Override
isDataConnectivityPossible(int subId)3262     public boolean isDataConnectivityPossible(int subId) {
3263         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3264                 PackageManager.FEATURE_TELEPHONY_DATA, "isDataConnectivityPossible");
3265 
3266         final long identity = Binder.clearCallingIdentity();
3267         try {
3268             final Phone phone = getPhone(subId);
3269             if (phone != null) {
3270                 return phone.isDataAllowed();
3271             } else {
3272                 return false;
3273             }
3274         } finally {
3275             Binder.restoreCallingIdentity(identity);
3276         }
3277     }
3278 
handlePinMmi(String dialString)3279     public boolean handlePinMmi(String dialString) {
3280         return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
3281     }
3282 
handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback)3283     public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
3284         enforceCallPermission();
3285 
3286         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3287                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "handleUssdRequest");
3288 
3289         final long identity = Binder.clearCallingIdentity();
3290         try {
3291             if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3292                 return;
3293             }
3294             Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
3295             sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
3296         } finally {
3297             Binder.restoreCallingIdentity(identity);
3298         }
3299     };
3300 
handlePinMmiForSubscriber(int subId, String dialString)3301     public boolean handlePinMmiForSubscriber(int subId, String dialString) {
3302         enforceModifyPermission();
3303 
3304         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3305                 PackageManager.FEATURE_TELEPHONY_CALLING, "handlePinMmiForSubscriber");
3306 
3307         final long identity = Binder.clearCallingIdentity();
3308         try {
3309             if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3310                 return false;
3311             }
3312             return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
3313         } finally {
3314             Binder.restoreCallingIdentity(identity);
3315         }
3316     }
3317 
3318     /**
3319      * @deprecated  This method is deprecated and is only being kept due to an UnsupportedAppUsage
3320      * tag on getCallState Binder call.
3321      */
3322     @Deprecated
3323     @Override
getCallState()3324     public int getCallState() {
3325         if (CompatChanges.isChangeEnabled(
3326                 TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION,
3327                 Binder.getCallingUid())) {
3328             // Do not allow this API to be called on API version 31+, it should only be
3329             // called on old apps using this Binder call directly.
3330             throw new SecurityException("This method can only be used for applications "
3331                     + "targeting API version 30 or less.");
3332         }
3333         final long identity = Binder.clearCallingIdentity();
3334         try {
3335             Phone phone = getPhoneFromSubIdOrDefault(getDefaultSubscription());
3336             return PhoneConstantConversions.convertCallState(phone.getState());
3337         } finally {
3338             Binder.restoreCallingIdentity(identity);
3339         }
3340     }
3341 
3342     @Override
getCallStateForSubscription(int subId, String callingPackage, String featureId)3343     public int getCallStateForSubscription(int subId, String callingPackage, String featureId) {
3344         if (CompatChanges.isChangeEnabled(
3345                 TelecomManager.ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION,
3346                 Binder.getCallingUid())) {
3347             // Check READ_PHONE_STATE for API version 31+
3348             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
3349                     featureId, "getCallStateForSubscription")) {
3350                 throw new SecurityException("getCallState requires READ_PHONE_STATE for apps "
3351                         + "targeting API level 31+.");
3352             }
3353         }
3354 
3355         enforceTelephonyFeatureWithException(callingPackage,
3356                 PackageManager.FEATURE_TELEPHONY_CALLING, "getCallStateForSubscription");
3357 
3358         final long identity = Binder.clearCallingIdentity();
3359         try {
3360             Phone phone = getPhone(subId);
3361             return phone == null ? TelephonyManager.CALL_STATE_IDLE :
3362                     PhoneConstantConversions.convertCallState(phone.getState());
3363         } finally {
3364             Binder.restoreCallingIdentity(identity);
3365         }
3366     }
3367 
3368     @Override
getDataState()3369     public int getDataState() {
3370         return getDataStateForSubId(SubscriptionManager.getDefaultDataSubscriptionId());
3371     }
3372 
3373     @Override
getDataStateForSubId(int subId)3374     public int getDataStateForSubId(int subId) {
3375         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3376                 PackageManager.FEATURE_TELEPHONY_DATA, "getDataStateForSubId");
3377 
3378         final long identity = Binder.clearCallingIdentity();
3379         try {
3380             final Phone phone = getPhone(subId);
3381             if (phone != null) {
3382                 return phone.getDataNetworkController().getInternetDataNetworkState();
3383             } else {
3384                 return PhoneConstantConversions.convertDataState(
3385                         PhoneConstants.DataState.DISCONNECTED);
3386             }
3387         } finally {
3388             Binder.restoreCallingIdentity(identity);
3389         }
3390     }
3391 
3392     @Override
getDataActivity()3393     public @DataActivityType int getDataActivity() {
3394         return getDataActivityForSubId(SubscriptionManager.getDefaultDataSubscriptionId());
3395     }
3396 
3397     @Override
getDataActivityForSubId(int subId)3398     public @DataActivityType int getDataActivityForSubId(int subId) {
3399         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3400                 PackageManager.FEATURE_TELEPHONY_DATA, "getDataActivityForSubId");
3401 
3402         final long identity = Binder.clearCallingIdentity();
3403         try {
3404             final Phone phone = getPhone(subId);
3405             if (phone != null) {
3406                 return phone.getDataActivityState();
3407             } else {
3408                 return TelephonyManager.DATA_ACTIVITY_NONE;
3409             }
3410         } finally {
3411             Binder.restoreCallingIdentity(identity);
3412         }
3413     }
3414 
3415     @Override
getCellLocation(String callingPackage, String callingFeatureId)3416     public CellIdentity getCellLocation(String callingPackage, String callingFeatureId) {
3417         mApp.getSystemService(AppOpsManager.class)
3418                 .checkPackage(Binder.getCallingUid(), callingPackage);
3419 
3420         LocationAccessPolicy.LocationPermissionResult locationResult =
3421                 LocationAccessPolicy.checkLocationPermission(mApp,
3422                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
3423                                 .setCallingPackage(callingPackage)
3424                                 .setCallingFeatureId(callingFeatureId)
3425                                 .setCallingPid(Binder.getCallingPid())
3426                                 .setCallingUid(Binder.getCallingUid())
3427                                 .setMethod("getCellLocation")
3428                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
3429                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
3430                                 .build());
3431         switch (locationResult) {
3432             case DENIED_HARD:
3433                 throw new SecurityException("Not allowed to access cell location");
3434             case DENIED_SOFT:
3435                 return (getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
3436                         ? new CellIdentityCdma() : new CellIdentityGsm();
3437         }
3438 
3439         enforceTelephonyFeatureWithException(callingPackage,
3440                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getCellLocation");
3441 
3442         WorkSource workSource = getWorkSource(Binder.getCallingUid());
3443         final long identity = Binder.clearCallingIdentity();
3444         try {
3445             if (DBG_LOC) log("getCellLocation: is active user");
3446             int subId = SubscriptionManager.getDefaultDataSubscriptionId();
3447             return (CellIdentity) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
3448         } finally {
3449             Binder.restoreCallingIdentity(identity);
3450         }
3451     }
3452 
3453     @Override
getNetworkCountryIsoForPhone(int phoneId)3454     public String getNetworkCountryIsoForPhone(int phoneId) {
3455         if (!mApp.getResources().getBoolean(
3456                 com.android.internal.R.bool.config_force_phone_globals_creation)) {
3457             enforceTelephonyFeatureWithException(getCurrentPackageName(),
3458                     PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getNetworkCountryIsoForPhone");
3459         }
3460 
3461         // Reporting the correct network country is ambiguous when IWLAN could conflict with
3462         // registered cell info, so return a NULL country instead.
3463         final long identity = Binder.clearCallingIdentity();
3464         try {
3465             if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
3466                 // Get default phone in this case.
3467                 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
3468             }
3469             final int subId = SubscriptionManager.getSubscriptionId(phoneId);
3470             Phone phone = PhoneFactory.getPhone(phoneId);
3471             if (phone == null) return "";
3472             ServiceStateTracker sst = phone.getServiceStateTracker();
3473             if (sst == null) return "";
3474             LocaleTracker lt = sst.getLocaleTracker();
3475             if (lt == null) return "";
3476             return lt.getCurrentCountry();
3477         } finally {
3478             Binder.restoreCallingIdentity(identity);
3479         }
3480     }
3481 
3482     /**
3483      * This method was removed due to potential issues caused by performing partial
3484      * updates of service state, and lack of a credible use case.
3485      *
3486      * This has the ability to break the telephony implementation by disabling notification of
3487      * changes in device connectivity. DO NOT USE THIS!
3488      */
3489     @Override
enableLocationUpdates()3490     public void enableLocationUpdates() {
3491         mApp.enforceCallingOrSelfPermission(
3492                 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
3493     }
3494 
3495     /**
3496      * This method was removed due to potential issues caused by performing partial
3497      * updates of service state, and lack of a credible use case.
3498      *
3499      * This has the ability to break the telephony implementation by disabling notification of
3500      * changes in device connectivity. DO NOT USE THIS!
3501      */
3502     @Override
disableLocationUpdates()3503     public void disableLocationUpdates() {
3504         mApp.enforceCallingOrSelfPermission(
3505                 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
3506     }
3507 
3508     @Override
3509     @SuppressWarnings("unchecked")
getNeighboringCellInfo(String callingPackage, String callingFeatureId)3510     public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage,
3511             String callingFeatureId) {
3512         try {
3513             mApp.getSystemService(AppOpsManager.class)
3514                     .checkPackage(Binder.getCallingUid(), callingPackage);
3515         } catch (SecurityException e) {
3516             EventLog.writeEvent(0x534e4554, "190619791", Binder.getCallingUid());
3517             throw e;
3518         }
3519 
3520         final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
3521         if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
3522             throw new SecurityException(
3523                     "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
3524         }
3525 
3526         if (mAppOps.noteOp(AppOpsManager.OPSTR_NEIGHBORING_CELLS, Binder.getCallingUid(),
3527                 callingPackage) != AppOpsManager.MODE_ALLOWED) {
3528             return null;
3529         }
3530 
3531         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3532                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getNeighboringCellInfo");
3533 
3534         if (DBG_LOC) log("getNeighboringCellInfo: is active user");
3535 
3536         List<CellInfo> info = getAllCellInfo(callingPackage, callingFeatureId);
3537         if (info == null) return null;
3538 
3539         List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
3540         for (CellInfo ci : info) {
3541             if (ci instanceof CellInfoGsm) {
3542                 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
3543             } else if (ci instanceof CellInfoWcdma) {
3544                 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
3545             }
3546         }
3547         return (neighbors.size()) > 0 ? neighbors : null;
3548     }
3549 
getCachedCellInfo()3550     private List<CellInfo> getCachedCellInfo() {
3551         List<CellInfo> cellInfos = new ArrayList<CellInfo>();
3552         for (Phone phone : PhoneFactory.getPhones()) {
3553             List<CellInfo> info = phone.getAllCellInfo();
3554             if (info != null) cellInfos.addAll(info);
3555         }
3556         return cellInfos;
3557     }
3558 
3559     @Override
getAllCellInfo(String callingPackage, String callingFeatureId)3560     public List<CellInfo> getAllCellInfo(String callingPackage, String callingFeatureId) {
3561         mApp.getSystemService(AppOpsManager.class)
3562                 .checkPackage(Binder.getCallingUid(), callingPackage);
3563 
3564         LocationAccessPolicy.LocationPermissionResult locationResult =
3565                 LocationAccessPolicy.checkLocationPermission(mApp,
3566                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
3567                                 .setCallingPackage(callingPackage)
3568                                 .setCallingFeatureId(callingFeatureId)
3569                                 .setCallingPid(Binder.getCallingPid())
3570                                 .setCallingUid(Binder.getCallingUid())
3571                                 .setMethod("getAllCellInfo")
3572                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
3573                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
3574                                 .build());
3575         switch (locationResult) {
3576             case DENIED_HARD:
3577                 throw new SecurityException("Not allowed to access cell info");
3578             case DENIED_SOFT:
3579                 return new ArrayList<>();
3580         }
3581 
3582         final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
3583         if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
3584             return getCachedCellInfo();
3585         }
3586 
3587         enforceTelephonyFeatureWithException(callingPackage,
3588                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getAllCellInfo");
3589 
3590         if (DBG_LOC) log("getAllCellInfo: is active user");
3591         WorkSource workSource = getWorkSource(Binder.getCallingUid());
3592         final long identity = Binder.clearCallingIdentity();
3593         try {
3594             List<CellInfo> cellInfos = new ArrayList<CellInfo>();
3595             for (Phone phone : PhoneFactory.getPhones()) {
3596                 final List<CellInfo> info = (List<CellInfo>) sendRequest(
3597                         CMD_GET_ALL_CELL_INFO, null, phone, workSource);
3598                 if (info != null) cellInfos.addAll(info);
3599             }
3600             return cellInfos;
3601         } finally {
3602             Binder.restoreCallingIdentity(identity);
3603         }
3604     }
3605 
3606     @Override
requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage, String callingFeatureId)3607     public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage,
3608             String callingFeatureId) {
3609         requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId,
3610                 getWorkSource(Binder.getCallingUid()));
3611     }
3612 
3613     @Override
requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb, String callingPackage, String callingFeatureId, WorkSource workSource)3614     public void requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb,
3615             String callingPackage, String callingFeatureId, WorkSource workSource) {
3616         enforceModifyPermission();
3617         requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId, workSource);
3618     }
3619 
requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb, String callingPackage, String callingFeatureId, WorkSource workSource)3620     private void requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb,
3621             String callingPackage, String callingFeatureId, WorkSource workSource) {
3622         mApp.getSystemService(AppOpsManager.class)
3623                 .checkPackage(Binder.getCallingUid(), callingPackage);
3624 
3625         LocationAccessPolicy.LocationPermissionResult locationResult =
3626                 LocationAccessPolicy.checkLocationPermission(mApp,
3627                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
3628                                 .setCallingPackage(callingPackage)
3629                                 .setCallingFeatureId(callingFeatureId)
3630                                 .setCallingPid(Binder.getCallingPid())
3631                                 .setCallingUid(Binder.getCallingUid())
3632                                 .setMethod("requestCellInfoUpdate")
3633                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
3634                                 .setMinSdkVersionForFine(Build.VERSION_CODES.BASE)
3635                                 .build());
3636         switch (locationResult) {
3637             case DENIED_HARD:
3638                 if (TelephonyPermissions
3639                         .getTargetSdk(mApp, callingPackage) < Build.VERSION_CODES.Q) {
3640                     // Safetynet logging for b/154934934
3641                     EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
3642                 }
3643                 throw new SecurityException("Not allowed to access cell info");
3644             case DENIED_SOFT:
3645                 if (TelephonyPermissions
3646                         .getTargetSdk(mApp, callingPackage) < Build.VERSION_CODES.Q) {
3647                     // Safetynet logging for b/154934934
3648                     EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
3649                 }
3650                 try {
3651                     cb.onCellInfo(new ArrayList<CellInfo>());
3652                 } catch (RemoteException re) {
3653                     // Drop without consequences
3654                 }
3655                 return;
3656         }
3657 
3658         enforceTelephonyFeatureWithException(callingPackage,
3659                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "requestCellInfoUpdateInternal");
3660 
3661         final Phone phone = getPhoneFromSubId(subId);
3662         if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
3663 
3664         sendRequestAsync(CMD_REQUEST_CELL_INFO_UPDATE, cb, phone, workSource);
3665     }
3666 
3667     @Override
setCellInfoListRate(int rateInMillis, int subId)3668     public void setCellInfoListRate(int rateInMillis, int subId) {
3669         enforceModifyPermission();
3670         WorkSource workSource = getWorkSource(Binder.getCallingUid());
3671 
3672         final long identity = Binder.clearCallingIdentity();
3673         try {
3674             Phone phone = getPhone(subId);
3675             if (phone == null) {
3676                 getDefaultPhone().setCellInfoListRate(rateInMillis, workSource);
3677             } else {
3678                 phone.setCellInfoListRate(rateInMillis, workSource);
3679             }
3680         } finally {
3681             Binder.restoreCallingIdentity(identity);
3682         }
3683     }
3684 
3685     @Override
getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId)3686     public String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
3687         Phone phone = PhoneFactory.getPhone(slotIndex);
3688         if (phone == null) {
3689             return null;
3690         }
3691         int subId = phone.getSubId();
3692         enforceCallingPackage(callingPackage, Binder.getCallingUid(), "getImeiForSlot");
3693         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
3694                 callingPackage, callingFeatureId, "getImeiForSlot")) {
3695             return null;
3696         }
3697 
3698         final long identity = Binder.clearCallingIdentity();
3699         try {
3700             return phone.getImei();
3701         } finally {
3702             Binder.restoreCallingIdentity(identity);
3703         }
3704     }
3705 
3706     @Override
getPrimaryImei(String callingPackage, String callingFeatureId)3707     public String getPrimaryImei(String callingPackage, String callingFeatureId) {
3708         enforceCallingPackage(callingPackage, Binder.getCallingUid(), "getPrimaryImei");
3709         if (!checkCallingOrSelfReadDeviceIdentifiersForAnySub(mApp, callingPackage,
3710                 callingFeatureId, "getPrimaryImei")) {
3711             throw new SecurityException("Caller does not have permission");
3712         }
3713 
3714         final long identity = Binder.clearCallingIdentity();
3715         try {
3716             for (Phone phone : PhoneFactory.getPhones()) {
3717                 if (phone.getImeiType() == Phone.IMEI_TYPE_PRIMARY) {
3718                     return phone.getImei();
3719                 }
3720             }
3721             throw new UnsupportedOperationException("Operation not supported");
3722         } finally {
3723             Binder.restoreCallingIdentity(identity);
3724         }
3725     }
3726 
3727     @Override
getTypeAllocationCodeForSlot(int slotIndex)3728     public String getTypeAllocationCodeForSlot(int slotIndex) {
3729         Phone phone = PhoneFactory.getPhone(slotIndex);
3730         String tac = null;
3731         if (phone != null) {
3732             String imei = phone.getImei();
3733             try {
3734                 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
3735             } catch (IndexOutOfBoundsException e) {
3736                 Log.e(LOG_TAG, "IMEI length shorter than upper index.");
3737                 return null;
3738             }
3739         }
3740         return tac;
3741     }
3742 
3743     @Override
getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId)3744     public String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
3745         if (mFeatureFlags.cleanupCdma()) return null;
3746 
3747         try {
3748             mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3749         } catch (SecurityException se) {
3750             EventLog.writeEvent(0x534e4554, "186530496", Binder.getCallingUid());
3751             throw new SecurityException("Package " + callingPackage + " does not belong to "
3752                     + Binder.getCallingUid());
3753         }
3754         Phone phone = PhoneFactory.getPhone(slotIndex);
3755         if (phone == null) {
3756             return null;
3757         }
3758 
3759         int subId = phone.getSubId();
3760         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
3761                 callingPackage, callingFeatureId, "getMeidForSlot")) {
3762             return null;
3763         }
3764 
3765         enforceTelephonyFeatureWithException(callingPackage,
3766                 PackageManager.FEATURE_TELEPHONY_CDMA, "getMeidForSlot");
3767 
3768         final long identity = Binder.clearCallingIdentity();
3769         try {
3770             return phone.getMeid();
3771         } finally {
3772             Binder.restoreCallingIdentity(identity);
3773         }
3774     }
3775 
3776     @Override
getManufacturerCodeForSlot(int slotIndex)3777     public String getManufacturerCodeForSlot(int slotIndex) {
3778         if (mFeatureFlags.cleanupCdma()) return null;
3779 
3780         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3781                 PackageManager.FEATURE_TELEPHONY_CDMA, "getManufacturerCodeForSlot");
3782 
3783         Phone phone = PhoneFactory.getPhone(slotIndex);
3784         String manufacturerCode = null;
3785         if (phone != null) {
3786             String meid = phone.getMeid();
3787             try {
3788                 manufacturerCode =
3789                         meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
3790             } catch (IndexOutOfBoundsException e) {
3791                 Log.e(LOG_TAG, "MEID length shorter than upper index.");
3792                 return null;
3793             }
3794         }
3795         return manufacturerCode;
3796     }
3797 
3798     @Override
getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage, String callingFeatureId)3799     public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage,
3800             String callingFeatureId) {
3801         Phone phone = PhoneFactory.getPhone(slotIndex);
3802         if (phone == null) {
3803             return null;
3804         }
3805         int subId = phone.getSubId();
3806         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3807                 mApp, subId, callingPackage, callingFeatureId,
3808                 "getDeviceSoftwareVersionForSlot")) {
3809             return null;
3810         }
3811 
3812         enforceTelephonyFeatureWithException(callingPackage,
3813                 PackageManager.FEATURE_TELEPHONY, "getDeviceSoftwareVersionForSlot");
3814 
3815         final long identity = Binder.clearCallingIdentity();
3816         try {
3817             return phone.getDeviceSvn();
3818         } finally {
3819             Binder.restoreCallingIdentity(identity);
3820         }
3821     }
3822 
3823     @Override
getSubscriptionCarrierId(int subId)3824     public int getSubscriptionCarrierId(int subId) {
3825         if (!mApp.getResources().getBoolean(
3826                 com.android.internal.R.bool.config_force_phone_globals_creation)) {
3827             enforceTelephonyFeatureWithException(getCurrentPackageName(),
3828                     PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSubscriptionCarrierId");
3829         }
3830 
3831         final long identity = Binder.clearCallingIdentity();
3832         try {
3833             final Phone phone = getPhone(subId);
3834             return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
3835         } finally {
3836             Binder.restoreCallingIdentity(identity);
3837         }
3838     }
3839 
3840     @Override
getSubscriptionCarrierName(int subId)3841     public String getSubscriptionCarrierName(int subId) {
3842         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3843                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSubscriptionCarrierName");
3844 
3845         final long identity = Binder.clearCallingIdentity();
3846         try {
3847             final Phone phone = getPhone(subId);
3848             return phone == null ? null : phone.getCarrierName();
3849         } finally {
3850             Binder.restoreCallingIdentity(identity);
3851         }
3852     }
3853 
3854     @Override
getSubscriptionSpecificCarrierId(int subId)3855     public int getSubscriptionSpecificCarrierId(int subId) {
3856         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3857                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSubscriptionSpecificCarrierId");
3858 
3859         final long identity = Binder.clearCallingIdentity();
3860         try {
3861             final Phone phone = getPhone(subId);
3862             return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
3863                     : phone.getSpecificCarrierId();
3864         } finally {
3865             Binder.restoreCallingIdentity(identity);
3866         }
3867     }
3868 
3869     @Override
getSubscriptionSpecificCarrierName(int subId)3870     public String getSubscriptionSpecificCarrierName(int subId) {
3871         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3872                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
3873                 "getSubscriptionSpecificCarrierName");
3874 
3875         final long identity = Binder.clearCallingIdentity();
3876         try {
3877             final Phone phone = getPhone(subId);
3878             return phone == null ? null : phone.getSpecificCarrierName();
3879         } finally {
3880             Binder.restoreCallingIdentity(identity);
3881         }
3882     }
3883 
3884     @Override
getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc)3885     public int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc) {
3886         if (!isSubscriptionMccMnc) {
3887             enforceReadPrivilegedPermission("getCarrierIdFromMccMnc");
3888         }
3889         final Phone phone = PhoneFactory.getPhone(slotIndex);
3890         if (phone == null) {
3891             return TelephonyManager.UNKNOWN_CARRIER_ID;
3892         }
3893 
3894         enforceTelephonyFeatureWithException(getCurrentPackageName(),
3895                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getCarrierIdFromMccMnc");
3896 
3897         final long identity = Binder.clearCallingIdentity();
3898         try {
3899             return CarrierResolver.getCarrierIdFromMccMnc(phone.getContext(), mccmnc);
3900         } finally {
3901             Binder.restoreCallingIdentity(identity);
3902         }
3903     }
3904 
3905     //
3906     // Internal helper methods.
3907     //
3908 
3909     /**
3910      * Make sure the caller is the calling package itself
3911      *
3912      * @throws SecurityException if the caller is not the calling package
3913      */
enforceCallingPackage(String callingPackage, int callingUid, String message)3914     private void enforceCallingPackage(String callingPackage, int callingUid, String message) {
3915         int packageUid = -1;
3916         PackageManager pm = mApp.getBaseContext().createContextAsUser(
3917                 UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager();
3918         try {
3919             packageUid = pm.getPackageUid(callingPackage, 0);
3920         } catch (PackageManager.NameNotFoundException e) {
3921             // packageUid is -1
3922         }
3923         if (packageUid != callingUid) {
3924             throw new SecurityException(message + ": Package " + callingPackage
3925                     + " does not belong to " + callingUid);
3926         }
3927     }
3928 
3929     /**
3930      * Make sure the caller has the MODIFY_PHONE_STATE permission.
3931      *
3932      * @throws SecurityException if the caller does not have the required permission
3933      */
3934     @VisibleForTesting
enforceModifyPermission()3935     public void enforceModifyPermission() {
3936         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
3937     }
3938 
3939     /**
3940      * Make sure the caller has the READ_PHONE_STATE permission.
3941      *
3942      * @throws SecurityException if the caller does not have the required permission
3943      */
3944     @VisibleForTesting
enforceReadPermission()3945     public void enforceReadPermission() {
3946         enforceReadPermission(null);
3947     }
3948 
3949     /**
3950      * Make sure the caller has the READ_PHONE_STATE permissions.
3951      *
3952      * @throws SecurityException if the caller does not have the READ_PHONE_STATE permission.
3953      */
3954     @VisibleForTesting
enforceReadPermission(String msg)3955     public void enforceReadPermission(String msg) {
3956         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE, msg);
3957     }
3958 
enforceActiveEmergencySessionPermission()3959     private void enforceActiveEmergencySessionPermission() {
3960         mApp.enforceCallingOrSelfPermission(
3961                 android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
3962     }
3963 
3964     /**
3965      * Make sure the caller has the CALL_PHONE permission.
3966      *
3967      * @throws SecurityException if the caller does not have the required permission
3968      */
enforceCallPermission()3969     private void enforceCallPermission() {
3970         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
3971     }
3972 
enforceSettingsPermission()3973     private void enforceSettingsPermission() {
3974         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS, null);
3975     }
3976 
enforceRebootPermission()3977     private void enforceRebootPermission() {
3978         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
3979     }
3980 
3981     /**
3982      * Make sure the caller has SATELLITE_COMMUNICATION permission.
3983      * @param message - log message to print.
3984      * @throws SecurityException if the caller does not have the required permission
3985      */
enforceSatelliteCommunicationPermission(String message)3986     private void enforceSatelliteCommunicationPermission(String message) {
3987         mApp.enforceCallingOrSelfPermission(permission.SATELLITE_COMMUNICATION, message);
3988     }
3989 
3990     /**
3991      * Make sure the caller has PACKAGE_USAGE_STATS permission.
3992      * @param message - log message to print.
3993      * @throws SecurityException if the caller does not have the required permission
3994      */
enforcePackageUsageStatsPermission(String message)3995     private void enforcePackageUsageStatsPermission(String message) {
3996         mApp.enforceCallingOrSelfPermission(permission.PACKAGE_USAGE_STATS, message);
3997     }
3998 
createTelUrl(String number)3999     private String createTelUrl(String number) {
4000         if (TextUtils.isEmpty(number)) {
4001             return null;
4002         }
4003 
4004         return "tel:" + number;
4005     }
4006 
log(String msg)4007     private static void log(String msg) {
4008         Log.d(LOG_TAG, msg);
4009     }
4010 
logv(String msg)4011     private static void logv(String msg) {
4012         Log.v(LOG_TAG, msg);
4013     }
4014 
loge(String msg)4015     private static void loge(String msg) {
4016         Log.e(LOG_TAG, msg);
4017     }
4018 
4019     @Override
getActivePhoneType()4020     public int getActivePhoneType() {
4021         return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
4022     }
4023 
4024     @Override
getActivePhoneTypeForSlot(int slotIndex)4025     public int getActivePhoneTypeForSlot(int slotIndex) {
4026         if (!mApp.getResources().getBoolean(
4027                 com.android.internal.R.bool.config_force_phone_globals_creation)) {
4028             enforceTelephonyFeatureWithException(getCurrentPackageName(),
4029                     PackageManager.FEATURE_TELEPHONY, "getActivePhoneTypeForSlot");
4030         }
4031 
4032         final long identity = Binder.clearCallingIdentity();
4033         try {
4034             final Phone phone = PhoneFactory.getPhone(slotIndex);
4035             if (phone == null) {
4036                 return PhoneConstants.PHONE_TYPE_NONE;
4037             } else {
4038                 return phone.getPhoneType();
4039             }
4040         } finally {
4041             Binder.restoreCallingIdentity(identity);
4042         }
4043     }
4044 
4045     /**
4046      * Returns the CDMA ERI icon index to display
4047      */
4048     @Override
getCdmaEriIconIndex(String callingPackage, String callingFeatureId)4049     public int getCdmaEriIconIndex(String callingPackage, String callingFeatureId) {
4050         if (mFeatureFlags.cleanupCdma()) return -1;
4051         return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage,
4052                 callingFeatureId);
4053     }
4054 
4055     @Override
getCdmaEriIconIndexForSubscriber(int subId, String callingPackage, String callingFeatureId)4056     public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
4057             String callingFeatureId) {
4058         if (mFeatureFlags.cleanupCdma()) return -1;
4059 
4060         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4061                 mApp, subId, callingPackage, callingFeatureId,
4062                 "getCdmaEriIconIndexForSubscriber")) {
4063             return -1;
4064         }
4065 
4066         enforceTelephonyFeatureWithException(callingPackage,
4067                 PackageManager.FEATURE_TELEPHONY_CDMA,
4068                 "getCdmaEriIconIndexForSubscriber");
4069 
4070         final long identity = Binder.clearCallingIdentity();
4071         try {
4072             final Phone phone = getPhone(subId);
4073             if (phone != null) {
4074                 return phone.getCdmaEriIconIndex();
4075             } else {
4076                 return -1;
4077             }
4078         } finally {
4079             Binder.restoreCallingIdentity(identity);
4080         }
4081     }
4082 
4083     /**
4084      * Returns the CDMA ERI icon mode,
4085      * 0 - ON
4086      * 1 - FLASHING
4087      */
4088     @Override
getCdmaEriIconMode(String callingPackage, String callingFeatureId)4089     public int getCdmaEriIconMode(String callingPackage, String callingFeatureId) {
4090         if (mFeatureFlags.cleanupCdma()) return -1;
4091         return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage,
4092                 callingFeatureId);
4093     }
4094 
4095     @Override
getCdmaEriIconModeForSubscriber(int subId, String callingPackage, String callingFeatureId)4096     public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
4097             String callingFeatureId) {
4098         if (mFeatureFlags.cleanupCdma()) return -1;
4099 
4100         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4101                 mApp, subId, callingPackage, callingFeatureId,
4102                 "getCdmaEriIconModeForSubscriber")) {
4103             return -1;
4104         }
4105 
4106         final long identity = Binder.clearCallingIdentity();
4107         try {
4108             final Phone phone = getPhone(subId);
4109             if (phone != null) {
4110                 return phone.getCdmaEriIconMode();
4111             } else {
4112                 return -1;
4113             }
4114         } finally {
4115             Binder.restoreCallingIdentity(identity);
4116         }
4117     }
4118 
4119     /**
4120      * Returns the CDMA ERI text,
4121      */
4122     @Override
getCdmaEriText(String callingPackage, String callingFeatureId)4123     public String getCdmaEriText(String callingPackage, String callingFeatureId) {
4124         if (mFeatureFlags.cleanupCdma()) return null;
4125         return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage,
4126                 callingFeatureId);
4127     }
4128 
4129     @Override
getCdmaEriTextForSubscriber(int subId, String callingPackage, String callingFeatureId)4130     public String getCdmaEriTextForSubscriber(int subId, String callingPackage,
4131             String callingFeatureId) {
4132         if (mFeatureFlags.cleanupCdma()) return null;
4133 
4134         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4135                 mApp, subId, callingPackage, callingFeatureId,
4136                 "getCdmaEriIconTextForSubscriber")) {
4137             return null;
4138         }
4139 
4140         final long identity = Binder.clearCallingIdentity();
4141         try {
4142             final Phone phone = getPhone(subId);
4143             if (phone != null) {
4144                 return phone.getCdmaEriText();
4145             } else {
4146                 return null;
4147             }
4148         } finally {
4149             Binder.restoreCallingIdentity(identity);
4150         }
4151     }
4152 
4153     /**
4154      * Returns the CDMA MDN.
4155      */
4156     @Override
getCdmaMdn(int subId)4157     public String getCdmaMdn(int subId) {
4158         if (mFeatureFlags.cleanupCdma()) return null;
4159 
4160         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4161                 mApp, subId, "getCdmaMdn");
4162 
4163         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4164                 PackageManager.FEATURE_TELEPHONY_CDMA, "getCdmaMdn");
4165 
4166         final long identity = Binder.clearCallingIdentity();
4167         try {
4168             final Phone phone = getPhone(subId);
4169             if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
4170                 return phone.getLine1Number();
4171             } else {
4172                 loge("getCdmaMdn: no phone found. Invalid subId: " + subId);
4173                 return null;
4174             }
4175         } finally {
4176             Binder.restoreCallingIdentity(identity);
4177         }
4178     }
4179 
4180     /**
4181      * Returns the CDMA MIN.
4182      */
4183     @Override
getCdmaMin(int subId)4184     public String getCdmaMin(int subId) {
4185         if (mFeatureFlags.cleanupCdma()) return null;
4186 
4187         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4188                 mApp, subId, "getCdmaMin");
4189 
4190         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4191                 PackageManager.FEATURE_TELEPHONY_CDMA, "getCdmaMin");
4192 
4193         final long identity = Binder.clearCallingIdentity();
4194         try {
4195             final Phone phone = getPhone(subId);
4196             if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
4197                 return phone.getCdmaMin();
4198             } else {
4199                 return null;
4200             }
4201         } finally {
4202             Binder.restoreCallingIdentity(identity);
4203         }
4204     }
4205 
4206     @Override
requestNumberVerification(PhoneNumberRange range, long timeoutMillis, INumberVerificationCallback callback, String callingPackage)4207     public void requestNumberVerification(PhoneNumberRange range, long timeoutMillis,
4208             INumberVerificationCallback callback, String callingPackage) {
4209         if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
4210                 != PERMISSION_GRANTED) {
4211             throw new SecurityException("Caller must hold the MODIFY_PHONE_STATE permission");
4212         }
4213         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4214 
4215         String authorizedPackage = NumberVerificationManager.getAuthorizedPackage(mApp);
4216         if (!TextUtils.equals(callingPackage, authorizedPackage)) {
4217             throw new SecurityException("Calling package must be configured in the device config: "
4218                     + "calling package: " + callingPackage
4219                     + ", configured package: " + authorizedPackage);
4220         }
4221 
4222         enforceTelephonyFeatureWithException(callingPackage,
4223                 PackageManager.FEATURE_TELEPHONY_CALLING, "requestNumberVerification");
4224 
4225         if (range == null) {
4226             throw new NullPointerException("Range must be non-null");
4227         }
4228 
4229         timeoutMillis = Math.min(timeoutMillis,
4230                 TelephonyManager.getMaxNumberVerificationTimeoutMillis());
4231 
4232         NumberVerificationManager.getInstance().requestVerification(range, callback, timeoutMillis);
4233     }
4234 
4235     /**
4236      * Returns true if CDMA provisioning needs to run.
4237      */
needsOtaServiceProvisioning()4238     public boolean needsOtaServiceProvisioning() {
4239         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4240                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "needsOtaServiceProvisioning");
4241 
4242         final long identity = Binder.clearCallingIdentity();
4243         try {
4244             return getDefaultPhone().needsOtaServiceProvisioning();
4245         } finally {
4246             Binder.restoreCallingIdentity(identity);
4247         }
4248     }
4249 
4250     /**
4251      * Sets the voice mail number of a given subId.
4252      */
4253     @Override
setVoiceMailNumber(int subId, String alphaTag, String number)4254     public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
4255         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
4256                 mApp, subId, "setVoiceMailNumber");
4257 
4258         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4259                 PackageManager.FEATURE_TELEPHONY_CALLING, "setVoiceMailNumber");
4260 
4261         final long identity = Binder.clearCallingIdentity();
4262         try {
4263             Boolean success = (Boolean) sendRequest(
4264                     CMD_SET_VOICEMAIL_NUMBER,
4265                     new Pair<String, String>(alphaTag, number),
4266                     new Integer(subId),
4267                     BLOCKING_REQUEST_DEFAULT_TIMEOUT_MS);
4268             if (success == null) return false; // most likely due to a timeout
4269             return success;
4270         } finally {
4271             Binder.restoreCallingIdentity(identity);
4272         }
4273     }
4274 
4275     @Override
getVisualVoicemailSettings(String callingPackage, int subId)4276     public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
4277         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4278         TelecomManager tm = mApp.getSystemService(TelecomManager.class);
4279         String systemDialer = tm.getSystemDialerPackage();
4280         if (!TextUtils.equals(callingPackage, systemDialer)) {
4281             throw new SecurityException("caller must be system dialer");
4282         }
4283 
4284         enforceTelephonyFeatureWithException(callingPackage,
4285                 PackageManager.FEATURE_TELEPHONY_CALLING, "getVisualVoicemailSettings");
4286 
4287         final long identity = Binder.clearCallingIdentity();
4288         try {
4289             PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
4290             if (phoneAccountHandle == null) {
4291                 return null;
4292             }
4293             return VisualVoicemailSettingsUtil.dump(mApp, phoneAccountHandle);
4294         } finally {
4295             Binder.restoreCallingIdentity(identity);
4296         }
4297     }
4298 
4299     @Override
getVisualVoicemailPackageName(String callingPackage, String callingFeatureId, int subId)4300     public String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId,
4301             int subId) {
4302         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4303         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4304                 mApp, subId, callingPackage, callingFeatureId,
4305                 "getVisualVoicemailPackageName")) {
4306             return null;
4307         }
4308 
4309         enforceTelephonyFeatureWithException(callingPackage,
4310                 PackageManager.FEATURE_TELEPHONY_CALLING, "getVisualVoicemailPackageName");
4311 
4312         final long identity = Binder.clearCallingIdentity();
4313         try {
4314             return RemoteVvmTaskManager.getRemotePackage(mApp, subId).getPackageName();
4315         } finally {
4316             Binder.restoreCallingIdentity(identity);
4317         }
4318     }
4319 
4320     @Override
enableVisualVoicemailSmsFilter(String callingPackage, int subId, VisualVoicemailSmsFilterSettings settings)4321     public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
4322             VisualVoicemailSmsFilterSettings settings) {
4323         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4324         enforceVisualVoicemailPackage(callingPackage, subId);
4325         enforceTelephonyFeatureWithException(callingPackage,
4326                 PackageManager.FEATURE_TELEPHONY_CALLING, "enableVisualVoicemailSmsFilter");
4327         final long identity = Binder.clearCallingIdentity();
4328         try {
4329             VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
4330                     mApp, callingPackage, subId, settings);
4331         } finally {
4332             Binder.restoreCallingIdentity(identity);
4333         }
4334     }
4335 
4336     @Override
disableVisualVoicemailSmsFilter(String callingPackage, int subId)4337     public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
4338         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4339         enforceVisualVoicemailPackage(callingPackage, subId);
4340         enforceTelephonyFeatureWithException(callingPackage,
4341                 PackageManager.FEATURE_TELEPHONY_CALLING, "disableVisualVoicemailSmsFilter");
4342 
4343         final long identity = Binder.clearCallingIdentity();
4344         try {
4345             VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
4346                     mApp, callingPackage, subId);
4347         } finally {
4348             Binder.restoreCallingIdentity(identity);
4349         }
4350     }
4351 
4352     @Override
getVisualVoicemailSmsFilterSettings( String callingPackage, int subId)4353     public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
4354             String callingPackage, int subId) {
4355         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4356 
4357         final long identity = Binder.clearCallingIdentity();
4358         try {
4359             return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
4360                     mApp, callingPackage, subId);
4361         } finally {
4362             Binder.restoreCallingIdentity(identity);
4363         }
4364     }
4365 
4366     @Override
getActiveVisualVoicemailSmsFilterSettings(int subId)4367     public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
4368         enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
4369 
4370         final long identity = Binder.clearCallingIdentity();
4371         try {
4372             return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
4373                     mApp, subId);
4374         } finally {
4375             Binder.restoreCallingIdentity(identity);
4376         }
4377     }
4378 
4379     @Override
sendVisualVoicemailSmsForSubscriber(String callingPackage, String callingAttributionTag, int subId, String number, int port, String text, PendingIntent sentIntent)4380     public void sendVisualVoicemailSmsForSubscriber(String callingPackage,
4381             String callingAttributionTag, int subId, String number, int port, String text,
4382             PendingIntent sentIntent) {
4383         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4384         enforceVisualVoicemailPackage(callingPackage, subId);
4385         enforceSendSmsPermission();
4386 
4387         enforceTelephonyFeatureWithException(callingPackage,
4388                 PackageManager.FEATURE_TELEPHONY_CALLING, "sendVisualVoicemailSmsForSubscriber");
4389 
4390         SmsController smsController = PhoneFactory.getSmsController();
4391         smsController.sendVisualVoicemailSmsForSubscriber(callingPackage,
4392                 Binder.getCallingUserHandle().getIdentifier(), callingAttributionTag, subId, number,
4393                 port, text, sentIntent);
4394     }
4395 
4396     /**
4397      * Sets the voice activation state of a given subId.
4398      */
4399     @Override
setVoiceActivationState(int subId, int activationState)4400     public void setVoiceActivationState(int subId, int activationState) {
4401         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4402                 mApp, subId, "setVoiceActivationState");
4403 
4404         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4405                 PackageManager.FEATURE_TELEPHONY_CALLING, "setVoiceActivationState");
4406 
4407         final long identity = Binder.clearCallingIdentity();
4408         try {
4409             final Phone phone = getPhone(subId);
4410             if (phone != null) {
4411                 phone.setVoiceActivationState(activationState);
4412             } else {
4413                 loge("setVoiceActivationState fails with invalid subId: " + subId);
4414             }
4415         } finally {
4416             Binder.restoreCallingIdentity(identity);
4417         }
4418     }
4419 
4420     /**
4421      * Sets the data activation state of a given subId.
4422      */
4423     @Override
setDataActivationState(int subId, int activationState)4424     public void setDataActivationState(int subId, int activationState) {
4425         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4426                 mApp, subId, "setDataActivationState");
4427 
4428         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4429                 PackageManager.FEATURE_TELEPHONY_DATA, "setDataActivationState");
4430 
4431         final long identity = Binder.clearCallingIdentity();
4432         try {
4433             final Phone phone = getPhone(subId);
4434             if (phone != null) {
4435                 phone.setDataActivationState(activationState);
4436             } else {
4437                 loge("setDataActivationState fails with invalid subId: " + subId);
4438             }
4439         } finally {
4440             Binder.restoreCallingIdentity(identity);
4441         }
4442     }
4443 
4444     /**
4445      * Returns the voice activation state of a given subId.
4446      */
4447     @Override
getVoiceActivationState(int subId, String callingPackage)4448     public int getVoiceActivationState(int subId, String callingPackage) {
4449         enforceReadPrivilegedPermission("getVoiceActivationState");
4450 
4451         enforceTelephonyFeatureWithException(callingPackage,
4452                 PackageManager.FEATURE_TELEPHONY_CALLING, "getVoiceActivationState");
4453 
4454         final Phone phone = getPhone(subId);
4455         final long identity = Binder.clearCallingIdentity();
4456         try {
4457             if (phone != null) {
4458                 return phone.getVoiceActivationState();
4459             } else {
4460                 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
4461             }
4462         } finally {
4463             Binder.restoreCallingIdentity(identity);
4464         }
4465     }
4466 
4467     /**
4468      * Returns the data activation state of a given subId.
4469      */
4470     @Override
getDataActivationState(int subId, String callingPackage)4471     public int getDataActivationState(int subId, String callingPackage) {
4472         enforceReadPrivilegedPermission("getDataActivationState");
4473 
4474         enforceTelephonyFeatureWithException(callingPackage,
4475                 PackageManager.FEATURE_TELEPHONY_DATA, "getDataActivationState");
4476 
4477         final Phone phone = getPhone(subId);
4478         final long identity = Binder.clearCallingIdentity();
4479         try {
4480             if (phone != null) {
4481                 return phone.getDataActivationState();
4482             } else {
4483                 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
4484             }
4485         } finally {
4486             Binder.restoreCallingIdentity(identity);
4487         }
4488     }
4489 
4490     /**
4491      * Returns the unread count of voicemails for a subId
4492      */
4493     @Override
getVoiceMessageCountForSubscriber(int subId, String callingPackage, String callingFeatureId)4494     public int getVoiceMessageCountForSubscriber(int subId, String callingPackage,
4495             String callingFeatureId) {
4496         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4497                 mApp, subId, callingPackage, callingFeatureId,
4498                 "getVoiceMessageCountForSubscriber")) {
4499             return 0;
4500         }
4501         final long identity = Binder.clearCallingIdentity();
4502         try {
4503             final Phone phone = getPhone(subId);
4504             if (phone != null) {
4505                 return phone.getVoiceMessageCount();
4506             } else {
4507                 return 0;
4508             }
4509         } finally {
4510             Binder.restoreCallingIdentity(identity);
4511         }
4512     }
4513 
4514     /**
4515      * returns true, if the device is in a state where both voice and data
4516      * are supported simultaneously. This can change based on location or network condition.
4517      */
4518     @Override
isConcurrentVoiceAndDataAllowed(int subId)4519     public boolean isConcurrentVoiceAndDataAllowed(int subId) {
4520         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4521                 PackageManager.FEATURE_TELEPHONY_DATA, "isConcurrentVoiceAndDataAllowed");
4522 
4523         final long identity = Binder.clearCallingIdentity();
4524         try {
4525             return getPhoneFromSubIdOrDefault(subId).isConcurrentVoiceAndDataAllowed();
4526         } finally {
4527             Binder.restoreCallingIdentity(identity);
4528         }
4529     }
4530 
4531     /**
4532      * Send the dialer code if called from the current default dialer or the caller has
4533      * carrier privilege.
4534      * @param inputCode The dialer code to send
4535      */
4536     @Override
sendDialerSpecialCode(String callingPackage, String inputCode)4537     public void sendDialerSpecialCode(String callingPackage, String inputCode) {
4538         final Phone defaultPhone = getDefaultPhone();
4539         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4540         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
4541         String defaultDialer = tm.getDefaultDialerPackage();
4542         if (!TextUtils.equals(callingPackage, defaultDialer)) {
4543             TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
4544                     getDefaultSubscription(), "sendDialerSpecialCode");
4545         }
4546 
4547         enforceTelephonyFeatureWithException(callingPackage,
4548                 PackageManager.FEATURE_TELEPHONY_CALLING, "sendDialerSpecialCode");
4549 
4550         final long identity = Binder.clearCallingIdentity();
4551         try {
4552             defaultPhone.sendDialerSpecialCode(inputCode);
4553         } finally {
4554             Binder.restoreCallingIdentity(identity);
4555         }
4556     }
4557 
4558     @Override
getNetworkSelectionMode(int subId)4559     public int getNetworkSelectionMode(int subId) {
4560         TelephonyPermissions
4561                 .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4562                         mApp, subId, "getNetworkSelectionMode");
4563 
4564         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4565                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getNetworkSelectionMode");
4566 
4567         final long identity = Binder.clearCallingIdentity();
4568         try {
4569             if (!isActiveSubscription(subId)) {
4570                 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
4571             }
4572             return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
4573         } finally {
4574             Binder.restoreCallingIdentity(identity);
4575         }
4576     }
4577 
4578     @Override
isInEmergencySmsMode()4579     public boolean isInEmergencySmsMode() {
4580         enforceReadPrivilegedPermission("isInEmergencySmsMode");
4581 
4582         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4583                 PackageManager.FEATURE_TELEPHONY_MESSAGING, "isInEmergencySmsMode");
4584 
4585         final long identity = Binder.clearCallingIdentity();
4586         try {
4587             for (Phone phone : PhoneFactory.getPhones()) {
4588                 if (phone.isInEmergencySmsMode()) {
4589                     return true;
4590                 }
4591             }
4592         } finally {
4593             Binder.restoreCallingIdentity(identity);
4594         }
4595         return false;
4596     }
4597 
4598     /**
4599      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4600      * @param subId The subscription to use to check the configuration.
4601      * @param c The callback that will be used to send the result.
4602      */
4603     @Override
registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)4604     public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)
4605             throws RemoteException {
4606         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4607                 mApp, subId, "registerImsRegistrationCallback");
4608 
4609         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4610             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4611                     "IMS not available on device.");
4612         }
4613         final long token = Binder.clearCallingIdentity();
4614         try {
4615             int slotId = getSlotIndexOrException(subId);
4616             verifyImsMmTelConfiguredOrThrow(slotId);
4617 
4618             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4619             if (controller != null) {
4620                 ImsManager imsManager = controller.getImsManager(subId);
4621                 if (imsManager != null) {
4622                     imsManager.addRegistrationCallbackForSubscription(c, subId);
4623                 } else {
4624                     throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
4625                 }
4626             } else {
4627                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
4628             }
4629         } catch (ImsException e) {
4630             throw new ServiceSpecificException(e.getCode());
4631         } finally {
4632             Binder.restoreCallingIdentity(token);
4633         }
4634     }
4635 
4636     /**
4637      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4638      * @param subId The subscription to use to check the configuration.
4639      * @param c The callback that will be used to send the result.
4640      */
4641     @Override
unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c)4642     public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c) {
4643         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4644                 mApp, subId, "unregisterImsRegistrationCallback");
4645         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4646             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
4647         }
4648         final long token = Binder.clearCallingIdentity();
4649 
4650         try {
4651             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4652             if (controller != null) {
4653                 ImsManager imsManager = controller.getImsManager(subId);
4654                 if (imsManager != null) {
4655                     imsManager.removeRegistrationCallbackForSubscription(c, subId);
4656                 } else {
4657                     Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
4658                             + "is inactive, ignoring unregister.");
4659                     // If the ImsManager is not valid, just return, since the callback
4660                     // will already have been removed internally.
4661                 }
4662             }
4663         } finally {
4664             Binder.restoreCallingIdentity(token);
4665         }
4666     }
4667 
4668     /**
4669      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4670      * @param subId The subscription to use to check the configuration.
4671      * @param c The callback that will be used to send the result.
4672      */
4673     @Override
registerImsEmergencyRegistrationCallback(int subId, IImsRegistrationCallback c)4674     public void registerImsEmergencyRegistrationCallback(int subId, IImsRegistrationCallback c)
4675             throws RemoteException {
4676         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4677                 mApp, subId, "registerImsEmergencyRegistrationCallback");
4678 
4679         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4680             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4681                     "IMS not available on device.");
4682         }
4683         final long token = Binder.clearCallingIdentity();
4684         try {
4685             int slotId = getSlotIndexOrException(subId);
4686             verifyImsMmTelConfiguredOrThrow(slotId);
4687 
4688             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4689             if (controller != null) {
4690                 ImsManager imsManager = controller.getImsManager(subId);
4691                 if (imsManager != null) {
4692                     imsManager.addEmergencyRegistrationCallbackForSubscription(c, subId);
4693                 } else {
4694                     throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
4695                 }
4696             } else {
4697                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
4698             }
4699         } catch (ImsException e) {
4700             throw new ServiceSpecificException(e.getCode());
4701         } finally {
4702             Binder.restoreCallingIdentity(token);
4703         }
4704     }
4705 
4706     /**
4707      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4708      * @param subId The subscription to use to check the configuration.
4709      * @param c The callback that will be used to send the result.
4710      */
4711     @Override
unregisterImsEmergencyRegistrationCallback(int subId, IImsRegistrationCallback c)4712     public void unregisterImsEmergencyRegistrationCallback(int subId, IImsRegistrationCallback c) {
4713         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4714                 mApp, subId, "unregisterImsEmergencyRegistrationCallback");
4715         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4716             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
4717         }
4718         final long token = Binder.clearCallingIdentity();
4719 
4720         try {
4721             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4722             if (controller != null) {
4723                 ImsManager imsManager = controller.getImsManager(subId);
4724                 if (imsManager != null) {
4725                     imsManager.removeEmergencyRegistrationCallbackForSubscription(c, subId);
4726                 } else {
4727                     Log.i(LOG_TAG, "unregisterImsEmergencyRegistrationCallback: " + subId
4728                             + "is inactive, ignoring unregister.");
4729                     // If the ImsManager is not valid, just return, since the callback
4730                     // will already have been removed internally.
4731                 }
4732             }
4733         } finally {
4734             Binder.restoreCallingIdentity(token);
4735         }
4736     }
4737 
4738     /**
4739      * Get the IMS service registration state for the MmTelFeature associated with this sub id.
4740      */
4741     @Override
getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer)4742     public void getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer) {
4743         enforceReadPrivilegedPermission("getImsMmTelRegistrationState");
4744         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4745             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4746                     "IMS not available on device.");
4747         }
4748         final long token = Binder.clearCallingIdentity();
4749         try {
4750             Phone phone = getPhone(subId);
4751             if (phone == null) {
4752                 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
4753                         + subId + "'");
4754                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4755             }
4756             phone.getImsRegistrationState(regState -> {
4757                 try {
4758                     consumer.accept((regState == null)
4759                             ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
4760                 } catch (RemoteException e) {
4761                     // Ignore if the remote process is no longer available to call back.
4762                     Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
4763                 }
4764             });
4765         } finally {
4766             Binder.restoreCallingIdentity(token);
4767         }
4768     }
4769 
4770     /**
4771      * Get the transport type for the IMS service registration state.
4772      */
4773     @Override
getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer)4774     public void getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer) {
4775         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4776                 mApp, subId, "getImsMmTelRegistrationTransportType");
4777         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4778             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4779                     "IMS not available on device.");
4780         }
4781         final long token = Binder.clearCallingIdentity();
4782         try {
4783             Phone phone = getPhone(subId);
4784             if (phone == null) {
4785                 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
4786                         + subId + "'");
4787                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4788             }
4789             phone.getImsRegistrationTech(regTech -> {
4790                 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
4791                 int regTechConverted = (regTech == null)
4792                         ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
4793                 regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
4794                         regTechConverted);
4795                 try {
4796                     consumer.accept(regTechConverted);
4797                 } catch (RemoteException e) {
4798                     // Ignore if the remote process is no longer available to call back.
4799                     Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
4800                 }
4801             });
4802         } finally {
4803             Binder.restoreCallingIdentity(token);
4804         }
4805     }
4806 
4807     /**
4808      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4809      * @param subId The subscription to use to check the configuration.
4810      * @param c The callback that will be used to send the result.
4811      */
4812     @Override
registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)4813     public void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)
4814             throws RemoteException {
4815         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4816                 mApp, subId, "registerMmTelCapabilityCallback");
4817         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4818             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4819                     "IMS not available on device.");
4820         }
4821         final long token = Binder.clearCallingIdentity();
4822         try {
4823             int slotId = getSlotIndexOrException(subId);
4824             verifyImsMmTelConfiguredOrThrow(slotId);
4825 
4826             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4827             if (controller != null) {
4828                 ImsManager imsManager = controller.getImsManager(subId);
4829                 if (imsManager != null) {
4830                     imsManager.addCapabilitiesCallbackForSubscription(c, subId);
4831                 } else {
4832                     throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
4833                 }
4834             } else {
4835                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
4836             }
4837         } catch (ImsException e) {
4838             throw new ServiceSpecificException(e.getCode());
4839         } finally {
4840             Binder.restoreCallingIdentity(token);
4841         }
4842     }
4843 
4844     /**
4845      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
4846      * @param subId The subscription to use to check the configuration.
4847      * @param c The callback that will be used to send the result.
4848      */
4849     @Override
unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)4850     public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
4851         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4852                 mApp, subId, "unregisterMmTelCapabilityCallback");
4853         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4854             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
4855         }
4856 
4857         final long token = Binder.clearCallingIdentity();
4858         try {
4859             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
4860             if (controller != null) {
4861                 ImsManager imsManager = controller.getImsManager(subId);
4862                 if (imsManager != null) {
4863                     imsManager.removeCapabilitiesCallbackForSubscription(c, subId);
4864                 } else {
4865                     Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
4866                             + " is inactive, ignoring unregister.");
4867                     // If the ImsManager is not valid, just return, since the callback
4868                     // will already have been removed internally.
4869                 }
4870             }
4871         } finally {
4872             Binder.restoreCallingIdentity(token);
4873         }
4874     }
4875 
4876     @Override
isCapable(int subId, int capability, int regTech)4877     public boolean isCapable(int subId, int capability, int regTech) {
4878         enforceReadPrivilegedPermission("isCapable");
4879 
4880         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4881                 FEATURE_TELEPHONY_IMS, "isCapable");
4882 
4883         final long token = Binder.clearCallingIdentity();
4884         try {
4885             int slotId = getSlotIndexOrException(subId);
4886             verifyImsMmTelConfiguredOrThrow(slotId);
4887             return ImsManager.getInstance(mApp, slotId).queryMmTelCapability(capability, regTech);
4888         } catch (com.android.ims.ImsException e) {
4889             Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
4890             return false;
4891         } catch (ImsException e) {
4892             Log.i(LOG_TAG, "isCapable: " + subId + " is inactive, returning false.");
4893             return false;
4894         } finally {
4895             Binder.restoreCallingIdentity(token);
4896         }
4897     }
4898 
4899     @Override
isAvailable(int subId, int capability, int regTech)4900     public boolean isAvailable(int subId, int capability, int regTech) {
4901         enforceReadPrivilegedPermission("isAvailable");
4902 
4903         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4904                 FEATURE_TELEPHONY_IMS, "isAvailable");
4905 
4906         final long token = Binder.clearCallingIdentity();
4907         try {
4908             Phone phone = getPhone(subId);
4909             if (phone == null) return false;
4910             return phone.isImsCapabilityAvailable(capability, regTech);
4911         } catch (com.android.ims.ImsException e) {
4912             Log.w(LOG_TAG, "IMS isAvailable - service unavailable: " + e.getMessage());
4913             return false;
4914         } finally {
4915             Binder.restoreCallingIdentity(token);
4916         }
4917     }
4918 
4919     /**
4920      * Determines if the MmTel feature capability is supported by the carrier configuration for this
4921      * subscription.
4922      * @param subId The subscription to use to check the configuration.
4923      * @param callback The callback that will be used to send the result.
4924      * @param capability The MmTelFeature capability that will be used to send the result.
4925      * @param transportType The transport type of the MmTelFeature capability.
4926      */
4927     @Override
isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability, int transportType)4928     public void isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability,
4929             int transportType) {
4930         enforceReadPrivilegedPermission("isMmTelCapabilitySupported");
4931         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
4932             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
4933                     "IMS not available on device.");
4934         }
4935         final long token = Binder.clearCallingIdentity();
4936         try {
4937             int slotId = getSlotIndex(subId);
4938             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4939                 Log.w(LOG_TAG, "isMmTelCapabilitySupported: called with an inactive subscription '"
4940                         + subId + "'");
4941                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4942             }
4943             verifyImsMmTelConfiguredOrThrow(slotId);
4944             ImsManager.getInstance(mApp, slotId).isSupported(capability,
4945                     transportType, aBoolean -> {
4946                         try {
4947                             callback.accept((aBoolean == null) ? 0 : (aBoolean ? 1 : 0));
4948                         } catch (RemoteException e) {
4949                             Log.w(LOG_TAG, "isMmTelCapabilitySupported: remote caller is not "
4950                                     + "running. Ignore");
4951                         }
4952                     });
4953         } catch (ImsException e) {
4954             throw new ServiceSpecificException(e.getCode());
4955         } finally {
4956             Binder.restoreCallingIdentity(token);
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
isAdvancedCallingSettingEnabled(int subId)4965     public boolean isAdvancedCallingSettingEnabled(int subId) {
4966         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
4967                 mApp, subId, "isAdvancedCallingSettingEnabled");
4968 
4969         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4970                 FEATURE_TELEPHONY_IMS, "isAdvancedCallingSettingEnabled");
4971 
4972         final long token = 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).isEnhanced4gLteModeSettingEnabledByUser();
4977         } catch (ImsException e) {
4978             throw new ServiceSpecificException(e.getCode());
4979         } finally {
4980             Binder.restoreCallingIdentity(token);
4981         }
4982     }
4983 
4984     @Override
setAdvancedCallingSettingEnabled(int subId, boolean isEnabled)4985     public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
4986         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4987                 "setAdvancedCallingSettingEnabled");
4988 
4989         enforceTelephonyFeatureWithException(getCurrentPackageName(),
4990                 FEATURE_TELEPHONY_IMS, "setAdvancedCallingSettingEnabled");
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).setEnhanced4gLteModeSetting(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
isVtSettingEnabled(int subId)5010     public boolean isVtSettingEnabled(int subId) {
5011         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5012                 mApp, subId, "isVtSettingEnabled");
5013 
5014         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5015                 FEATURE_TELEPHONY_IMS, "isVtSettingEnabled");
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).isVtEnabledByUser();
5022         } catch (ImsException e) {
5023             throw new ServiceSpecificException(e.getCode());
5024         } finally {
5025             Binder.restoreCallingIdentity(identity);
5026         }
5027     }
5028 
5029     @Override
setVtSettingEnabled(int subId, boolean isEnabled)5030     public void setVtSettingEnabled(int subId, boolean isEnabled) {
5031         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5032                 "setVtSettingEnabled");
5033 
5034         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5035                 FEATURE_TELEPHONY_IMS, "setVtSettingEnabled");
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).setVtSetting(isEnabled);
5043         } catch (ImsException e) {
5044             throw new ServiceSpecificException(e.getCode());
5045         } finally {
5046             Binder.restoreCallingIdentity(identity);
5047         }
5048     }
5049 
5050     /**
5051      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5052      * @param subId The subscription to use to check the configuration.
5053      */
5054     @Override
isVoWiFiSettingEnabled(int subId)5055     public boolean isVoWiFiSettingEnabled(int subId) {
5056         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5057                 mApp, subId, "isVoWiFiSettingEnabled");
5058 
5059         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5060                 FEATURE_TELEPHONY_IMS, "isVoWiFiSettingEnabled");
5061 
5062         final long identity = Binder.clearCallingIdentity();
5063         try {
5064             int slotId = getSlotIndexOrException(subId);
5065             // This setting doesn't require an active ImsService connection, so do not verify.
5066             return ImsManager.getInstance(mApp, slotId).isWfcEnabledByUser();
5067         } catch (ImsException e) {
5068             throw new ServiceSpecificException(e.getCode());
5069         } finally {
5070             Binder.restoreCallingIdentity(identity);
5071         }
5072     }
5073 
5074     @Override
setVoWiFiSettingEnabled(int subId, boolean isEnabled)5075     public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
5076         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5077                 "setVoWiFiSettingEnabled");
5078 
5079         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5080                 FEATURE_TELEPHONY_IMS, "setVoWiFiSettingEnabled");
5081 
5082         final long identity = Binder.clearCallingIdentity();
5083         try {
5084             int slotId = getSlotIndexOrException(subId);
5085             // This setting doesn't require an active ImsService connection, so do not verify. The
5086             // new setting will be picked up when the ImsService comes up next if it isn't up.
5087             ImsManager.getInstance(mApp, slotId).setWfcSetting(isEnabled);
5088         } catch (ImsException e) {
5089             throw new ServiceSpecificException(e.getCode());
5090         } finally {
5091             Binder.restoreCallingIdentity(identity);
5092         }
5093     }
5094 
5095     /**
5096      * @return true if the user's setting for Voice over Cross SIM is enabled and false if it is not
5097      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5098      * @param subId The subscription to use to check the configuration.
5099      */
5100     @Override
isCrossSimCallingEnabledByUser(int subId)5101     public boolean isCrossSimCallingEnabledByUser(int subId) {
5102         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5103                 mApp, subId, "isCrossSimCallingEnabledByUser");
5104 
5105         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5106                 FEATURE_TELEPHONY_IMS, "isCrossSimCallingEnabledByUser");
5107 
5108         final long identity = Binder.clearCallingIdentity();
5109         try {
5110             int slotId = getSlotIndexOrException(subId);
5111             // This setting doesn't require an active ImsService connection, so do not verify.
5112             return ImsManager.getInstance(mApp, slotId).isCrossSimCallingEnabledByUser();
5113         } catch (ImsException e) {
5114             throw new ServiceSpecificException(e.getCode());
5115         } finally {
5116             Binder.restoreCallingIdentity(identity);
5117         }
5118     }
5119 
5120     /**
5121      * Sets the user's setting for whether or not Voice over Cross SIM is enabled.
5122      * Requires MODIFY_PHONE_STATE permission.
5123      * @param subId The subscription to use to check the configuration.
5124      * @param isEnabled true if the user's setting for Voice over Cross SIM is enabled,
5125      *                 false otherwise
5126      */
5127     @Override
setCrossSimCallingEnabled(int subId, boolean isEnabled)5128     public void setCrossSimCallingEnabled(int subId, boolean isEnabled) {
5129         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5130                 "setCrossSimCallingEnabled");
5131 
5132         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5133                 FEATURE_TELEPHONY_IMS, "setCrossSimCallingEnabled");
5134 
5135         final long identity = Binder.clearCallingIdentity();
5136         try {
5137             int slotId = getSlotIndexOrException(subId);
5138             // This setting doesn't require an active ImsService connection, so do not verify. The
5139             // new setting will be picked up when the ImsService comes up next if it isn't up.
5140             ImsManager.getInstance(mApp, slotId).setCrossSimCallingEnabled(isEnabled);
5141         } catch (ImsException e) {
5142             throw new ServiceSpecificException(e.getCode());
5143         } finally {
5144             Binder.restoreCallingIdentity(identity);
5145         }
5146     }
5147 
5148     /**
5149      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5150      * @param subId The subscription to use to check the configuration.
5151      */
5152     @Override
5153 
isVoWiFiRoamingSettingEnabled(int subId)5154     public boolean isVoWiFiRoamingSettingEnabled(int subId) {
5155         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5156                 mApp, subId, "isVoWiFiRoamingSettingEnabled");
5157 
5158         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5159                 FEATURE_TELEPHONY_IMS, "isVoWiFiRoamingSettingEnabled");
5160 
5161         final long identity = Binder.clearCallingIdentity();
5162         try {
5163             int slotId = getSlotIndexOrException(subId);
5164             // This setting doesn't require an active ImsService connection, so do not verify.
5165             return ImsManager.getInstance(mApp, slotId).isWfcRoamingEnabledByUser();
5166         } catch (ImsException e) {
5167             throw new ServiceSpecificException(e.getCode());
5168         } finally {
5169             Binder.restoreCallingIdentity(identity);
5170         }
5171     }
5172 
5173     @Override
setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled)5174     public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
5175         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5176                 "setVoWiFiRoamingSettingEnabled");
5177 
5178         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5179                 FEATURE_TELEPHONY_IMS, "setVoWiFiRoamingSettingEnabled");
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. The
5185             // new setting will be picked up when the ImsService comes up next if it isn't up.
5186             ImsManager.getInstance(mApp, slotId).setWfcRoamingSetting(isEnabled);
5187         } catch (ImsException e) {
5188             throw new ServiceSpecificException(e.getCode());
5189         } finally {
5190             Binder.restoreCallingIdentity(identity);
5191         }
5192     }
5193 
5194     @Override
setVoWiFiNonPersistent(int subId, boolean isCapable, int mode)5195     public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
5196         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5197                 "setVoWiFiNonPersistent");
5198 
5199         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5200                 FEATURE_TELEPHONY_IMS, "setVoWiFiNonPersistent");
5201 
5202         final long identity = Binder.clearCallingIdentity();
5203         try {
5204             int slotId = getSlotIndexOrException(subId);
5205             // This setting will be ignored if the ImsService isn't up.
5206             ImsManager.getInstance(mApp, slotId).setWfcNonPersistent(isCapable, mode);
5207         } catch (ImsException e) {
5208             throw new ServiceSpecificException(e.getCode());
5209         } finally {
5210             Binder.restoreCallingIdentity(identity);
5211         }
5212     }
5213 
5214     /**
5215      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5216      * @param subId The subscription to use to check the configuration.
5217      */
5218     @Override
getVoWiFiModeSetting(int subId)5219     public int getVoWiFiModeSetting(int subId) {
5220         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5221                 mApp, subId, "getVoWiFiModeSetting");
5222 
5223         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5224                 FEATURE_TELEPHONY_IMS, "getVoWiFiModeSetting");
5225 
5226         final long identity = Binder.clearCallingIdentity();
5227         try {
5228             int slotId = getSlotIndexOrException(subId);
5229             // This setting doesn't require an active ImsService connection, so do not verify.
5230             return ImsManager.getInstance(mApp, slotId).getWfcMode(false /*isRoaming*/);
5231         } catch (ImsException e) {
5232             throw new ServiceSpecificException(e.getCode());
5233         } finally {
5234             Binder.restoreCallingIdentity(identity);
5235         }
5236     }
5237 
5238     @Override
setVoWiFiModeSetting(int subId, int mode)5239     public void setVoWiFiModeSetting(int subId, int mode) {
5240         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5241                 "setVoWiFiModeSetting");
5242 
5243         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5244                 FEATURE_TELEPHONY_IMS, "setVoWiFiModeSetting");
5245 
5246         final long identity = Binder.clearCallingIdentity();
5247         try {
5248             int slotId = getSlotIndexOrException(subId);
5249             // This setting doesn't require an active ImsService connection, so do not verify. The
5250             // new setting will be picked up when the ImsService comes up next if it isn't up.
5251             ImsManager.getInstance(mApp, slotId).setWfcMode(mode, false /*isRoaming*/);
5252         } catch (ImsException e) {
5253             throw new ServiceSpecificException(e.getCode());
5254         } finally {
5255             Binder.restoreCallingIdentity(identity);
5256         }
5257     }
5258 
5259     @Override
getVoWiFiRoamingModeSetting(int subId)5260     public int getVoWiFiRoamingModeSetting(int subId) {
5261         enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
5262 
5263         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5264                 FEATURE_TELEPHONY_IMS, "getVoWiFiRoamingModeSetting");
5265 
5266         final long identity = Binder.clearCallingIdentity();
5267         try {
5268             int slotId = getSlotIndexOrException(subId);
5269             // This setting doesn't require an active ImsService connection, so do not verify.
5270             return ImsManager.getInstance(mApp, slotId).getWfcMode(true /*isRoaming*/);
5271         } catch (ImsException e) {
5272             throw new ServiceSpecificException(e.getCode());
5273         } finally {
5274             Binder.restoreCallingIdentity(identity);
5275         }
5276     }
5277 
5278     @Override
setVoWiFiRoamingModeSetting(int subId, int mode)5279     public void setVoWiFiRoamingModeSetting(int subId, int mode) {
5280         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5281                 "setVoWiFiRoamingModeSetting");
5282 
5283         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5284                 FEATURE_TELEPHONY_IMS, "setVoWiFiRoamingModeSetting");
5285 
5286         final long identity = Binder.clearCallingIdentity();
5287         try {
5288             int slotId = getSlotIndexOrException(subId);
5289             // This setting doesn't require an active ImsService connection, so do not verify. The
5290             // new setting will be picked up when the ImsService comes up next if it isn't up.
5291             ImsManager.getInstance(mApp, slotId).setWfcMode(mode, true /*isRoaming*/);
5292         } catch (ImsException e) {
5293             throw new ServiceSpecificException(e.getCode());
5294         } finally {
5295             Binder.restoreCallingIdentity(identity);
5296         }
5297     }
5298 
5299     @Override
setRttCapabilitySetting(int subId, boolean isEnabled)5300     public void setRttCapabilitySetting(int subId, boolean isEnabled) {
5301         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5302                 "setRttCapabilityEnabled");
5303 
5304         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5305                 FEATURE_TELEPHONY_IMS, "setRttCapabilitySetting");
5306 
5307         final long identity = Binder.clearCallingIdentity();
5308         try {
5309             int slotId = getSlotIndexOrException(subId);
5310             // This setting doesn't require an active ImsService connection, so do not verify. The
5311             // new setting will be picked up when the ImsService comes up next if it isn't up.
5312             ImsManager.getInstance(mApp, slotId).setRttEnabled(isEnabled);
5313         } catch (ImsException e) {
5314             throw new ServiceSpecificException(e.getCode());
5315         } finally {
5316             Binder.restoreCallingIdentity(identity);
5317         }
5318     }
5319 
5320     /**
5321      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
5322      * @param subId The subscription to use to check the configuration.
5323      */
5324     @Override
isTtyOverVolteEnabled(int subId)5325     public boolean isTtyOverVolteEnabled(int subId) {
5326         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5327                 mApp, subId, "isTtyOverVolteEnabled");
5328 
5329         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5330                 FEATURE_TELEPHONY_IMS, "isTtyOverVolteEnabled");
5331 
5332         final long identity = Binder.clearCallingIdentity();
5333         try {
5334             int slotId = getSlotIndexOrException(subId);
5335             // This setting doesn't require an active ImsService connection, so do not verify.
5336             return ImsManager.getInstance(mApp, slotId).isTtyOnVoLteCapable();
5337         } catch (ImsException e) {
5338             throw new ServiceSpecificException(e.getCode());
5339         } finally {
5340             Binder.restoreCallingIdentity(identity);
5341         }
5342     }
5343 
5344     @Override
registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback)5345     public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
5346         enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
5347 
5348         final long identity = Binder.clearCallingIdentity();
5349         try {
5350             if (!isImsAvailableOnDevice()) {
5351                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5352                         "IMS not available on device.");
5353             }
5354             int slotId = getSlotIndexOrException(subId);
5355             verifyImsMmTelConfiguredOrThrow(slotId);
5356 
5357             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
5358             if (controller != null) {
5359                 ImsManager imsManager = controller.getImsManager(subId);
5360                 if (imsManager != null) {
5361                     imsManager.addProvisioningCallbackForSubscription(callback, subId);
5362                 } else {
5363                     throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
5364                 }
5365             } else {
5366                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
5367             }
5368         } catch (ImsException e) {
5369             throw new ServiceSpecificException(e.getCode());
5370         } finally {
5371             Binder.restoreCallingIdentity(identity);
5372         }
5373     }
5374 
5375     @Override
unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback)5376     public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
5377         enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
5378 
5379         final long identity = Binder.clearCallingIdentity();
5380         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5381             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
5382         }
5383         try {
5384             ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
5385             if (controller != null) {
5386                 ImsManager imsManager = controller.getImsManager(subId);
5387                 if (imsManager != null) {
5388                     imsManager.removeProvisioningCallbackForSubscription(callback, subId);
5389                 } else {
5390                     Log.i(LOG_TAG, "unregisterImsProvisioningChangedCallback: " + subId
5391                             + " is inactive, ignoring unregister.");
5392                     // If the ImsManager is not valid, just return, since the callback will already
5393                     // have been removed internally.
5394                 }
5395             }
5396         } finally {
5397             Binder.restoreCallingIdentity(identity);
5398         }
5399     }
5400 
5401     @Override
registerFeatureProvisioningChangedCallback(int subId, IFeatureProvisioningCallback callback)5402     public void registerFeatureProvisioningChangedCallback(int subId,
5403             IFeatureProvisioningCallback callback) {
5404         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5405                 mApp, subId, "registerFeatureProvisioningChangedCallback");
5406 
5407         final long identity = Binder.clearCallingIdentity();
5408         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5409             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
5410         }
5411 
5412         try {
5413             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5414             if (controller == null) {
5415                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5416                         "Device does not support IMS");
5417             }
5418             controller.addFeatureProvisioningChangedCallback(subId, callback);
5419         } finally {
5420             Binder.restoreCallingIdentity(identity);
5421         }
5422     }
5423 
5424     @Override
unregisterFeatureProvisioningChangedCallback(int subId, IFeatureProvisioningCallback callback)5425     public void unregisterFeatureProvisioningChangedCallback(int subId,
5426             IFeatureProvisioningCallback callback) {
5427         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5428                 mApp, subId, "unregisterFeatureProvisioningChangedCallback");
5429 
5430         final long identity = Binder.clearCallingIdentity();
5431         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5432             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
5433         }
5434 
5435         try {
5436             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5437             if (controller == null) {
5438                 loge("unregisterFeatureProvisioningChangedCallback: Device does not support IMS");
5439                 return;
5440             }
5441             controller.removeFeatureProvisioningChangedCallback(subId, callback);
5442         } finally {
5443             Binder.restoreCallingIdentity(identity);
5444         }
5445     }
5446 
checkModifyPhoneStatePermission(int subId, String message)5447     private void checkModifyPhoneStatePermission(int subId, String message) {
5448         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5449                 message);
5450     }
5451 
5452     @Override
setRcsProvisioningStatusForCapability(int subId, int capability, int tech, boolean isProvisioned)5453     public void setRcsProvisioningStatusForCapability(int subId, int capability, int tech,
5454             boolean isProvisioned) {
5455         checkModifyPhoneStatePermission(subId, "setRcsProvisioningStatusForCapability");
5456 
5457         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5458                 FEATURE_TELEPHONY_IMS, "setRcsProvisioningStatusForCapability");
5459 
5460         final long identity = Binder.clearCallingIdentity();
5461         try {
5462             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5463             if (controller == null) {
5464                 loge("setRcsProvisioningStatusForCapability: Device does not support IMS");
5465                 return;
5466             }
5467             controller.setRcsProvisioningStatusForCapability(
5468                     subId, capability, tech, isProvisioned);
5469         } finally {
5470             Binder.restoreCallingIdentity(identity);
5471         }
5472     }
5473 
5474 
5475     @Override
getRcsProvisioningStatusForCapability(int subId, int capability, int tech)5476     public boolean getRcsProvisioningStatusForCapability(int subId, int capability, int tech) {
5477         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5478                 mApp, subId, "getRcsProvisioningStatusForCapability");
5479 
5480         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5481                 FEATURE_TELEPHONY_IMS, "getRcsProvisioningStatusForCapability");
5482 
5483         final long identity = Binder.clearCallingIdentity();
5484         try {
5485             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5486             if (controller == null) {
5487                 loge("getRcsProvisioningStatusForCapability: 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.getRcsProvisioningStatusForCapability(subId, capability, tech);
5493         } finally {
5494             Binder.restoreCallingIdentity(identity);
5495         }
5496     }
5497 
5498     @Override
setImsProvisioningStatusForCapability(int subId, int capability, int tech, boolean isProvisioned)5499     public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
5500             boolean isProvisioned) {
5501         checkModifyPhoneStatePermission(subId, "setImsProvisioningStatusForCapability");
5502 
5503         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5504                 FEATURE_TELEPHONY_IMS, "setImsProvisioningStatusForCapability");
5505 
5506         String displayPackageName = getCurrentPackageNameOrPhone();
5507         final long identity = Binder.clearCallingIdentity();
5508         try {
5509             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5510             if (controller == null) {
5511                 loge("setImsProvisioningStatusForCapability: Device does not support IMS");
5512                 return;
5513             }
5514             controller.setImsProvisioningStatusForCapability(displayPackageName,
5515                     subId, capability, tech, isProvisioned);
5516         } finally {
5517             Binder.restoreCallingIdentity(identity);
5518         }
5519     }
5520 
5521     @Override
getImsProvisioningStatusForCapability(int subId, int capability, int tech)5522     public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
5523         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5524                 mApp, subId, "getProvisioningStatusForCapability");
5525 
5526         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5527                 FEATURE_TELEPHONY_IMS, "getImsProvisioningStatusForCapability");
5528 
5529         String displayPackageName = getCurrentPackageNameOrPhone();
5530         final long identity = Binder.clearCallingIdentity();
5531         try {
5532             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5533             if (controller == null) {
5534                 loge("getImsProvisioningStatusForCapability: Device does not support IMS");
5535 
5536                 // device does not support IMS, this method will return true always.
5537                 return true;
5538             }
5539             return controller.getImsProvisioningStatusForCapability(displayPackageName,
5540                     subId, capability, tech);
5541         } finally {
5542             Binder.restoreCallingIdentity(identity);
5543         }
5544     }
5545 
5546     @Override
isProvisioningRequiredForCapability(int subId, int capability, int tech)5547     public boolean isProvisioningRequiredForCapability(int subId, int capability, int tech) {
5548         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5549                 mApp, subId, "isProvisioningRequiredForCapability");
5550 
5551         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5552                 FEATURE_TELEPHONY_IMS, "isProvisioningRequiredForCapability");
5553 
5554         final long identity = Binder.clearCallingIdentity();
5555         try {
5556             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5557             if (controller == null) {
5558                 loge("isProvisioningRequiredForCapability: Device does not support IMS");
5559 
5560                 // device does not support IMS, this method will return false
5561                 return false;
5562             }
5563             return controller.isImsProvisioningRequiredForCapability(subId, capability, tech);
5564         } finally {
5565             Binder.restoreCallingIdentity(identity);
5566         }
5567     }
5568 
5569     @Override
isRcsProvisioningRequiredForCapability(int subId, int capability, int tech)5570     public boolean isRcsProvisioningRequiredForCapability(int subId, int capability, int tech) {
5571         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5572                 mApp, subId, "isProvisioningRequiredForCapability");
5573 
5574         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5575                 FEATURE_TELEPHONY_IMS, "isRcsProvisioningRequiredForCapability");
5576 
5577         final long identity = Binder.clearCallingIdentity();
5578         try {
5579             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5580             if (controller == null) {
5581                 loge("isRcsProvisioningRequiredForCapability: Device does not support IMS");
5582 
5583                 // device does not support IMS, this method will return false
5584                 return false;
5585             }
5586             return controller.isRcsProvisioningRequiredForCapability(subId, capability, tech);
5587         } finally {
5588             Binder.restoreCallingIdentity(identity);
5589         }
5590     }
5591 
5592     @Override
getImsProvisioningInt(int subId, int key)5593     public int getImsProvisioningInt(int subId, int key) {
5594         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5595             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5596         }
5597         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5598                 mApp, subId, "getImsProvisioningInt");
5599 
5600         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5601                 FEATURE_TELEPHONY_IMS, "getImsProvisioningInt");
5602 
5603         String displayPackageName = getCurrentPackageNameOrPhone();
5604         final long identity = Binder.clearCallingIdentity();
5605         try {
5606             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
5607             int slotId = getSlotIndex(subId);
5608             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5609                 Log.w(LOG_TAG, "getImsProvisioningInt: called with an inactive subscription '"
5610                         + subId + "' for key:" + key);
5611                 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
5612             }
5613 
5614             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5615             if (controller == null) {
5616                 loge("getImsProvisioningInt: Device does not support IMS");
5617 
5618                 // device does not support IMS, this method will return CONFIG_RESULT_UNKNOWN.
5619                 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
5620             }
5621             int retVal = controller.getProvisioningValue(displayPackageName, subId,
5622                     key);
5623             if (retVal != ImsConfigImplBase.CONFIG_RESULT_UNKNOWN) {
5624                 return retVal;
5625             }
5626 
5627             return ImsManager.getInstance(mApp, slotId).getConfigInt(key);
5628         } catch (com.android.ims.ImsException e) {
5629             Log.w(LOG_TAG, "getImsProvisioningInt: ImsService is not available for subscription '"
5630                     + subId + "' for key:" + key);
5631             return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
5632         } finally {
5633             Binder.restoreCallingIdentity(identity);
5634         }
5635     }
5636 
5637     @Override
getImsProvisioningString(int subId, int key)5638     public String getImsProvisioningString(int subId, int key) {
5639         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5640             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5641         }
5642         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5643                 mApp, subId, "getImsProvisioningString");
5644 
5645         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5646                 FEATURE_TELEPHONY_IMS, "getImsProvisioningString");
5647 
5648         final long identity = Binder.clearCallingIdentity();
5649         try {
5650             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
5651             int slotId = getSlotIndex(subId);
5652             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5653                 Log.w(LOG_TAG, "getImsProvisioningString: called for an inactive subscription id '"
5654                         + subId + "' for key:" + key);
5655                 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_GENERIC;
5656             }
5657             return ImsManager.getInstance(mApp, slotId).getConfigString(key);
5658         } catch (com.android.ims.ImsException e) {
5659             Log.w(LOG_TAG, "getImsProvisioningString: ImsService is not available for sub '"
5660                     + subId + "' for key:" + key);
5661             return ProvisioningManager.STRING_QUERY_RESULT_ERROR_NOT_READY;
5662         } finally {
5663             Binder.restoreCallingIdentity(identity);
5664         }
5665     }
5666 
5667     @Override
setImsProvisioningInt(int subId, int key, int value)5668     public int setImsProvisioningInt(int subId, int key, int value) {
5669         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5670             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5671         }
5672         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5673                 "setImsProvisioningInt");
5674 
5675         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5676                 FEATURE_TELEPHONY_IMS, "setImsProvisioningInt");
5677 
5678         String displayPackageName = getCurrentPackageNameOrPhone();
5679         final long identity = Binder.clearCallingIdentity();
5680         try {
5681             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
5682             int slotId = getSlotIndex(subId);
5683             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5684                 Log.w(LOG_TAG, "setImsProvisioningInt: called with an inactive subscription id '"
5685                         + subId + "' for key:" + key);
5686                 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5687             }
5688 
5689             ImsProvisioningController controller = ImsProvisioningController.getInstance();
5690             if (controller == null) {
5691                 loge("setImsProvisioningInt: Device does not support IMS");
5692 
5693                 // device does not support IMS, this method will return CONFIG_RESULT_FAILED.
5694                 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5695             }
5696             int retVal = controller.setProvisioningValue(displayPackageName, subId, key,
5697                     value);
5698             if (retVal != ImsConfigImplBase.CONFIG_RESULT_UNKNOWN) {
5699                 return retVal;
5700             }
5701 
5702             return ImsManager.getInstance(mApp, slotId).setConfig(key, value);
5703         } catch (com.android.ims.ImsException | RemoteException e) {
5704             Log.w(LOG_TAG, "setImsProvisioningInt: ImsService unavailable for sub '" + subId
5705                     + "' for key:" + key, e);
5706             return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5707         } finally {
5708             Binder.restoreCallingIdentity(identity);
5709         }
5710     }
5711 
5712     @Override
setImsProvisioningString(int subId, int key, String value)5713     public int setImsProvisioningString(int subId, int key, String value) {
5714         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
5715             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
5716         }
5717         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
5718                 "setImsProvisioningString");
5719 
5720         enforceTelephonyFeatureWithException(getCurrentPackageName(),
5721                 FEATURE_TELEPHONY_IMS, "setImsProvisioningString");
5722 
5723         final long identity = Binder.clearCallingIdentity();
5724         try {
5725             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
5726             int slotId = getSlotIndex(subId);
5727             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5728                 Log.w(LOG_TAG, "setImsProvisioningString: called with an inactive subscription id '"
5729                         + subId + "' for key:" + key);
5730                 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5731             }
5732             return ImsManager.getInstance(mApp, slotId).setConfig(key, value);
5733         } catch (com.android.ims.ImsException | RemoteException e) {
5734             Log.w(LOG_TAG, "setImsProvisioningString: ImsService unavailable for sub '" + subId
5735                     + "' for key:" + key, e);
5736             return ImsConfigImplBase.CONFIG_RESULT_FAILED;
5737         } finally {
5738             Binder.restoreCallingIdentity(identity);
5739         }
5740     }
5741 
5742     /**
5743      * Throw an ImsException if the IMS resolver does not have an ImsService configured for MMTEL
5744      * for the given slot ID or no ImsResolver instance has been created.
5745      * @param slotId The slot ID that the IMS service is created for.
5746      * @throws ImsException If there is no ImsService configured for this slot.
5747      */
verifyImsMmTelConfiguredOrThrow(int slotId)5748     private void verifyImsMmTelConfiguredOrThrow(int slotId) throws ImsException {
5749         if (mImsResolver == null || !mImsResolver.isImsServiceConfiguredForFeature(slotId,
5750                 ImsFeature.FEATURE_MMTEL)) {
5751             throw new ImsException("This subscription does not support MMTEL over IMS",
5752                     ImsException.CODE_ERROR_UNSUPPORTED_OPERATION);
5753         }
5754     }
5755 
getSlotIndexOrException(int subId)5756     private int getSlotIndexOrException(int subId) throws ImsException {
5757         int slotId = SubscriptionManager.getSlotIndex(subId);
5758         if (!SubscriptionManager.isValidSlotIndex(slotId)) {
5759             throw new ImsException("Invalid Subscription Id, subId=" + subId,
5760                     ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
5761         }
5762         return slotId;
5763     }
5764 
getSlotIndex(int subId)5765     private int getSlotIndex(int subId) {
5766         int slotId = SubscriptionManager.getSlotIndex(subId);
5767         if (!SubscriptionManager.isValidSlotIndex(slotId)) {
5768             return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
5769         }
5770         return slotId;
5771     }
5772 
5773     /**
5774      * Returns the data network type for a subId; does not throw SecurityException.
5775      */
5776     @Override
getNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId)5777     public int getNetworkTypeForSubscriber(int subId, String callingPackage,
5778             String callingFeatureId) {
5779         try {
5780             mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
5781         } catch (SecurityException se) {
5782             EventLog.writeEvent(0x534e4554, "186776740", Binder.getCallingUid());
5783             throw new SecurityException("Package " + callingPackage + " does not belong to "
5784                     + Binder.getCallingUid());
5785         }
5786         final int targetSdk = TelephonyPermissions.getTargetSdk(mApp, callingPackage);
5787         if (targetSdk > android.os.Build.VERSION_CODES.Q) {
5788             return getDataNetworkTypeForSubscriber(subId, callingPackage, callingFeatureId);
5789         } else if (targetSdk == android.os.Build.VERSION_CODES.Q
5790                 && !TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
5791                 mApp, subId, callingPackage, callingFeatureId,
5792                 "getNetworkTypeForSubscriber")) {
5793             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5794         }
5795 
5796         enforceTelephonyFeatureWithException(callingPackage,
5797                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getNetworkTypeForSubscriber");
5798 
5799         final long identity = Binder.clearCallingIdentity();
5800         try {
5801             final Phone phone = getPhone(subId);
5802             if (phone != null) {
5803                 return phone.getServiceState().getDataNetworkType();
5804             } else {
5805                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5806             }
5807         } finally {
5808             Binder.restoreCallingIdentity(identity);
5809         }
5810     }
5811 
5812     /**
5813      * Returns the data network type
5814      */
5815     @Override
getDataNetworkType(String callingPackage, String callingFeatureId)5816     public int getDataNetworkType(String callingPackage, String callingFeatureId) {
5817         return getDataNetworkTypeForSubscriber(SubscriptionManager.getDefaultDataSubscriptionId(),
5818                 callingPackage, callingFeatureId);
5819     }
5820 
5821     /**
5822      * Returns the data network type for a subId
5823      */
5824     @Override
getDataNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId)5825     public int getDataNetworkTypeForSubscriber(int subId, String callingPackage,
5826             String callingFeatureId) {
5827         String functionName = "getDataNetworkTypeForSubscriber";
5828         if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
5829                 mApp, functionName)) {
5830             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5831                     mApp, subId, callingPackage, callingFeatureId, functionName)) {
5832                 loge("getDataNetworkTypeForSubscriber: missing permission " + callingPackage);
5833                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5834             }
5835         }
5836 
5837         enforceTelephonyFeatureWithException(callingPackage,
5838                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getDataNetworkTypeForSubscriber");
5839 
5840         final long identity = Binder.clearCallingIdentity();
5841         try {
5842             final Phone phone = getPhone(subId);
5843             if (phone != null) {
5844                 return phone.getServiceState().getDataNetworkType();
5845             } else {
5846                 loge("getDataNetworkTypeForSubscriber: phone is null for sub " + subId);
5847                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5848             }
5849         } finally {
5850             Binder.restoreCallingIdentity(identity);
5851         }
5852     }
5853 
5854     /**
5855      * Returns the Voice network type for a subId
5856      */
5857     @Override
getVoiceNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId)5858     public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage,
5859             String callingFeatureId) {
5860         String functionName = "getVoiceNetworkTypeForSubscriber";
5861         if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
5862                 mApp, functionName)) {
5863             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
5864                     mApp, subId, callingPackage, callingFeatureId, functionName)) {
5865                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5866             }
5867         }
5868 
5869         enforceTelephonyFeatureWithException(callingPackage,
5870                 PackageManager.FEATURE_TELEPHONY_CALLING, "getVoiceNetworkTypeForSubscriber");
5871 
5872         final long identity = Binder.clearCallingIdentity();
5873         try {
5874             final Phone phone = getPhone(subId);
5875             if (phone != null) {
5876                 return phone.getServiceState().getVoiceNetworkType();
5877             } else {
5878                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
5879             }
5880         } finally {
5881             Binder.restoreCallingIdentity(identity);
5882         }
5883     }
5884 
5885     /**
5886      * @return true if a ICC card is present
5887      */
hasIccCard()5888     public boolean hasIccCard() {
5889         // FIXME Make changes to pass defaultSimId of type int
5890         return hasIccCardUsingSlotIndex(SubscriptionManager.getSlotIndex(
5891                 getDefaultSubscription()));
5892     }
5893 
5894     /**
5895      * @return true if a ICC card is present for a slotIndex
5896      */
5897     @Override
hasIccCardUsingSlotIndex(int slotIndex)5898     public boolean hasIccCardUsingSlotIndex(int slotIndex) {
5899         if (!mApp.getResources().getBoolean(
5900                 com.android.internal.R.bool.config_force_phone_globals_creation)) {
5901             enforceTelephonyFeatureWithException(getCurrentPackageName(),
5902                     PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "hasIccCardUsingSlotIndex");
5903         }
5904 
5905         final long identity = Binder.clearCallingIdentity();
5906         try {
5907             final Phone phone = PhoneFactory.getPhone(slotIndex);
5908             if (phone != null) {
5909                 return phone.getIccCard().hasIccCard();
5910             } else {
5911                 return false;
5912             }
5913         } finally {
5914             Binder.restoreCallingIdentity(identity);
5915         }
5916     }
5917 
5918     /**
5919      * Return if the current radio is LTE on CDMA. This
5920      * is a tri-state return value as for a period of time
5921      * the mode may be unknown.
5922      *
5923      * @param callingPackage the name of the package making the call.
5924      * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
5925      * or {@link Phone#LTE_ON_CDMA_TRUE}
5926      */
5927     @Override
getLteOnCdmaMode(String callingPackage, String callingFeatureId)5928     public int getLteOnCdmaMode(String callingPackage, String callingFeatureId) {
5929         return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage,
5930                 callingFeatureId);
5931     }
5932 
5933     @Override
getLteOnCdmaModeForSubscriber(int subId, String callingPackage, String callingFeatureId)5934     public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage,
5935             String callingFeatureId) {
5936         try {
5937             enforceReadPrivilegedPermission("getLteOnCdmaModeForSubscriber");
5938         } catch (SecurityException e) {
5939             return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
5940         }
5941 
5942         enforceTelephonyFeatureWithException(callingPackage,
5943                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getLteOnCdmaModeForSubscriber");
5944 
5945         final long identity = Binder.clearCallingIdentity();
5946         try {
5947             final Phone phone = getPhone(subId);
5948             if (phone == null) {
5949                 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
5950             } else {
5951                 return TelephonyProperties.lte_on_cdma_device()
5952                         .orElse(PhoneConstants.LTE_ON_CDMA_FALSE);
5953             }
5954         } finally {
5955             Binder.restoreCallingIdentity(identity);
5956         }
5957     }
5958 
5959     /**
5960      * {@hide}
5961      * Returns Default subId, 0 in the case of single standby.
5962      */
getDefaultSubscription()5963     private int getDefaultSubscription() {
5964         return SubscriptionManager.getDefaultSubscriptionId();
5965     }
5966 
getSlotForDefaultSubscription()5967     private int getSlotForDefaultSubscription() {
5968         return SubscriptionManager.getPhoneId(getDefaultSubscription());
5969     }
5970 
getPreferredVoiceSubscription()5971     private int getPreferredVoiceSubscription() {
5972         return SubscriptionManager.getDefaultVoiceSubscriptionId();
5973     }
5974 
isActiveSubscription(int subId)5975     private boolean isActiveSubscription(int subId) {
5976         return getSubscriptionManagerService().isActiveSubId(subId,
5977                 mApp.getOpPackageName(), mApp.getFeatureId());
5978     }
5979 
5980     /**
5981      * @see android.telephony.TelephonyManager.WifiCallingChoices
5982      */
getWhenToMakeWifiCalls()5983     public int getWhenToMakeWifiCalls() {
5984         final long identity = Binder.clearCallingIdentity();
5985         try {
5986             return Settings.System.getInt(mApp.getContentResolver(),
5987                     Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
5988                     getWhenToMakeWifiCallsDefaultPreference());
5989         } finally {
5990             Binder.restoreCallingIdentity(identity);
5991         }
5992     }
5993 
5994     /**
5995      * @see android.telephony.TelephonyManager.WifiCallingChoices
5996      */
setWhenToMakeWifiCalls(int preference)5997     public void setWhenToMakeWifiCalls(int preference) {
5998         final long identity = Binder.clearCallingIdentity();
5999         try {
6000             if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
6001             Settings.System.putInt(mApp.getContentResolver(),
6002                     Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
6003         } finally {
6004             Binder.restoreCallingIdentity(identity);
6005         }
6006     }
6007 
getWhenToMakeWifiCallsDefaultPreference()6008     private static int getWhenToMakeWifiCallsDefaultPreference() {
6009         // TODO: Use a build property to choose this value.
6010         return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
6011     }
6012 
getPhoneFromSlotPortIndexOrThrowException(int slotIndex, int portIndex)6013     private Phone getPhoneFromSlotPortIndexOrThrowException(int slotIndex, int portIndex) {
6014         int phoneId = UiccController.getInstance().getPhoneIdFromSlotPortIndex(slotIndex,
6015                 portIndex);
6016         if (phoneId == -1) {
6017             throw new IllegalArgumentException("Given slot index: " + slotIndex + " port index: "
6018                     + portIndex + " does not correspond to an active phone");
6019         }
6020         return PhoneFactory.getPhone(phoneId);
6021     }
6022 
6023     @Override
iccOpenLogicalChannel( @onNull IccLogicalChannelRequest request)6024     public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
6025             @NonNull IccLogicalChannelRequest request) {
6026 
6027         Phone phone = getPhoneFromValidIccLogicalChannelRequest(request,
6028                 /*message=*/ "iccOpenLogicalChannel");
6029 
6030         if (DBG) log("iccOpenLogicalChannel: request=" + request);
6031         // Verify that the callingPackage in the request belongs to the calling UID
6032         mAppOps.checkPackage(Binder.getCallingUid(), request.callingPackage);
6033 
6034         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6035                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccOpenLogicalChannel");
6036 
6037         return iccOpenLogicalChannelWithPermission(phone, request);
6038     }
6039 
getPhoneFromValidIccLogicalChannelRequest( @onNull IccLogicalChannelRequest request, String message)6040     private Phone getPhoneFromValidIccLogicalChannelRequest(
6041             @NonNull IccLogicalChannelRequest request, String message) {
6042         Phone phone;
6043         if (request.subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
6044             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6045                     mApp, request.subId, message);
6046             phone = getPhoneFromSubId(request.subId);
6047         } else if (request.slotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
6048             enforceModifyPermission();
6049             phone = getPhoneFromSlotPortIndexOrThrowException(request.slotIndex, request.portIndex);
6050         } else {
6051             throw new IllegalArgumentException("Both subId and slotIndex in request are invalid.");
6052         }
6053         return phone;
6054     }
6055 
iccOpenLogicalChannelWithPermission(Phone phone, IccLogicalChannelRequest channelRequest)6056     private IccOpenLogicalChannelResponse iccOpenLogicalChannelWithPermission(Phone phone,
6057             IccLogicalChannelRequest channelRequest) {
6058         final long identity = Binder.clearCallingIdentity();
6059         try {
6060             if (TextUtils.equals(ISDR_AID, channelRequest.aid)) {
6061                 // Only allows LPA to open logical channel to ISD-R.
6062                 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
6063                         .getContext().getPackageManager());
6064                 if (bestComponent == null || !TextUtils.equals(channelRequest.callingPackage,
6065                         bestComponent.packageName)) {
6066                     loge("The calling package is not allowed to access ISD-R.");
6067                     throw new SecurityException(
6068                             "The calling package is not allowed to access ISD-R.");
6069                 }
6070             }
6071 
6072             IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
6073                     CMD_OPEN_CHANNEL, channelRequest, phone, null /* workSource */);
6074             if (DBG) log("iccOpenLogicalChannelWithPermission: response=" + response);
6075             return response;
6076         } finally {
6077             Binder.restoreCallingIdentity(identity);
6078         }
6079     }
6080 
6081     @Override
iccCloseLogicalChannel(@onNull IccLogicalChannelRequest request)6082     public boolean iccCloseLogicalChannel(@NonNull IccLogicalChannelRequest request) {
6083         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6084                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccCloseLogicalChannel");
6085 
6086         Phone phone = getPhoneFromValidIccLogicalChannelRequest(request,
6087                 /*message=*/"iccCloseLogicalChannel");
6088 
6089         if (DBG) log("iccCloseLogicalChannel: request=" + request);
6090 
6091         return iccCloseLogicalChannelWithPermission(phone, request);
6092     }
6093 
iccCloseLogicalChannelWithPermission(Phone phone, IccLogicalChannelRequest request)6094     private boolean iccCloseLogicalChannelWithPermission(Phone phone,
6095             IccLogicalChannelRequest request) {
6096         // before this feature is enabled, this API should only return false if
6097         // the operation fails instead of throwing runtime exception for
6098         // backward-compatibility.
6099         final boolean shouldThrowExceptionOnFailure = CompatChanges.isChangeEnabled(
6100                 ICC_CLOSE_CHANNEL_EXCEPTION_ON_FAILURE, Binder.getCallingUid());
6101         final long identity = Binder.clearCallingIdentity();
6102         try {
6103             if (request.channel < 0) {
6104                 throw new IllegalArgumentException("request.channel is less than 0");
6105             }
6106             Object result = sendRequest(CMD_CLOSE_CHANNEL, request.channel, phone,
6107                     null /* workSource */);
6108             Boolean success = false;
6109             if (result instanceof RuntimeException) {
6110                 // if there is an exception returned, throw from the binder thread here.
6111                 if (shouldThrowExceptionOnFailure) {
6112                     throw (RuntimeException) result;
6113                 } else {
6114                     return false;
6115                 }
6116             } else if (result instanceof Boolean) {
6117                 success = (Boolean) result;
6118             } else {
6119                 loge("iccCloseLogicalChannelWithPermission: supported return type " + result);
6120             }
6121             if (DBG) log("iccCloseLogicalChannelWithPermission: success=" + success);
6122             return success;
6123         } finally {
6124             Binder.restoreCallingIdentity(identity);
6125         }
6126     }
6127 
6128     @Override
iccTransmitApduLogicalChannel(int subId, int channel, int cla, int command, int p1, int p2, int p3, String data)6129     public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
6130             int command, int p1, int p2, int p3, String data) {
6131         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6132                 mApp, subId, "iccTransmitApduLogicalChannel");
6133 
6134         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6135                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccTransmitApduLogicalChannel");
6136 
6137         if (DBG) {
6138             log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
6139                     + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
6140                     + p3 + " data=" + data);
6141         }
6142         return iccTransmitApduLogicalChannelWithPermission(getPhoneFromSubId(subId), channel, cla,
6143                 command, p1, p2, p3, data);
6144     }
6145 
6146     @Override
iccTransmitApduLogicalChannelByPort(int slotIndex, int portIndex, int channel, int cla, int command, int p1, int p2, int p3, String data)6147     public String iccTransmitApduLogicalChannelByPort(int slotIndex, int portIndex, int channel,
6148             int cla, int command, int p1, int p2, int p3, String data) {
6149         enforceModifyPermission();
6150 
6151         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6152                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
6153                 "iccTransmitApduLogicalChannelBySlot");
6154 
6155         if (DBG) {
6156             log("iccTransmitApduLogicalChannelByPort: slotIndex=" + slotIndex + " portIndex="
6157                     + portIndex + " chnl=" + channel + " cla=" + cla + " cmd=" + command + " p1="
6158                     + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
6159         }
6160         return iccTransmitApduLogicalChannelWithPermission(
6161                 getPhoneFromSlotPortIndexOrThrowException(slotIndex, portIndex), channel, cla,
6162                 command, p1, p2, p3, data);
6163     }
6164 
iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla, int command, int p1, int p2, int p3, String data)6165     private String iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla,
6166             int command, int p1, int p2, int p3, String data) {
6167         final long identity = Binder.clearCallingIdentity();
6168         try {
6169             if (channel <= 0 || channel >= 256) {
6170                 return "6881";  // STATUS_CHANNEL_NOT_SUPPORTED
6171             }
6172 
6173             IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
6174                     new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), phone,
6175                     null /* workSource */);
6176             if (DBG) log("iccTransmitApduLogicalChannelWithPermission: " + response);
6177 
6178             // Append the returned status code to the end of the response payload.
6179             String s = Integer.toHexString(
6180                     (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
6181             if (response.payload != null) {
6182                 s = IccUtils.bytesToHexString(response.payload) + s;
6183             }
6184             return s;
6185         } finally {
6186             Binder.restoreCallingIdentity(identity);
6187         }
6188     }
6189 
6190     @Override
iccTransmitApduBasicChannel(int subId, String callingPackage, int cla, int command, int p1, int p2, int p3, String data)6191     public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
6192             int command, int p1, int p2, int p3, String data) {
6193         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6194                 mApp, subId, "iccTransmitApduBasicChannel");
6195         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
6196 
6197         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6198                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccTransmitApduBasicChannel");
6199 
6200         if (DBG) {
6201             log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
6202                     + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
6203         }
6204         return iccTransmitApduBasicChannelWithPermission(getPhoneFromSubId(subId), callingPackage,
6205                 cla, command, p1, p2, p3, data);
6206     }
6207 
6208     @Override
iccTransmitApduBasicChannelByPort(int slotIndex, int portIndex, String callingPackage, int cla, int command, int p1, int p2, int p3, String data)6209     public String iccTransmitApduBasicChannelByPort(int slotIndex, int portIndex,
6210             String callingPackage, int cla, int command, int p1, int p2, int p3, String data) {
6211         enforceModifyPermission();
6212         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
6213 
6214         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6215                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccTransmitApduBasicChannelBySlot");
6216 
6217         if (DBG) {
6218             log("iccTransmitApduBasicChannelByPort: slotIndex=" + slotIndex + " portIndex="
6219                     + portIndex + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2="
6220                     + p2 + " p3=" + p3 + " data=" + data);
6221         }
6222 
6223         return iccTransmitApduBasicChannelWithPermission(
6224                 getPhoneFromSlotPortIndexOrThrowException(slotIndex, portIndex), callingPackage,
6225                 cla, command, p1, p2, p3, data);
6226     }
6227 
6228     // 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)6229     private String iccTransmitApduBasicChannelWithPermission(Phone phone, String callingPackage,
6230             int cla, int command, int p1, int p2, int p3, String data) {
6231         final long identity = Binder.clearCallingIdentity();
6232         try {
6233             if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
6234                     && TextUtils.equals(ISDR_AID, data)) {
6235                 // Only allows LPA to select ISD-R.
6236                 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
6237                         .getContext().getPackageManager());
6238                 if (bestComponent == null
6239                         || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
6240                     loge("The calling package is not allowed to select ISD-R.");
6241                     throw new SecurityException(
6242                             "The calling package is not allowed to select ISD-R.");
6243                 }
6244             }
6245 
6246             IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
6247                     new IccAPDUArgument(0, cla, command, p1, p2, p3, data), phone,
6248                     null /* workSource */);
6249             if (DBG) log("iccTransmitApduBasicChannelWithPermission: " + response);
6250 
6251             // Append the returned status code to the end of the response payload.
6252             String s = Integer.toHexString(
6253                     (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
6254             if (response.payload != null) {
6255                 s = IccUtils.bytesToHexString(response.payload) + s;
6256             }
6257             return s;
6258         } finally {
6259             Binder.restoreCallingIdentity(identity);
6260         }
6261     }
6262 
6263     @Override
iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3, String filePath)6264     public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
6265             String filePath) {
6266         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6267                 mApp, subId, "iccExchangeSimIO");
6268 
6269         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6270                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "iccExchangeSimIO");
6271 
6272         final long identity = Binder.clearCallingIdentity();
6273         try {
6274             if (DBG) {
6275                 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
6276                         + p1 + " " + p2 + " " + p3 + ":" + filePath);
6277             }
6278 
6279             IccIoResult response =
6280                     (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
6281                             new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
6282                             subId);
6283 
6284             if (DBG) {
6285                 log("Exchange SIM_IO [R]" + response);
6286             }
6287 
6288             byte[] result = null;
6289             int length = 2;
6290             if (response.payload != null) {
6291                 length = 2 + response.payload.length;
6292                 result = new byte[length];
6293                 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
6294             } else {
6295                 result = new byte[length];
6296             }
6297 
6298             result[length - 1] = (byte) response.sw2;
6299             result[length - 2] = (byte) response.sw1;
6300             return result;
6301         } finally {
6302             Binder.restoreCallingIdentity(identity);
6303         }
6304     }
6305 
6306     /**
6307      * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
6308      * on a particular subscription
6309      */
getForbiddenPlmns(int subId, int appType, String callingPackage, String callingFeatureId)6310     public String[] getForbiddenPlmns(int subId, int appType, String callingPackage,
6311             String callingFeatureId) {
6312         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6313                 mApp, subId, callingPackage, callingFeatureId, "getForbiddenPlmns")) {
6314             return null;
6315         }
6316 
6317         enforceTelephonyFeatureWithException(callingPackage,
6318                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getForbiddenPlmns");
6319 
6320         final long identity = Binder.clearCallingIdentity();
6321         try {
6322             if (appType != TelephonyManager.APPTYPE_USIM
6323                     && appType != TelephonyManager.APPTYPE_SIM) {
6324                 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
6325                 return null;
6326             }
6327             Object response = sendRequest(
6328                     CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
6329             if (response instanceof String[]) {
6330                 return (String[]) response;
6331             }
6332             // Response is an Exception of some kind
6333             // which is signalled to the user as a NULL retval
6334             return null;
6335         } finally {
6336             Binder.restoreCallingIdentity(identity);
6337         }
6338     }
6339 
6340     /**
6341      * Set the forbidden PLMN list from the given app type (ex APPTYPE_USIM) on a particular
6342      * subscription.
6343      *
6344      * @param subId the id of the subscription.
6345      * @param appType the uicc app type, must be USIM or SIM.
6346      * @param fplmns the Forbiden plmns list that needed to be written to the SIM.
6347      * @param callingPackage the op Package name.
6348      * @param callingFeatureId the feature in the package.
6349      * @return number of fplmns that is successfully written to the SIM.
6350      */
setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage, String callingFeatureId)6351     public int setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage,
6352             String callingFeatureId) {
6353         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6354                 mApp, subId, "setForbiddenPlmns");
6355 
6356         enforceTelephonyFeatureWithException(callingPackage,
6357                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "setForbiddenPlmns");
6358 
6359         if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
6360             loge("setForbiddenPlmnList(): App Type must be USIM or SIM");
6361             throw new IllegalArgumentException("Invalid appType: App Type must be USIM or SIM");
6362         }
6363         if (fplmns == null) {
6364             throw new IllegalArgumentException("Fplmn List provided is null");
6365         }
6366         for (String fplmn : fplmns) {
6367             if (!CellIdentity.isValidPlmn(fplmn)) {
6368                 throw new IllegalArgumentException("Invalid fplmn provided: " + fplmn);
6369             }
6370         }
6371         final long identity = Binder.clearCallingIdentity();
6372         try {
6373             Object response = sendRequest(
6374                     CMD_SET_FORBIDDEN_PLMNS,
6375                     new Pair<Integer, List<String>>(new Integer(appType), fplmns),
6376                     subId);
6377             return (int) response;
6378         } finally {
6379             Binder.restoreCallingIdentity(identity);
6380         }
6381     }
6382 
6383     @Override
sendEnvelopeWithStatus(int subId, String content)6384     public String sendEnvelopeWithStatus(int subId, String content) {
6385         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6386                 mApp, subId, "sendEnvelopeWithStatus");
6387 
6388         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6389                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "sendEnvelopeWithStatus");
6390 
6391         final long identity = Binder.clearCallingIdentity();
6392         try {
6393             IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
6394             if (response.payload == null) {
6395                 return "";
6396             }
6397 
6398             // Append the returned status code to the end of the response payload.
6399             String s = Integer.toHexString(
6400                     (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
6401             s = IccUtils.bytesToHexString(response.payload) + s;
6402             return s;
6403         } finally {
6404             Binder.restoreCallingIdentity(identity);
6405         }
6406     }
6407 
6408     /**
6409      * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
6410      * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
6411      *
6412      * @param itemID the ID of the item to read
6413      * @return the NV item as a String, or null on error.
6414      */
6415     @Override
nvReadItem(int itemID)6416     public String nvReadItem(int itemID) {
6417         if (mFeatureFlags.cleanupCdma()) return null;
6418 
6419         WorkSource workSource = getWorkSource(Binder.getCallingUid());
6420         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6421                 mApp, getDefaultSubscription(), "nvReadItem");
6422 
6423         final long identity = Binder.clearCallingIdentity();
6424         try {
6425             if (DBG) log("nvReadItem: item " + itemID);
6426             String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
6427             if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
6428             return value;
6429         } finally {
6430             Binder.restoreCallingIdentity(identity);
6431         }
6432     }
6433 
6434     /**
6435      * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
6436      * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
6437      *
6438      * @param itemID the ID of the item to read
6439      * @param itemValue the value to write, as a String
6440      * @return true on success; false on any failure
6441      */
6442     @Override
nvWriteItem(int itemID, String itemValue)6443     public boolean nvWriteItem(int itemID, String itemValue) {
6444         if (mFeatureFlags.cleanupCdma()) return false;
6445 
6446         WorkSource workSource = getWorkSource(Binder.getCallingUid());
6447         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6448                 mApp, getDefaultSubscription(), "nvWriteItem");
6449 
6450         final long identity = Binder.clearCallingIdentity();
6451         try {
6452             if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
6453             Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
6454                     new Pair<Integer, String>(itemID, itemValue), workSource);
6455             if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
6456             return success;
6457         } finally {
6458             Binder.restoreCallingIdentity(identity);
6459         }
6460     }
6461 
6462     /**
6463      * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
6464      * Used for device configuration by some CDMA operators.
6465      *
6466      * @param preferredRoamingList byte array containing the new PRL
6467      * @return true on success; false on any failure
6468      */
6469     @Override
nvWriteCdmaPrl(byte[] preferredRoamingList)6470     public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
6471         if (mFeatureFlags.cleanupCdma()) return false;
6472 
6473         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6474                 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
6475 
6476         final long identity = Binder.clearCallingIdentity();
6477         try {
6478             if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
6479             Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
6480             if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
6481             return success;
6482         } finally {
6483             Binder.restoreCallingIdentity(identity);
6484         }
6485     }
6486 
6487     /**
6488      * Rollback modem configurations to factory default except some config which are in whitelist.
6489      * Used for device configuration by some CDMA operators.
6490      *
6491      * @param slotIndex - device slot.
6492      *
6493      * @return true on success; false on any failure
6494      */
6495     @Override
resetModemConfig(int slotIndex)6496     public boolean resetModemConfig(int slotIndex) {
6497         if (mFeatureFlags.cleanupCdma()) return false;
6498         Phone phone = PhoneFactory.getPhone(slotIndex);
6499         if (phone != null) {
6500             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6501                     mApp, phone.getSubId(), "resetModemConfig");
6502 
6503             enforceTelephonyFeatureWithException(getCurrentPackageName(),
6504                     PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "resetModemConfig");
6505 
6506             final long identity = Binder.clearCallingIdentity();
6507             try {
6508                 int cmd = mFeatureFlags.cleanupCdma() ? CMD_MODEM_REBOOT : CMD_RESET_MODEM_CONFIG;
6509                 Boolean success = (Boolean) sendRequest(cmd, null);
6510                 if (DBG) log("resetModemConfig:" + ' ' + (success ? "ok" : "fail"));
6511                 return success;
6512             } finally {
6513                 Binder.restoreCallingIdentity(identity);
6514             }
6515         }
6516         return false;
6517     }
6518 
6519     /**
6520      * Generate a radio modem reset. Used for device configuration by some CDMA operators.
6521      *
6522      * @param slotIndex - device slot.
6523      *
6524      * @return true on success; false on any failure
6525      */
6526     @Override
rebootModem(int slotIndex)6527     public boolean rebootModem(int slotIndex) {
6528         Phone phone = PhoneFactory.getPhone(slotIndex);
6529         if (phone != null) {
6530             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6531                     mApp, phone.getSubId(), "rebootModem");
6532 
6533             enforceTelephonyFeatureWithException(getCurrentPackageName(),
6534                     PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "rebootModem");
6535 
6536             final long identity = Binder.clearCallingIdentity();
6537             try {
6538                 Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
6539                 if (DBG) log("rebootModem:" + ' ' + (success ? "ok" : "fail"));
6540                 return success;
6541             } finally {
6542                 Binder.restoreCallingIdentity(identity);
6543             }
6544         }
6545         return false;
6546     }
6547 
6548     /**
6549      * Toggle IMS disable and enable for the framework to reset it. See {@link #enableIms(int)} and
6550      * {@link #disableIms(int)}.
6551      * @param slotIndex device slot.
6552      */
resetIms(int slotIndex)6553     public void resetIms(int slotIndex) {
6554         enforceModifyPermission();
6555 
6556         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6557                 PackageManager.FEATURE_TELEPHONY_IMS, "resetIms");
6558 
6559         final long identity = Binder.clearCallingIdentity();
6560         try {
6561             if (mImsResolver == null) {
6562                 // may happen if the does not support IMS.
6563                 return;
6564             }
6565             mImsResolver.resetIms(slotIndex);
6566         } finally {
6567             Binder.restoreCallingIdentity(identity);
6568         }
6569     }
6570 
6571     /**
6572      * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
6573      * status updates, if not already enabled.
6574      */
enableIms(int slotId)6575     public void enableIms(int slotId) {
6576         enforceModifyPermission();
6577 
6578         final long identity = Binder.clearCallingIdentity();
6579         try {
6580             if (mImsResolver == null) {
6581                 // may happen if the device does not support IMS.
6582                 return;
6583             }
6584             mImsResolver.enableIms(slotId);
6585         } finally {
6586             Binder.restoreCallingIdentity(identity);
6587         }
6588     }
6589 
6590     /**
6591      * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
6592      * status updates to disabled.
6593      */
disableIms(int slotId)6594     public void disableIms(int slotId) {
6595         enforceModifyPermission();
6596 
6597         final long identity = Binder.clearCallingIdentity();
6598         try {
6599             if (mImsResolver == null) {
6600                 // may happen if the device does not support IMS.
6601                 return;
6602             }
6603             mImsResolver.disableIms(slotId);
6604         } finally {
6605             Binder.restoreCallingIdentity(identity);
6606         }
6607     }
6608 
6609     /**
6610      * Registers for updates to the MmTelFeature connection through the IImsServiceFeatureCallback
6611      * callback.
6612      */
6613     @Override
registerMmTelFeatureCallback(int slotId, IImsServiceFeatureCallback callback)6614     public void registerMmTelFeatureCallback(int slotId, IImsServiceFeatureCallback callback) {
6615         enforceModifyPermission();
6616 
6617         final long identity = Binder.clearCallingIdentity();
6618         try {
6619             if (mImsResolver == null) {
6620                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
6621                         "Device does not support IMS");
6622             }
6623             mImsResolver.listenForFeature(slotId, ImsFeature.FEATURE_MMTEL, callback);
6624         } finally {
6625             Binder.restoreCallingIdentity(identity);
6626         }
6627     }
6628     /**
6629      * Unregister a previously registered IImsServiceFeatureCallback associated with an ImsFeature.
6630      */
6631     @Override
unregisterImsFeatureCallback(IImsServiceFeatureCallback callback)6632     public void unregisterImsFeatureCallback(IImsServiceFeatureCallback callback) {
6633         enforceModifyPermission();
6634 
6635         final long identity = Binder.clearCallingIdentity();
6636         try {
6637             if (mImsResolver == null) return;
6638             mImsResolver.unregisterImsFeatureCallback(callback);
6639         } finally {
6640             Binder.restoreCallingIdentity(identity);
6641         }
6642     }
6643 
6644     /**
6645      * Returns the {@link IImsRegistration} structure associated with the slotId and feature
6646      * specified or null if IMS is not supported on the slot specified.
6647      */
getImsRegistration(int slotId, int feature)6648     public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
6649         enforceModifyPermission();
6650 
6651         final long identity = Binder.clearCallingIdentity();
6652         try {
6653             if (mImsResolver == null) {
6654                 // may happen if the device does not support IMS.
6655                 return null;
6656             }
6657             return mImsResolver.getImsRegistration(slotId, feature);
6658         } finally {
6659             Binder.restoreCallingIdentity(identity);
6660         }
6661     }
6662 
6663     /**
6664      * Returns the {@link IImsConfig} structure associated with the slotId and feature
6665      * specified or null if IMS is not supported on the slot specified.
6666      */
getImsConfig(int slotId, int feature)6667     public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
6668         enforceModifyPermission();
6669 
6670         final long identity = Binder.clearCallingIdentity();
6671         try {
6672             if (mImsResolver == null) {
6673                 // may happen if the device does not support IMS.
6674                 return null;
6675             }
6676             return mImsResolver.getImsConfig(slotId, feature);
6677         } finally {
6678             Binder.restoreCallingIdentity(identity);
6679         }
6680     }
6681 
6682     /**
6683      * Sets the ImsService Package Name that Telephony will bind to.
6684      *
6685      * @param slotIndex the slot ID that the ImsService should bind for.
6686      * @param userId the user ID that the ImsService should bind for or {@link UserHandle#USER_NULL}
6687      *               if there is no preference.
6688      * @param isCarrierService true if the ImsService is the carrier override, false if the
6689      *         ImsService is the device default ImsService.
6690      * @param featureTypes An integer array of feature types associated with a packageName.
6691      * @param packageName The name of the package that the current configuration will be replaced
6692      *                    with.
6693      * @return true if setting the ImsService to bind to succeeded, false if it did not.
6694      */
setBoundImsServiceOverride(int slotIndex, int userId, boolean isCarrierService, int[] featureTypes, String packageName)6695     public boolean setBoundImsServiceOverride(int slotIndex, int userId, boolean isCarrierService,
6696             int[] featureTypes, String packageName) {
6697         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setBoundImsServiceOverride");
6698         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
6699                 SubscriptionManager.getSubscriptionId(slotIndex), "setBoundImsServiceOverride");
6700 
6701         final long identity = Binder.clearCallingIdentity();
6702         try {
6703             if (mImsResolver == null) {
6704                 // may happen if the device does not support IMS.
6705                 return false;
6706             }
6707             return mImsResolver.overrideImsServiceConfiguration(packageName, slotIndex, userId,
6708                     isCarrierService, featureTypes);
6709         } finally {
6710             Binder.restoreCallingIdentity(identity);
6711         }
6712     }
6713 
6714     /**
6715      * Clears any carrier ImsService overrides for the slot index specified that were previously
6716      * set with {@link #setBoundImsServiceOverride(int, boolean, int[], String)}.
6717      *
6718      * This should only be used for testing.
6719      *
6720      * @param slotIndex the slot ID that the ImsService should bind for.
6721      * @return true if clearing the carrier ImsService override succeeded or false if it did not.
6722      */
6723     @Override
clearCarrierImsServiceOverride(int slotIndex)6724     public boolean clearCarrierImsServiceOverride(int slotIndex) {
6725         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
6726                 "clearCarrierImsServiceOverride");
6727         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
6728                 SubscriptionManager.getSubscriptionId(slotIndex), "clearCarrierImsServiceOverride");
6729 
6730         final long identity = Binder.clearCallingIdentity();
6731         try {
6732             if (mImsResolver == null) {
6733                 // may happen if the device does not support IMS.
6734                 return false;
6735             }
6736             return mImsResolver.clearCarrierImsServiceConfiguration(slotIndex);
6737         } finally {
6738             Binder.restoreCallingIdentity(identity);
6739         }
6740     }
6741 
6742     /**
6743      * Return the package name of the currently bound ImsService.
6744      *
6745      * @param slotId The slot that the ImsService is associated with.
6746      * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
6747      *         the device default.
6748      * @param featureType The feature associated with the queried configuration.
6749      * @return the package name of the ImsService configuration.
6750      */
getBoundImsServicePackage(int slotId, boolean isCarrierImsService, @ImsFeature.FeatureType int featureType)6751     public String getBoundImsServicePackage(int slotId, boolean isCarrierImsService,
6752             @ImsFeature.FeatureType int featureType) {
6753         TelephonyPermissions
6754                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(mApp,
6755                         SubscriptionManager.getSubscriptionId(slotId), "getBoundImsServicePackage");
6756 
6757         final long identity = Binder.clearCallingIdentity();
6758         try {
6759             if (mImsResolver == null) {
6760                 // may happen if the device does not support IMS.
6761                 return "";
6762             }
6763             // TODO: change API to query RCS separately.
6764             return mImsResolver.getImsServiceConfiguration(slotId, isCarrierImsService,
6765                     featureType);
6766         } finally {
6767             Binder.restoreCallingIdentity(identity);
6768         }
6769     }
6770 
6771     /**
6772      * Get the MmTelFeature state associated with the requested subscription id.
6773      * @param subId The subscription that the MmTelFeature is associated with.
6774      * @param callback A callback with an integer containing the
6775      * {@link android.telephony.ims.feature.ImsFeature.ImsState} associated with the MmTelFeature.
6776      */
6777     @Override
getImsMmTelFeatureState(int subId, IIntegerConsumer callback)6778     public void getImsMmTelFeatureState(int subId, IIntegerConsumer callback) {
6779         enforceReadPrivilegedPermission("getImsMmTelFeatureState");
6780         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
6781             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
6782                     "IMS not available on device.");
6783         }
6784         final long token = Binder.clearCallingIdentity();
6785         try {
6786             int slotId = getSlotIndex(subId);
6787             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
6788                 Log.w(LOG_TAG, "getImsMmTelFeatureState: called with an inactive subscription '"
6789                         + subId + "'");
6790                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
6791             }
6792             verifyImsMmTelConfiguredOrThrow(slotId);
6793             ImsManager.getInstance(mApp, slotId).getImsServiceState(anInteger -> {
6794                 try {
6795                     callback.accept(anInteger == null ? ImsFeature.STATE_UNAVAILABLE : anInteger);
6796                 } catch (RemoteException e) {
6797                     Log.w(LOG_TAG, "getImsMmTelFeatureState: remote caller is no longer running. "
6798                             + "Ignore");
6799                 }
6800             });
6801         } catch (ImsException e) {
6802             throw new ServiceSpecificException(e.getCode());
6803         } finally {
6804             Binder.restoreCallingIdentity(token);
6805         }
6806     }
6807 
6808     /**
6809      * Sets the ims registration state on all valid {@link Phone}s.
6810      */
setImsRegistrationState(final boolean registered)6811     public void setImsRegistrationState(final boolean registered) {
6812         enforceModifyPermission();
6813 
6814         final long identity = Binder.clearCallingIdentity();
6815         try {
6816             // NOTE: Before S, this method only set the default phone.
6817             for (final Phone phone : PhoneFactory.getPhones()) {
6818                 if (SubscriptionManager.isValidSubscriptionId(phone.getSubId())) {
6819                     phone.setImsRegistrationState(registered);
6820                 }
6821             }
6822         } finally {
6823             Binder.restoreCallingIdentity(identity);
6824         }
6825     }
6826 
6827     /**
6828      * Set the network selection mode to automatic.
6829      *
6830      */
6831     @Override
setNetworkSelectionModeAutomatic(int subId)6832     public void setNetworkSelectionModeAutomatic(int subId) {
6833         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6834                 mApp, subId, "setNetworkSelectionModeAutomatic");
6835 
6836         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6837                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "setNetworkSelectionModeAutomatic");
6838 
6839         final long identity = Binder.clearCallingIdentity();
6840         try {
6841             if (!isActiveSubscription(subId)) {
6842                 return;
6843             }
6844             if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
6845             sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId,
6846                     BLOCKING_REQUEST_DEFAULT_TIMEOUT_MS);
6847         } finally {
6848             Binder.restoreCallingIdentity(identity);
6849         }
6850     }
6851 
6852     /**
6853      * Ask the radio to connect to the input network and change selection mode to manual.
6854      *
6855      * @param subId the id of the subscription.
6856      * @param operatorInfo the operator information, included the PLMN, long name and short name of
6857      * the operator to attach to.
6858      * @param persistSelection whether the selection will persist until reboot. If true, only allows
6859      * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
6860      * normal network selection next time.
6861      * @return {@code true} on success; {@code true} on any failure.
6862      */
6863     @Override
setNetworkSelectionModeManual( int subId, OperatorInfo operatorInfo, boolean persistSelection)6864     public boolean setNetworkSelectionModeManual(
6865             int subId, OperatorInfo operatorInfo, boolean persistSelection) {
6866         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6867                 mApp, subId, "setNetworkSelectionModeManual");
6868 
6869         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6870                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "setNetworkSelectionModeManual");
6871 
6872         final long identity = Binder.clearCallingIdentity();
6873         if (!isActiveSubscription(subId)) {
6874             return false;
6875         }
6876 
6877         try {
6878             ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
6879                     persistSelection);
6880             if (DBG) {
6881                 log("setNetworkSelectionModeManual: subId: " + subId
6882                         + " operator: " + operatorInfo);
6883             }
6884             return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
6885         } finally {
6886             Binder.restoreCallingIdentity(identity);
6887         }
6888     }
6889     /**
6890      * Get the manual network selection
6891      *
6892      * @param subId the id of the subscription.
6893      *
6894      * @return the previously saved user selected PLMN
6895      */
6896     @Override
getManualNetworkSelectionPlmn(int subId)6897     public String getManualNetworkSelectionPlmn(int subId) {
6898         TelephonyPermissions
6899                 .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
6900                         mApp, subId, "getManualNetworkSelectionPlmn");
6901 
6902         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6903                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getManualNetworkSelectionPlmn");
6904 
6905         final long identity = Binder.clearCallingIdentity();
6906         try {
6907             if (!isActiveSubscription(subId)) {
6908                 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
6909             }
6910 
6911             final Phone phone = getPhone(subId);
6912             if (phone == null) {
6913                 throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
6914             }
6915             OperatorInfo networkSelection = phone.getSavedNetworkSelection();
6916             return TextUtils.isEmpty(networkSelection.getOperatorNumeric())
6917                     ? phone.getManualNetworkSelectionPlmn() : networkSelection.getOperatorNumeric();
6918         } finally {
6919             Binder.restoreCallingIdentity(identity);
6920         }
6921     }
6922 
6923     /**
6924      * Scans for available networks.
6925      */
6926     @Override
getCellNetworkScanResults(int subId, String callingPackage, String callingFeatureId)6927     public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage,
6928             String callingFeatureId) {
6929         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6930                 mApp, subId, "getCellNetworkScanResults");
6931         LocationAccessPolicy.LocationPermissionResult locationResult =
6932                 LocationAccessPolicy.checkLocationPermission(mApp,
6933                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
6934                                 .setCallingPackage(callingPackage)
6935                                 .setCallingFeatureId(callingFeatureId)
6936                                 .setCallingPid(Binder.getCallingPid())
6937                                 .setCallingUid(Binder.getCallingUid())
6938                                 .setMethod("getCellNetworkScanResults")
6939                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
6940                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
6941                                 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
6942                                 .build());
6943         switch (locationResult) {
6944             case DENIED_HARD:
6945                 throw new SecurityException("Not allowed to access scan results -- location");
6946             case DENIED_SOFT:
6947                 return null;
6948         }
6949 
6950         long identity = Binder.clearCallingIdentity();
6951         try {
6952             if (DBG) log("getCellNetworkScanResults: subId " + subId);
6953             return (CellNetworkScanResult) sendRequest(
6954                     CMD_PERFORM_NETWORK_SCAN, null, subId);
6955         } finally {
6956             Binder.restoreCallingIdentity(identity);
6957         }
6958     }
6959 
6960     /**
6961      * Get the call forwarding info, given the call forwarding reason.
6962      */
6963     @Override
getCallForwarding(int subId, int callForwardingReason, ICallForwardingInfoCallback callback)6964     public void getCallForwarding(int subId, int callForwardingReason,
6965             ICallForwardingInfoCallback callback) {
6966         enforceReadPrivilegedPermission("getCallForwarding");
6967 
6968         enforceTelephonyFeatureWithException(getCurrentPackageName(),
6969                 PackageManager.FEATURE_TELEPHONY_CALLING, "getCallForwarding");
6970 
6971         long identity = Binder.clearCallingIdentity();
6972         try {
6973             if (DBG) {
6974                 log("getCallForwarding: subId " + subId
6975                         + " callForwardingReason" + callForwardingReason);
6976             }
6977 
6978             Phone phone = getPhone(subId);
6979             if (phone == null) {
6980                 try {
6981                     callback.onError(
6982                             TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
6983                 } catch (RemoteException e) {
6984                     // ignore
6985                 }
6986                 return;
6987             }
6988 
6989             Pair<Integer, TelephonyManager.CallForwardingInfoCallback> argument = Pair.create(
6990                     callForwardingReason, new TelephonyManager.CallForwardingInfoCallback() {
6991                         @Override
6992                         public void onCallForwardingInfoAvailable(CallForwardingInfo info) {
6993                             try {
6994                                 callback.onCallForwardingInfoAvailable(info);
6995                             } catch (RemoteException e) {
6996                                 // ignore
6997                             }
6998                         }
6999 
7000                         @Override
7001                         public void onError(int error) {
7002                             try {
7003                                 callback.onError(error);
7004                             } catch (RemoteException e) {
7005                                 // ignore
7006                             }
7007                         }
7008                     });
7009             sendRequestAsync(CMD_GET_CALL_FORWARDING, argument, phone, null);
7010         } finally {
7011             Binder.restoreCallingIdentity(identity);
7012         }
7013     }
7014 
7015     /**
7016      * Sets the voice call forwarding info including status (enable/disable), call forwarding
7017      * reason, the number to forward, and the timeout before the forwarding is attempted.
7018      */
7019     @Override
setCallForwarding(int subId, CallForwardingInfo callForwardingInfo, IIntegerConsumer callback)7020     public void setCallForwarding(int subId, CallForwardingInfo callForwardingInfo,
7021             IIntegerConsumer callback) {
7022         enforceModifyPermission();
7023 
7024         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7025                 PackageManager.FEATURE_TELEPHONY_CALLING, "setCallForwarding");
7026 
7027         long identity = Binder.clearCallingIdentity();
7028         try {
7029             if (DBG) {
7030                 log("setCallForwarding: subId " + subId
7031                         + " callForwardingInfo" + callForwardingInfo);
7032             }
7033 
7034             Phone phone = getPhone(subId);
7035             if (phone == null) {
7036                 try {
7037                     callback.accept(
7038                             TelephonyManager.CallForwardingInfoCallback.RESULT_ERROR_UNKNOWN);
7039                 } catch (RemoteException e) {
7040                     // ignore
7041                 }
7042                 return;
7043             }
7044 
7045             Pair<CallForwardingInfo, Consumer<Integer>> arguments = Pair.create(callForwardingInfo,
7046                     FunctionalUtils.ignoreRemoteException(callback::accept));
7047 
7048             sendRequestAsync(CMD_SET_CALL_FORWARDING, arguments, phone, null);
7049         } finally {
7050             Binder.restoreCallingIdentity(identity);
7051         }
7052     }
7053 
7054     /**
7055      * Get the call waiting status for a subId.
7056      */
7057     @Override
getCallWaitingStatus(int subId, IIntegerConsumer callback)7058     public void getCallWaitingStatus(int subId, IIntegerConsumer callback) {
7059         enforceReadPrivilegedPermission("getCallWaitingStatus");
7060 
7061         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7062                 PackageManager.FEATURE_TELEPHONY_CALLING, "getCallWaitingStatus");
7063 
7064         long identity = Binder.clearCallingIdentity();
7065         try {
7066             Phone phone = getPhone(subId);
7067             if (phone == null) {
7068                 try {
7069                     callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
7070                 } catch (RemoteException e) {
7071                     // ignore
7072                 }
7073                 return;
7074             }
7075             CarrierConfigManager configManager = new CarrierConfigManager(phone.getContext());
7076             PersistableBundle c = configManager.getConfigForSubId(subId);
7077             boolean requireUssd = c.getBoolean(
7078                     CarrierConfigManager.KEY_USE_CALL_WAITING_USSD_BOOL, false);
7079 
7080             if (DBG) log("getCallWaitingStatus: subId " + subId);
7081             if (requireUssd) {
7082                 CarrierXmlParser carrierXmlParser = new CarrierXmlParser(phone.getContext(),
7083                         getSubscriptionCarrierId(subId));
7084                 String newUssdCommand = "";
7085                 try {
7086                     newUssdCommand = carrierXmlParser.getFeature(
7087                                     CarrierXmlParser.FEATURE_CALL_WAITING)
7088                             .makeCommand(CarrierXmlParser.SsEntry.SSAction.QUERY, null);
7089                 } catch (NullPointerException e) {
7090                     loge("Failed to generate USSD number" + e);
7091                 }
7092                 ResultReceiver wrappedCallback = new CallWaitingUssdResultReceiver(
7093                         mMainThreadHandler, callback, carrierXmlParser,
7094                         CarrierXmlParser.SsEntry.SSAction.QUERY);
7095                 final String ussdCommand = newUssdCommand;
7096                 Executors.newSingleThreadExecutor().execute(() -> {
7097                     handleUssdRequest(subId, ussdCommand, wrappedCallback);
7098                 });
7099             } else {
7100                 Consumer<Integer> argument = FunctionalUtils.ignoreRemoteException(
7101                         callback::accept);
7102                 sendRequestAsync(CMD_GET_CALL_WAITING, argument, phone, null);
7103             }
7104         } finally {
7105             Binder.restoreCallingIdentity(identity);
7106         }
7107     }
7108 
7109     /**
7110      * Sets whether call waiting is enabled for a given subId.
7111      */
7112     @Override
setCallWaitingStatus(int subId, boolean enable, IIntegerConsumer callback)7113     public void setCallWaitingStatus(int subId, boolean enable, IIntegerConsumer callback) {
7114         enforceModifyPermission();
7115 
7116         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7117                 PackageManager.FEATURE_TELEPHONY_CALLING, "setCallWaitingStatus");
7118 
7119         long identity = Binder.clearCallingIdentity();
7120         try {
7121             if (DBG) log("setCallWaitingStatus: subId " + subId + " enable: " + enable);
7122 
7123             Phone phone = getPhone(subId);
7124             if (phone == null) {
7125                 try {
7126                     callback.accept(TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR);
7127                 } catch (RemoteException e) {
7128                     // ignore
7129                 }
7130                 return;
7131             }
7132 
7133             CarrierConfigManager configManager = new CarrierConfigManager(phone.getContext());
7134             PersistableBundle c = configManager.getConfigForSubId(subId);
7135             boolean requireUssd = c.getBoolean(
7136                     CarrierConfigManager.KEY_USE_CALL_WAITING_USSD_BOOL, false);
7137 
7138             if (DBG) log("getCallWaitingStatus: subId " + subId);
7139             if (requireUssd) {
7140                 CarrierXmlParser carrierXmlParser = new CarrierXmlParser(phone.getContext(),
7141                         getSubscriptionCarrierId(subId));
7142                 CarrierXmlParser.SsEntry.SSAction ssAction =
7143                         enable ? CarrierXmlParser.SsEntry.SSAction.UPDATE_ACTIVATE
7144                                 : CarrierXmlParser.SsEntry.SSAction.UPDATE_DEACTIVATE;
7145                 String newUssdCommand = "";
7146                 try {
7147                     newUssdCommand = carrierXmlParser.getFeature(
7148                                     CarrierXmlParser.FEATURE_CALL_WAITING)
7149                             .makeCommand(ssAction, null);
7150                 } catch (NullPointerException e) {
7151                     loge("Failed to generate USSD number" + e);
7152                 }
7153                 ResultReceiver wrappedCallback = new CallWaitingUssdResultReceiver(
7154                         mMainThreadHandler, callback, carrierXmlParser, ssAction);
7155                 final String ussdCommand = newUssdCommand;
7156                 Executors.newSingleThreadExecutor().execute(() -> {
7157                     handleUssdRequest(subId, ussdCommand, wrappedCallback);
7158                 });
7159             } else {
7160                 Pair<Boolean, Consumer<Integer>> arguments = Pair.create(enable,
7161                         FunctionalUtils.ignoreRemoteException(callback::accept));
7162 
7163                 sendRequestAsync(CMD_SET_CALL_WAITING, arguments, phone, null);
7164             }
7165         } finally {
7166             Binder.restoreCallingIdentity(identity);
7167         }
7168     }
7169 
7170     /**
7171      * Starts a new network scan and returns the id of this scan.
7172      *
7173      * @param subId id of the subscription
7174      * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
7175      * location related information which will be sent if the caller already possess
7176      * {@android.Manifest.permission.ACCESS_FINE_LOCATION} and do not renounce the permission
7177      * @param request contains the radio access networks with bands/channels to scan
7178      * @param messenger callback messenger for scan results or errors
7179      * @param binder for the purpose of auto clean when the user thread crashes
7180      * @return the id of the requested scan which can be used to stop the scan.
7181      */
7182     @Override
requestNetworkScan(int subId, boolean renounceFineLocationAccess, NetworkScanRequest request, Messenger messenger, IBinder binder, String callingPackage, String callingFeatureId)7183     public int requestNetworkScan(int subId, boolean renounceFineLocationAccess,
7184             NetworkScanRequest request, Messenger messenger,
7185             IBinder binder, String callingPackage, String callingFeatureId) {
7186         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7187                 mApp, subId, "requestNetworkScan");
7188         LocationAccessPolicy.LocationPermissionResult locationResult =
7189                 LocationAccessPolicy.LocationPermissionResult.DENIED_HARD;
7190         if (!renounceFineLocationAccess) {
7191             locationResult = LocationAccessPolicy.checkLocationPermission(mApp,
7192                     new LocationAccessPolicy.LocationPermissionQuery.Builder()
7193                             .setCallingPackage(callingPackage)
7194                             .setCallingFeatureId(callingFeatureId)
7195                             .setCallingPid(Binder.getCallingPid())
7196                             .setCallingUid(Binder.getCallingUid())
7197                             .setMethod("requestNetworkScan")
7198                             .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
7199                             .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
7200                             .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
7201                             .build());
7202         }
7203         if (locationResult != LocationAccessPolicy.LocationPermissionResult.ALLOWED) {
7204             SecurityException e = checkNetworkRequestForSanitizedLocationAccess(
7205                     request, subId, callingPackage);
7206             if (e != null) {
7207                 if (locationResult == LocationAccessPolicy.LocationPermissionResult.DENIED_HARD) {
7208                     throw e;
7209                 } else {
7210                     loge(e.getMessage());
7211                     return TelephonyScanManager.INVALID_SCAN_ID;
7212                 }
7213             }
7214         }
7215 
7216         enforceTelephonyFeatureWithException(callingPackage,
7217                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "requestNetworkScan");
7218 
7219         int callingUid = Binder.getCallingUid();
7220         int callingPid = Binder.getCallingPid();
7221         final long identity = Binder.clearCallingIdentity();
7222         try {
7223             return mNetworkScanRequestTracker.startNetworkScan(
7224                     renounceFineLocationAccess, request, messenger, binder,
7225                     getPhoneFromSubIdOrDefault(subId),
7226                     callingUid, callingPid, callingPackage);
7227         } finally {
7228             Binder.restoreCallingIdentity(identity);
7229         }
7230     }
7231 
checkNetworkRequestForSanitizedLocationAccess( NetworkScanRequest request, int subId, String callingPackage)7232     private SecurityException checkNetworkRequestForSanitizedLocationAccess(
7233             NetworkScanRequest request, int subId, String callingPackage) {
7234         boolean hasCarrierPriv;
7235         final long identity = Binder.clearCallingIdentity();
7236         try {
7237             hasCarrierPriv = checkCarrierPrivilegesForPackage(subId, callingPackage)
7238                     == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
7239         } finally {
7240             Binder.restoreCallingIdentity(identity);
7241         }
7242         boolean hasNetworkScanPermission =
7243                 mApp.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SCAN)
7244                         == PERMISSION_GRANTED;
7245 
7246         if (!hasCarrierPriv && !hasNetworkScanPermission) {
7247             return new SecurityException("permission.NETWORK_SCAN or carrier privileges is needed"
7248                     + " for network scans without location access.");
7249         }
7250 
7251         if (request.getSpecifiers() != null && request.getSpecifiers().length > 0) {
7252             for (RadioAccessSpecifier ras : request.getSpecifiers()) {
7253                 if (ras.getChannels() != null && ras.getChannels().length > 0) {
7254                     return new SecurityException("Specific channels must not be"
7255                             + " scanned without location access.");
7256                 }
7257             }
7258         }
7259 
7260         return null;
7261     }
7262 
7263     /**
7264      * Stops an existing network scan with the given scanId.
7265      *
7266      * @param subId id of the subscription
7267      * @param scanId id of the scan that needs to be stopped
7268      */
7269     @Override
stopNetworkScan(int subId, int scanId)7270     public void stopNetworkScan(int subId, int scanId) {
7271         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7272                 mApp, subId, "stopNetworkScan");
7273 
7274         int callingUid = Binder.getCallingUid();
7275         final long identity = Binder.clearCallingIdentity();
7276         try {
7277             mNetworkScanRequestTracker.stopNetworkScan(scanId, callingUid);
7278         } finally {
7279             Binder.restoreCallingIdentity(identity);
7280         }
7281     }
7282 
7283     /**
7284      * Get the allowed network types bitmask.
7285      *
7286      * @return the allowed network types bitmask, defined in RILConstants.java.
7287      */
7288     @Override
getAllowedNetworkTypesBitmask(int subId)7289     public int getAllowedNetworkTypesBitmask(int subId) {
7290         TelephonyPermissions
7291                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
7292                         mApp, subId, "getAllowedNetworkTypesBitmask");
7293 
7294         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7295                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getAllowedNetworkTypesBitmask");
7296 
7297         final long identity = Binder.clearCallingIdentity();
7298         try {
7299             if (DBG) log("getAllowedNetworkTypesBitmask");
7300             int[] result = (int[]) sendRequest(CMD_GET_ALLOWED_NETWORK_TYPES_BITMASK, null, subId);
7301             int networkTypesBitmask = (result != null ? result[0] : -1);
7302             if (DBG) log("getAllowedNetworkTypesBitmask: " + networkTypesBitmask);
7303             return networkTypesBitmask;
7304         } finally {
7305             Binder.restoreCallingIdentity(identity);
7306         }
7307     }
7308 
7309     /**
7310      * Get the allowed network types for certain reason.
7311      *
7312      * @param subId the id of the subscription.
7313      * @param reason the reason the allowed network type change is taking place
7314      * @return the allowed network types.
7315      */
7316     @Override
getAllowedNetworkTypesForReason(int subId, @TelephonyManager.AllowedNetworkTypesReason int reason)7317     public long getAllowedNetworkTypesForReason(int subId,
7318             @TelephonyManager.AllowedNetworkTypesReason int reason) {
7319         TelephonyPermissions.enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
7320                 mApp, subId, "getAllowedNetworkTypesForReason");
7321 
7322         if (!mApp.getResources().getBoolean(
7323                 com.android.internal.R.bool.config_force_phone_globals_creation)) {
7324             enforceTelephonyFeatureWithException(getCurrentPackageName(),
7325                     PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS,
7326                             "getAllowedNetworkTypesForReason");
7327         }
7328 
7329         final long identity = Binder.clearCallingIdentity();
7330         try {
7331             return getPhoneFromSubIdOrDefault(subId).getAllowedNetworkTypes(reason);
7332         } finally {
7333             Binder.restoreCallingIdentity(identity);
7334         }
7335     }
7336 
7337     /**
7338      * Enable/Disable E-UTRA-NR Dual Connectivity
7339      * @param subId subscription id of the sim card
7340      * @param nrDualConnectivityState expected NR dual connectivity state
7341      * This can be passed following states
7342      * <ol>
7343      * <li>Enable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_ENABLE}
7344      * <li>Disable NR dual connectivity {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE}
7345      * <li>Disable NR dual connectivity and force secondary cell to be released
7346      * {@link TelephonyManager#NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE}
7347      * </ol>
7348      * @return operation result.
7349      */
7350     @Override
setNrDualConnectivityState(int subId, @TelephonyManager.NrDualConnectivityState int nrDualConnectivityState)7351     public int setNrDualConnectivityState(int subId,
7352             @TelephonyManager.NrDualConnectivityState int nrDualConnectivityState) {
7353         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7354                 mApp, subId, "enableNRDualConnectivity");
7355         if (!isRadioInterfaceCapabilitySupported(
7356                 TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE)) {
7357             return TelephonyManager.ENABLE_NR_DUAL_CONNECTIVITY_NOT_SUPPORTED;
7358         }
7359 
7360         WorkSource workSource = getWorkSource(Binder.getCallingUid());
7361         final long identity = Binder.clearCallingIdentity();
7362         try {
7363             int result = (int) sendRequest(CMD_ENABLE_NR_DUAL_CONNECTIVITY,
7364                     nrDualConnectivityState, subId,
7365                     workSource);
7366             if (DBG) log("enableNRDualConnectivity result: " + result);
7367             return result;
7368         } finally {
7369             Binder.restoreCallingIdentity(identity);
7370         }
7371     }
7372 
7373     /**
7374      * Is E-UTRA-NR Dual Connectivity enabled
7375      * @return true if dual connectivity is enabled else false
7376      */
7377     @Override
isNrDualConnectivityEnabled(int subId)7378     public boolean isNrDualConnectivityEnabled(int subId) {
7379         TelephonyPermissions
7380                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
7381                         mApp, subId, "isNRDualConnectivityEnabled");
7382         if (!isRadioInterfaceCapabilitySupported(
7383                 TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE)) {
7384             return false;
7385         }
7386         WorkSource workSource = getWorkSource(Binder.getCallingUid());
7387         final long identity = Binder.clearCallingIdentity();
7388         try {
7389             boolean isEnabled = (boolean) sendRequest(CMD_IS_NR_DUAL_CONNECTIVITY_ENABLED,
7390                     null, subId, workSource);
7391             if (DBG) log("isNRDualConnectivityEnabled: " + isEnabled);
7392             return isEnabled;
7393         } finally {
7394             Binder.restoreCallingIdentity(identity);
7395         }
7396     }
7397 
7398     /**
7399      * Set the allowed network types of the device and
7400      * provide the reason triggering the allowed network change.
7401      *
7402      * @param subId the id of the subscription.
7403      * @param reason the reason the allowed network type change is taking place
7404      * @param allowedNetworkTypes the allowed network types.
7405      * @return true on success; false on any failure.
7406      */
7407     @Override
setAllowedNetworkTypesForReason(int subId, @TelephonyManager.AllowedNetworkTypesReason int reason, @TelephonyManager.NetworkTypeBitMask long allowedNetworkTypes)7408     public boolean setAllowedNetworkTypesForReason(int subId,
7409             @TelephonyManager.AllowedNetworkTypesReason int reason,
7410             @TelephonyManager.NetworkTypeBitMask long allowedNetworkTypes) {
7411         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7412                 mApp, subId, "setAllowedNetworkTypesForReason");
7413         // If the caller only has carrier privileges, then they should not be able to override
7414         // any network types which were set for security reasons.
7415         if (mApp.checkCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE)
7416                 != PERMISSION_GRANTED
7417                 && reason == TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G) {
7418             throw new SecurityException(
7419                     "setAllowedNetworkTypesForReason cannot be called with carrier privileges for"
7420                             + " reason " + reason);
7421         }
7422 
7423         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7424                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "setAllowedNetworkTypesForReason");
7425 
7426         if (!TelephonyManager.isValidAllowedNetworkTypesReason(reason)) {
7427             loge("setAllowedNetworkTypesForReason: Invalid allowed network type reason: " + reason);
7428             return false;
7429         }
7430         if (!SubscriptionManager.isUsableSubscriptionId(subId)) {
7431             loge("setAllowedNetworkTypesForReason: Invalid subscriptionId:" + subId);
7432             return false;
7433         }
7434 
7435         log("setAllowedNetworkTypesForReason: subId=" + subId + ", reason=" + reason + " value: "
7436                 + TelephonyManager.convertNetworkTypeBitmaskToString(allowedNetworkTypes));
7437 
7438         Phone phone = getPhone(subId);
7439         if (phone == null) {
7440             return false;
7441         }
7442 
7443         if (allowedNetworkTypes == phone.getAllowedNetworkTypes(reason)) {
7444             log("setAllowedNetworkTypesForReason: " + reason + "does not change value");
7445             return true;
7446         }
7447 
7448         final long identity = Binder.clearCallingIdentity();
7449         try {
7450             Boolean success = (Boolean) sendRequest(
7451                     CMD_SET_ALLOWED_NETWORK_TYPES_FOR_REASON,
7452                     new Pair<Integer, Long>(reason, allowedNetworkTypes), subId);
7453 
7454             if (DBG) log("setAllowedNetworkTypesForReason: " + (success ? "ok" : "fail"));
7455             return success;
7456         } finally {
7457             Binder.restoreCallingIdentity(identity);
7458         }
7459     }
7460 
7461     /**
7462      * Check whether DUN APN is required for tethering with subId.
7463      *
7464      * @param subId the id of the subscription to require tethering.
7465      * @return {@code true} if DUN APN is required for tethering.
7466      * @hide
7467      */
7468     @Override
isTetheringApnRequiredForSubscriber(int subId)7469     public boolean isTetheringApnRequiredForSubscriber(int subId) {
7470         enforceModifyPermission();
7471 
7472         if (!mApp.getResources().getBoolean(
7473                     com.android.internal.R.bool.config_force_phone_globals_creation)) {
7474             enforceTelephonyFeatureWithException(getCurrentPackageName(),
7475                     PackageManager.FEATURE_TELEPHONY_DATA, "isTetheringApnRequiredForSubscriber");
7476         }
7477 
7478         final long identity = Binder.clearCallingIdentity();
7479         final Phone phone = getPhone(subId);
7480         try {
7481             if (phone != null) {
7482                 return phone.hasMatchedTetherApnSetting();
7483             } else {
7484                 return false;
7485             }
7486         } finally {
7487             Binder.restoreCallingIdentity(identity);
7488         }
7489     }
7490 
7491     /**
7492      * Get the user enabled state of Mobile Data.
7493      *
7494      * TODO: remove and use isUserDataEnabled.
7495      * This can't be removed now because some vendor codes
7496      * calls through ITelephony directly while they should
7497      * use TelephonyManager.
7498      *
7499      * @return true on enabled
7500      */
7501     @Override
getDataEnabled(int subId)7502     public boolean getDataEnabled(int subId) {
7503         return isUserDataEnabled(subId);
7504     }
7505 
7506     /**
7507      * Get whether mobile data is enabled per user setting.
7508      *
7509      * There are other factors deciding whether mobile data is actually enabled, but they are
7510      * not considered here. See {@link #isDataEnabled(int)} for more details.
7511      *
7512      * Accepts either READ_BASIC_PHONE_STATE, ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE
7513      * or carrier privileges.
7514      *
7515      * @return {@code true} if data is enabled else {@code false}
7516      */
7517     @Override
isUserDataEnabled(int subId)7518     public boolean isUserDataEnabled(int subId) {
7519         String functionName = "isUserDataEnabled";
7520         try {
7521             try {
7522                 mApp.enforceCallingOrSelfPermission(permission.READ_BASIC_PHONE_STATE,
7523                         functionName);
7524             } catch (SecurityException e) {
7525                 mApp.enforceCallingOrSelfPermission(permission.ACCESS_NETWORK_STATE, functionName);
7526             }
7527         } catch (SecurityException e) {
7528             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7529                     mApp, subId, functionName);
7530 
7531         }
7532 
7533         final long identity = Binder.clearCallingIdentity();
7534         try {
7535             int phoneId = SubscriptionManager.getPhoneId(subId);
7536             if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
7537             Phone phone = PhoneFactory.getPhone(phoneId);
7538             if (phone != null) {
7539                 boolean retVal = phone.isUserDataEnabled();
7540                 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
7541                 return retVal;
7542             } else {
7543                 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
7544                 return false;
7545             }
7546         } finally {
7547             Binder.restoreCallingIdentity(identity);
7548         }
7549     }
7550 
7551     /**
7552      * Checks if the device is capable of mobile data by considering whether whether the
7553      * user has enabled mobile data, whether the carrier has enabled mobile data, and
7554      * whether the network policy allows data connections.
7555      *
7556      * @return {@code true} if the overall data connection is capable; {@code false} if not.
7557      */
7558     @Override
isDataEnabled(int subId)7559     public boolean isDataEnabled(int subId) {
7560         String functionName = "isDataEnabled";
7561         try {
7562             try {
7563                 mApp.enforceCallingOrSelfPermission(
7564                         android.Manifest.permission.ACCESS_NETWORK_STATE,
7565                         functionName);
7566             } catch (SecurityException e) {
7567                 try {
7568                     mApp.enforceCallingOrSelfPermission(
7569                             android.Manifest.permission.READ_PHONE_STATE,
7570                             functionName);
7571                 } catch (SecurityException e2) {
7572                     mApp.enforceCallingOrSelfPermission(
7573                             permission.READ_BASIC_PHONE_STATE, functionName);
7574                 }
7575             }
7576         } catch (SecurityException e) {
7577             enforceReadPrivilegedPermission(functionName);
7578         }
7579 
7580         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7581                 PackageManager.FEATURE_TELEPHONY_DATA, "isDataEnabled");
7582 
7583         final long identity = Binder.clearCallingIdentity();
7584         try {
7585             int phoneId = SubscriptionManager.getPhoneId(subId);
7586             Phone phone = PhoneFactory.getPhone(phoneId);
7587             if (phone != null && phone.getDataSettingsManager() != null) {
7588                 boolean retVal = phone.getDataSettingsManager().isDataEnabled();
7589                 if (DBG) log("isDataEnabled: " + retVal + ", subId=" + subId);
7590                 return retVal;
7591             } else {
7592                 if (DBG) {
7593                     loge("isDataEnabled: no phone or no DataSettingsManager subId="
7594                             + subId + " retVal=false");
7595                 }
7596                 return false;
7597             }
7598         } finally {
7599             Binder.restoreCallingIdentity(identity);
7600         }
7601     }
7602 
7603     /**
7604      * Check if data is enabled for a specific reason
7605      * @param subId Subscription index
7606      * @param reason the reason the data enable change is taking place
7607      * @return {@code true} if the overall data is enabled; {@code false} if not.
7608      */
7609     @Override
isDataEnabledForReason(int subId, @TelephonyManager.DataEnabledReason int reason)7610     public boolean isDataEnabledForReason(int subId,
7611             @TelephonyManager.DataEnabledReason int reason) {
7612         String functionName = "isDataEnabledForReason";
7613         try {
7614             try {
7615                 mApp.enforceCallingOrSelfPermission(
7616                         android.Manifest.permission.ACCESS_NETWORK_STATE,
7617                         functionName);
7618             } catch (SecurityException e) {
7619                 mApp.enforceCallingOrSelfPermission(permission.READ_BASIC_PHONE_STATE,
7620                         functionName);
7621             }
7622         } catch (SecurityException e) {
7623             try {
7624                 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
7625                         functionName);
7626             } catch (SecurityException e2) {
7627                 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7628                         mApp, subId, functionName);
7629             }
7630         }
7631 
7632         if (!mApp.getResources().getBoolean(
7633                     com.android.internal.R.bool.config_force_phone_globals_creation)) {
7634             enforceTelephonyFeatureWithException(getCurrentPackageName(),
7635                     PackageManager.FEATURE_TELEPHONY_DATA, "isDataEnabledForReason");
7636         }
7637 
7638         final long identity = Binder.clearCallingIdentity();
7639         try {
7640             int phoneId = SubscriptionManager.getPhoneId(subId);
7641             if (DBG) {
7642                 log("isDataEnabledForReason: subId=" + subId + " phoneId=" + phoneId
7643                         + " reason=" + reason);
7644             }
7645             Phone phone = PhoneFactory.getPhone(phoneId);
7646             if (phone != null && phone.getDataSettingsManager() != null) {
7647                 boolean retVal;
7648                 retVal = phone.getDataSettingsManager().isDataEnabledForReason(reason);
7649                 if (DBG) log("isDataEnabledForReason: retVal=" + retVal);
7650                 return retVal;
7651             } else {
7652                 if (DBG) {
7653                     loge("isDataEnabledForReason: no phone or no DataSettingsManager subId="
7654                             + subId + " retVal=false");
7655                 }
7656                 return false;
7657             }
7658         } finally {
7659             Binder.restoreCallingIdentity(identity);
7660         }
7661     }
7662 
7663     @Override
getCarrierPrivilegeStatus(int subId)7664     public int getCarrierPrivilegeStatus(int subId) {
7665         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7666                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getCarrierPrivilegeStatus");
7667 
7668         // No permission needed; this only lets the caller inspect their own status.
7669         return getCarrierPrivilegeStatusForUidWithPermission(subId, Binder.getCallingUid());
7670     }
7671 
7672     @Override
getCarrierPrivilegeStatusForUid(int subId, int uid)7673     public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
7674         enforceReadPrivilegedPermission("getCarrierPrivilegeStatusForUid");
7675 
7676         if (!mApp.getResources().getBoolean(
7677                     com.android.internal.R.bool.config_force_phone_globals_creation)) {
7678             enforceTelephonyFeatureWithException(getCurrentPackageName(),
7679                     PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
7680                     "getCarrierPrivilegeStatusForUid");
7681         }
7682 
7683         return getCarrierPrivilegeStatusForUidWithPermission(subId, uid);
7684     }
7685 
getCarrierPrivilegeStatusForUidWithPermission(int subId, int uid)7686     private int getCarrierPrivilegeStatusForUidWithPermission(int subId, int uid) {
7687         Phone phone = getPhone(subId);
7688         if (phone == null) {
7689             loge("getCarrierPrivilegeStatusForUid: Invalid subId");
7690             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
7691         }
7692         CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7693         if (cpt == null) {
7694             loge("getCarrierPrivilegeStatusForUid: No CarrierPrivilegesTracker");
7695             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
7696         }
7697         return cpt.getCarrierPrivilegeStatusForUid(uid);
7698     }
7699 
7700     @Override
checkCarrierPrivilegesForPackage(int subId, String pkgName)7701     public int checkCarrierPrivilegesForPackage(int subId, String pkgName) {
7702         enforceReadPrivilegedPermission("checkCarrierPrivilegesForPackage");
7703 
7704         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7705                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "checkCarrierPrivilegesForPackage");
7706 
7707         if (TextUtils.isEmpty(pkgName)) {
7708             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
7709         }
7710         Phone phone = getPhone(subId);
7711         if (phone == null) {
7712             loge("checkCarrierPrivilegesForPackage: Invalid subId");
7713             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
7714         }
7715         CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7716         if (cpt == null) {
7717             loge("checkCarrierPrivilegesForPackage: No CarrierPrivilegesTracker");
7718             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
7719         }
7720         return cpt.getCarrierPrivilegeStatusForPackage(pkgName);
7721     }
7722 
7723     @Override
checkCarrierPrivilegesForPackageAnyPhone(String pkgName)7724     public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
7725         enforceReadPrivilegedPermission("checkCarrierPrivilegesForPackageAnyPhone");
7726 
7727         if (!mApp.getResources().getBoolean(
7728                     com.android.internal.R.bool.config_force_phone_globals_creation)) {
7729             enforceTelephonyFeatureWithException(getCurrentPackageName(),
7730                     PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
7731                     "checkCarrierPrivilegesForPackageAnyPhone");
7732         }
7733 
7734         return checkCarrierPrivilegesForPackageAnyPhoneWithPermission(pkgName);
7735     }
7736 
checkCarrierPrivilegesForPackageAnyPhoneWithPermission(String pkgName)7737     private int checkCarrierPrivilegesForPackageAnyPhoneWithPermission(String pkgName) {
7738         if (TextUtils.isEmpty(pkgName)) {
7739             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
7740         }
7741         int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
7742         for (int phoneId = 0; phoneId < TelephonyManager.getDefault().getPhoneCount(); phoneId++) {
7743             Phone phone = PhoneFactory.getPhone(phoneId);
7744             if (phone == null) {
7745                 continue;
7746             }
7747             CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7748             if (cpt == null) {
7749                 continue;
7750             }
7751             result = cpt.getCarrierPrivilegeStatusForPackage(pkgName);
7752             if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
7753                 break;
7754             }
7755         }
7756         return result;
7757     }
7758 
7759     @Override
getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId)7760     public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
7761         enforceReadPrivilegedPermission("getCarrierPackageNamesForIntentAndPhone");
7762 
7763         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7764                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
7765                 "getCarrierPackageNamesForIntentAndPhone");
7766 
7767         Phone phone = PhoneFactory.getPhone(phoneId);
7768         if (phone == null) {
7769             return Collections.emptyList();
7770         }
7771         CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7772         if (cpt == null) {
7773             return Collections.emptyList();
7774         }
7775         return cpt.getCarrierPackageNamesForIntent(intent);
7776     }
7777 
7778     @Override
getPackagesWithCarrierPrivileges(int phoneId)7779     public List<String> getPackagesWithCarrierPrivileges(int phoneId) {
7780         enforceReadPrivilegedPermission("getPackagesWithCarrierPrivileges");
7781 
7782         enforceTelephonyFeatureWithException(
7783                 getCurrentPackageName(),
7784                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
7785                 "getPackagesWithCarrierPrivileges");
7786 
7787         Phone phone = PhoneFactory.getPhone(phoneId);
7788         if (phone == null) {
7789             return Collections.emptyList();
7790         }
7791         CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7792         if (cpt == null) {
7793             return Collections.emptyList();
7794         }
7795         return new ArrayList<>(cpt.getPackagesWithCarrierPrivileges());
7796     }
7797 
7798     @Override
getPackagesWithCarrierPrivilegesForAllPhones()7799     public List<String> getPackagesWithCarrierPrivilegesForAllPhones() {
7800         enforceReadPrivilegedPermission("getPackagesWithCarrierPrivilegesForAllPhones");
7801 
7802         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7803                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
7804                 "getPackagesWithCarrierPrivilegesForAllPhones");
7805 
7806         Set<String> privilegedPackages = new ArraySet<>();
7807         final long identity = Binder.clearCallingIdentity();
7808         try {
7809             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
7810                 privilegedPackages.addAll(getPackagesWithCarrierPrivileges(i));
7811             }
7812         } finally {
7813             Binder.restoreCallingIdentity(identity);
7814         }
7815         return new ArrayList<>(privilegedPackages);
7816     }
7817 
7818     @Override
getCarrierServicePackageNameForLogicalSlot(int logicalSlotIndex)7819     public @Nullable String getCarrierServicePackageNameForLogicalSlot(int logicalSlotIndex) {
7820         enforceReadPrivilegedPermission("getCarrierServicePackageNameForLogicalSlot");
7821 
7822         if (!mApp.getResources().getBoolean(
7823                 com.android.internal.R.bool.config_force_phone_globals_creation)) {
7824             enforceTelephonyFeatureWithException(getCurrentPackageName(),
7825                     PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
7826                     "getCarrierServicePackageNameForLogicalSlot");
7827         }
7828 
7829         final Phone phone = PhoneFactory.getPhone(logicalSlotIndex);
7830         if (phone == null) {
7831             return null;
7832         }
7833         final CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
7834         if (cpt == null) {
7835             return null;
7836         }
7837         return cpt.getCarrierServicePackageName();
7838     }
7839 
getIccId(int subId)7840     private String getIccId(int subId) {
7841         final Phone phone = getPhone(subId);
7842         UiccPort port = phone == null ? null : phone.getUiccPort();
7843         if (port == null) {
7844             return null;
7845         }
7846         String iccId = port.getIccId();
7847         if (TextUtils.isEmpty(iccId)) {
7848             return null;
7849         }
7850         return iccId;
7851     }
7852 
7853     @Override
setCallComposerStatus(int subId, int status)7854     public void setCallComposerStatus(int subId, int status) {
7855         enforceModifyPermission();
7856 
7857         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7858                 PackageManager.FEATURE_TELEPHONY_CALLING, "setCallComposerStatus");
7859 
7860         final long identity = Binder.clearCallingIdentity();
7861         try {
7862             Phone phone = getPhone(subId);
7863             if (phone != null) {
7864                 Phone defaultPhone = phone.getImsPhone();
7865                 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
7866                     ImsPhone imsPhone = (ImsPhone) defaultPhone;
7867                     imsPhone.setCallComposerStatus(status);
7868                     ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
7869                             .updateImsServiceConfig();
7870                 }
7871             }
7872         } catch (ImsException e) {
7873             throw new ServiceSpecificException(e.getCode());
7874         }  finally {
7875             Binder.restoreCallingIdentity(identity);
7876         }
7877     }
7878 
7879     @Override
getCallComposerStatus(int subId)7880     public int getCallComposerStatus(int subId) {
7881         enforceReadPrivilegedPermission("getCallComposerStatus");
7882 
7883         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7884                 PackageManager.FEATURE_TELEPHONY_CALLING, "getCallComposerStatus");
7885 
7886         final long identity = Binder.clearCallingIdentity();
7887         try {
7888             Phone phone = getPhone(subId);
7889             if (phone != null) {
7890                 Phone defaultPhone = phone.getImsPhone();
7891                 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
7892                     ImsPhone imsPhone = (ImsPhone) defaultPhone;
7893                     return imsPhone.getCallComposerStatus();
7894                 }
7895             }
7896         } finally {
7897             Binder.restoreCallingIdentity(identity);
7898         }
7899         return TelephonyManager.CALL_COMPOSER_STATUS_OFF;
7900     }
7901 
7902     @Override
setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, String number)7903     public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
7904             String number) {
7905         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
7906                 subId, "setLine1NumberForDisplayForSubscriber");
7907 
7908         enforceTelephonyFeatureWithException(getCurrentPackageName(),
7909                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
7910                 "setLine1NumberForDisplayForSubscriber");
7911 
7912         final long identity = Binder.clearCallingIdentity();
7913         try {
7914             final String iccId = getIccId(subId);
7915             final Phone phone = getPhone(subId);
7916             if (phone == null) {
7917                 return false;
7918             }
7919             if (!TextUtils.isEmpty(number) && number.length() > LINE1_NUMBER_MAX_LEN) {
7920                 Rlog.e(LOG_TAG, "Number is too long");
7921                 return false;
7922             }
7923             final String subscriberId = phone.getSubscriberId();
7924 
7925             if (DBG_MERGE) {
7926                 Rlog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
7927                         + subscriberId + " to " + number);
7928             }
7929 
7930             if (TextUtils.isEmpty(iccId)) {
7931                 return false;
7932             }
7933 
7934             final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
7935 
7936             final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
7937             if (alphaTag == null) {
7938                 editor.remove(alphaTagPrefKey);
7939             } else {
7940                 editor.putString(alphaTagPrefKey, alphaTag);
7941             }
7942 
7943             // Record both the line number and IMSI for this ICCID, since we need to
7944             // track all merged IMSIs based on line number
7945             final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
7946             final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
7947             if (number == null) {
7948                 editor.remove(numberPrefKey);
7949                 editor.remove(subscriberPrefKey);
7950             } else {
7951                 editor.putString(numberPrefKey, number);
7952                 editor.putString(subscriberPrefKey, subscriberId);
7953             }
7954 
7955             editor.commit();
7956             return true;
7957         } finally {
7958             Binder.restoreCallingIdentity(identity);
7959         }
7960     }
7961 
7962     @Override
getLine1NumberForDisplay(int subId, String callingPackage, String callingFeatureId)7963     public String getLine1NumberForDisplay(int subId, String callingPackage,
7964             String callingFeatureId) {
7965         // This is open to apps with WRITE_SMS.
7966         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
7967                 mApp, subId, callingPackage, callingFeatureId, "getLine1NumberForDisplay")) {
7968             if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
7969             return null;
7970         }
7971 
7972         if (!mApp.getResources().getBoolean(
7973                     com.android.internal.R.bool.config_force_phone_globals_creation)) {
7974             enforceTelephonyFeatureWithException(callingPackage,
7975                     PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getLine1NumberForDisplay");
7976         }
7977 
7978         final long identity = Binder.clearCallingIdentity();
7979         try {
7980             String iccId = getIccId(subId);
7981             if (iccId != null) {
7982                 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
7983                 if (DBG_MERGE) {
7984                     log("getLine1NumberForDisplay returning "
7985                             + mTelephonySharedPreferences.getString(numberPrefKey, null));
7986                 }
7987                 return mTelephonySharedPreferences.getString(numberPrefKey, null);
7988             }
7989             if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
7990             return null;
7991         } finally {
7992             Binder.restoreCallingIdentity(identity);
7993         }
7994     }
7995 
7996     @Override
getLine1AlphaTagForDisplay(int subId, String callingPackage, String callingFeatureId)7997     public String getLine1AlphaTagForDisplay(int subId, String callingPackage,
7998             String callingFeatureId) {
7999         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
8000                 mApp, subId, callingPackage, callingFeatureId, "getLine1AlphaTagForDisplay")) {
8001             return null;
8002         }
8003 
8004         final long identity = Binder.clearCallingIdentity();
8005         try {
8006             String iccId = getIccId(subId);
8007             if (iccId != null) {
8008                 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
8009                 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
8010             }
8011             return null;
8012         } finally {
8013             Binder.restoreCallingIdentity(identity);
8014         }
8015     }
8016 
8017     @Override
getMergedSubscriberIds(int subId, String callingPackage, String callingFeatureId)8018     public String[] getMergedSubscriberIds(int subId, String callingPackage,
8019             String callingFeatureId) {
8020         // This API isn't public, so no need to provide a valid subscription ID - we're not worried
8021         // about carrier-privileged callers not having access.
8022         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
8023                 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
8024                 callingFeatureId, "getMergedSubscriberIds")) {
8025             return null;
8026         }
8027 
8028         // Clear calling identity, when calling TelephonyManager, because callerUid must be
8029         // the process, where TelephonyManager was instantiated.
8030         // Otherwise AppOps check will fail.
8031         final long identity  = Binder.clearCallingIdentity();
8032         try {
8033             final Context context = mApp;
8034             final TelephonyManager tele = TelephonyManager.from(context);
8035             final SubscriptionManager sub = SubscriptionManager.from(context);
8036 
8037             // Figure out what subscribers are currently active
8038             final ArraySet<String> activeSubscriberIds = new ArraySet<>();
8039 
8040             // Only consider subs which match the current subId
8041             // This logic can be simplified. See b/131189269 for progress.
8042             if (isActiveSubscription(subId)) {
8043                 activeSubscriberIds.add(tele.getSubscriberId(subId));
8044             }
8045 
8046             // First pass, find a number override for an active subscriber
8047             String mergeNumber = null;
8048             final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
8049             for (String key : prefs.keySet()) {
8050                 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
8051                     final String subscriberId = (String) prefs.get(key);
8052                     if (activeSubscriberIds.contains(subscriberId)) {
8053                         final String iccId = key.substring(
8054                                 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
8055                         final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
8056                         mergeNumber = (String) prefs.get(numberKey);
8057                         if (DBG_MERGE) {
8058                             Rlog.d(LOG_TAG, "Found line number " + mergeNumber
8059                                     + " for active subscriber " + subscriberId);
8060                         }
8061                         if (!TextUtils.isEmpty(mergeNumber)) {
8062                             break;
8063                         }
8064                     }
8065                 }
8066             }
8067 
8068             // Shortcut when no active merged subscribers
8069             if (TextUtils.isEmpty(mergeNumber)) {
8070                 return null;
8071             }
8072 
8073             // Second pass, find all subscribers under that line override
8074             final ArraySet<String> result = new ArraySet<>();
8075             for (String key : prefs.keySet()) {
8076                 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
8077                     final String number = (String) prefs.get(key);
8078                     if (mergeNumber.equals(number)) {
8079                         final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
8080                         final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
8081                         final String subscriberId = (String) prefs.get(subscriberKey);
8082                         if (!TextUtils.isEmpty(subscriberId)) {
8083                             result.add(subscriberId);
8084                         }
8085                     }
8086                 }
8087             }
8088 
8089             final String[] resultArray = result.toArray(new String[result.size()]);
8090             Arrays.sort(resultArray);
8091             if (DBG_MERGE) {
8092                 Rlog.d(LOG_TAG,
8093                         "Found subscribers " + Arrays.toString(resultArray) + " after merge");
8094             }
8095             return resultArray;
8096         } finally {
8097             Binder.restoreCallingIdentity(identity);
8098         }
8099     }
8100 
8101     @Override
getMergedImsisFromGroup(int subId, String callingPackage)8102     public String[] getMergedImsisFromGroup(int subId, String callingPackage) {
8103         enforceReadPrivilegedPermission("getMergedImsisFromGroup");
8104 
8105         enforceTelephonyFeatureWithException(callingPackage,
8106                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getMergedImsisFromGroup");
8107 
8108         final long identity = Binder.clearCallingIdentity();
8109         try {
8110             final TelephonyManager telephonyManager = mApp.getSystemService(
8111                     TelephonyManager.class);
8112             String subscriberId = telephonyManager.getSubscriberId(subId);
8113             if (subscriberId == null) {
8114                 if (DBG) {
8115                     log("getMergedImsisFromGroup can't find subscriberId for subId "
8116                             + subId);
8117                 }
8118                 return null;
8119             }
8120 
8121             final SubscriptionInfo info = getSubscriptionManagerService()
8122                     .getSubscriptionInfo(subId);
8123             ParcelUuid groupUuid = info.getGroupUuid();
8124             // If it doesn't belong to any group, return just subscriberId of itself.
8125             if (groupUuid == null) {
8126                 return new String[]{subscriberId};
8127             }
8128 
8129             // Get all subscriberIds from the group.
8130             final List<String> mergedSubscriberIds = new ArrayList<>();
8131             List<SubscriptionInfo> groupInfos = getSubscriptionManagerService()
8132                     .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
8133                             mApp.getAttributionTag());
8134             for (SubscriptionInfo subInfo : groupInfos) {
8135                 subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
8136                 if (subscriberId != null) {
8137                     mergedSubscriberIds.add(subscriberId);
8138                 }
8139             }
8140 
8141             return mergedSubscriberIds.toArray(new String[mergedSubscriberIds.size()]);
8142         } finally {
8143             Binder.restoreCallingIdentity(identity);
8144 
8145         }
8146     }
8147 
8148     @Override
setOperatorBrandOverride(int subId, String brand)8149     public boolean setOperatorBrandOverride(int subId, String brand) {
8150         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
8151                 subId, "setOperatorBrandOverride");
8152 
8153         enforceTelephonyFeatureWithException(getCurrentPackageName(),
8154                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "setOperatorBrandOverride");
8155 
8156         final long identity = Binder.clearCallingIdentity();
8157         try {
8158             final Phone phone = getPhone(subId);
8159             return phone == null ? false : phone.setOperatorBrandOverride(brand);
8160         } finally {
8161             Binder.restoreCallingIdentity(identity);
8162         }
8163     }
8164 
8165     @Override
setRoamingOverride(int subId, List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList)8166     public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
8167             List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
8168             List<String> cdmaNonRoamingList) {
8169         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
8170                 mApp, subId, "setRoamingOverride");
8171 
8172         final long identity = Binder.clearCallingIdentity();
8173         try {
8174             final Phone phone = getPhone(subId);
8175             if (phone == null) {
8176                 return false;
8177             }
8178             return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
8179                     cdmaNonRoamingList);
8180         } finally {
8181             Binder.restoreCallingIdentity(identity);
8182         }
8183     }
8184 
8185     @Override
getRadioAccessFamily(int phoneId, String callingPackage)8186     public int getRadioAccessFamily(int phoneId, String callingPackage) {
8187         int raf = RadioAccessFamily.RAF_UNKNOWN;
8188         Phone phone = PhoneFactory.getPhone(phoneId);
8189         if (phone == null) {
8190             return raf;
8191         }
8192 
8193         try {
8194             TelephonyPermissions
8195                     .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
8196                             mApp, phone.getSubId(), "getRadioAccessFamily");
8197         } catch (SecurityException e) {
8198             EventLog.writeEvent(0x534e4554, "150857259", -1, "Missing Permission");
8199             throw e;
8200         }
8201 
8202         if (!mApp.getResources().getBoolean(
8203                 com.android.internal.R.bool.config_force_phone_globals_creation)) {
8204             enforceTelephonyFeatureWithException(callingPackage,
8205                     PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getRadioAccessFamily");
8206         }
8207 
8208         final long identity = Binder.clearCallingIdentity();
8209         try {
8210             raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
8211         } finally {
8212             Binder.restoreCallingIdentity(identity);
8213         }
8214         return raf;
8215     }
8216 
8217     @Override
uploadCallComposerPicture(int subscriptionId, String callingPackage, String contentType, ParcelFileDescriptor fd, ResultReceiver callback)8218     public void uploadCallComposerPicture(int subscriptionId, String callingPackage,
8219             String contentType, ParcelFileDescriptor fd, ResultReceiver callback) {
8220         enforceCallingPackage(callingPackage, Binder.getCallingUid(),
8221                 "Invalid package:" + callingPackage);
8222         enforceTelephonyFeatureWithException(callingPackage,
8223                 PackageManager.FEATURE_TELEPHONY_CALLING, "uploadCallComposerPicture");
8224 
8225         RoleManager rm = mApp.getSystemService(RoleManager.class);
8226         List<String> dialerRoleHolders;
8227         dialerRoleHolders = rm.getRoleHoldersAsUser(RoleManager.ROLE_DIALER,
8228                 UserHandle.of(ActivityManager.getCurrentUser()));
8229         if (!dialerRoleHolders.contains(callingPackage)) {
8230             throw new SecurityException("App must be the dialer role holder to"
8231                     + " upload a call composer pic");
8232         }
8233 
8234         Executors.newSingleThreadExecutor().execute(() -> {
8235             ByteArrayOutputStream output = new ByteArrayOutputStream(
8236                     (int) TelephonyManager.getMaximumCallComposerPictureSize());
8237             InputStream input = new ParcelFileDescriptor.AutoCloseInputStream(fd);
8238             boolean readUntilEnd = false;
8239             int totalBytesRead = 0;
8240             byte[] buffer = new byte[16 * 1024];
8241             while (true) {
8242                 int numRead;
8243                 try {
8244                     numRead = input.read(buffer);
8245                 } catch (IOException e) {
8246                     try {
8247                         fd.checkError();
8248                         callback.send(TelephonyManager.CallComposerException.ERROR_INPUT_CLOSED,
8249                                 null);
8250                     } catch (IOException e1) {
8251                         // This means that the other side closed explicitly with an error. If this
8252                         // happens, log and ignore.
8253                         loge("Remote end of call composer picture pipe closed: " + e1);
8254                     }
8255                     break;
8256                 }
8257                 if (numRead == -1) {
8258                     readUntilEnd = true;
8259                     break;
8260                 }
8261                 totalBytesRead += numRead;
8262                 if (totalBytesRead > TelephonyManager.getMaximumCallComposerPictureSize()) {
8263                     loge("Too many bytes read for call composer picture: " + totalBytesRead);
8264                     try {
8265                         input.close();
8266                     } catch (IOException e) {
8267                         // ignore
8268                     }
8269                     break;
8270                 }
8271                 output.write(buffer, 0, numRead);
8272             }
8273             // Generally, the remote end will close the file descriptors. The only case where we
8274             // close is above, where the picture size is too big.
8275 
8276             try {
8277                 fd.checkError();
8278             } catch (IOException e) {
8279                 loge("Remote end for call composer closed with an error: " + e);
8280                 return;
8281             }
8282 
8283             if (!readUntilEnd) {
8284                 loge("Did not finish reading entire image; aborting");
8285                 return;
8286             }
8287 
8288             ImageData imageData = new ImageData(output.toByteArray(), contentType, null);
8289             CallComposerPictureManager.getInstance(mApp, subscriptionId).handleUploadToServer(
8290                     new CallComposerPictureTransfer.Factory() {},
8291                     imageData,
8292                     (result) -> {
8293                         if (result.first != null) {
8294                             ParcelUuid parcelUuid = new ParcelUuid(result.first);
8295                             Bundle outputResult = new Bundle();
8296                             outputResult.putParcelable(
8297                                     TelephonyManager.KEY_CALL_COMPOSER_PICTURE_HANDLE, parcelUuid);
8298                             callback.send(TelephonyManager.CallComposerException.SUCCESS,
8299                                     outputResult);
8300                         } else {
8301                             callback.send(result.second, null);
8302                         }
8303                     }
8304             );
8305         });
8306     }
8307 
8308     @Override
enableVideoCalling(boolean enable)8309     public void enableVideoCalling(boolean enable) {
8310         final Phone defaultPhone = getDefaultPhone();
8311         enforceModifyPermission();
8312 
8313         enforceTelephonyFeatureWithException(getCurrentPackageName(),
8314                 PackageManager.FEATURE_TELEPHONY_IMS, "enableVideoCalling");
8315 
8316         final long identity = Binder.clearCallingIdentity();
8317         try {
8318             ImsManager.getInstance(defaultPhone.getContext(),
8319                     defaultPhone.getPhoneId()).setVtSetting(enable);
8320         } finally {
8321             Binder.restoreCallingIdentity(identity);
8322         }
8323     }
8324 
8325     @Override
isVideoCallingEnabled(String callingPackage, String callingFeatureId)8326     public boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId) {
8327         final Phone defaultPhone = getDefaultPhone();
8328         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
8329                 callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
8330             return false;
8331         }
8332 
8333         enforceTelephonyFeatureWithException(callingPackage,
8334                 PackageManager.FEATURE_TELEPHONY_IMS, "isVideoCallingEnabled");
8335 
8336         final long identity = Binder.clearCallingIdentity();
8337         try {
8338             // Check the user preference and the  system-level IMS setting. Even if the user has
8339             // enabled video calling, if IMS is disabled we aren't able to support video calling.
8340             // In the long run, we may instead need to check if there exists a connection service
8341             // which can support video calling.
8342             ImsManager imsManager =
8343                     ImsManager.getInstance(defaultPhone.getContext(), defaultPhone.getPhoneId());
8344             return imsManager.isVtEnabledByPlatform()
8345                     && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
8346                     && imsManager.isVtEnabledByUser();
8347         } finally {
8348             Binder.restoreCallingIdentity(identity);
8349         }
8350     }
8351 
8352     @Override
canChangeDtmfToneLength(int subId, String callingPackage, String callingFeatureId)8353     public boolean canChangeDtmfToneLength(int subId, String callingPackage,
8354             String callingFeatureId) {
8355         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
8356                 mApp, subId, callingPackage, callingFeatureId,
8357                 "isVideoCallingEnabled")) {
8358             return false;
8359         }
8360 
8361         enforceTelephonyFeatureWithException(callingPackage,
8362                 PackageManager.FEATURE_TELEPHONY_CALLING, "canChangeDtmfToneLength");
8363 
8364         final long identity = Binder.clearCallingIdentity();
8365         try {
8366             CarrierConfigManager configManager =
8367                     (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
8368             return configManager.getConfigForSubId(subId)
8369                     .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
8370         } finally {
8371             Binder.restoreCallingIdentity(identity);
8372         }
8373     }
8374 
8375     @Override
isWorldPhone(int subId, String callingPackage, String callingFeatureId)8376     public boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId) {
8377         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
8378                 mApp, subId, callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
8379             return false;
8380         }
8381 
8382         enforceTelephonyFeatureWithException(callingPackage,
8383                 PackageManager.FEATURE_TELEPHONY, "isWorldPhone");
8384 
8385         final long identity = Binder.clearCallingIdentity();
8386         try {
8387             CarrierConfigManager configManager =
8388                     (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
8389             return configManager.getConfigForSubId(subId)
8390                     .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
8391         } finally {
8392             Binder.restoreCallingIdentity(identity);
8393         }
8394     }
8395 
8396     @Override
isTtyModeSupported()8397     public boolean isTtyModeSupported() {
8398         TelecomManager telecomManager = mApp.getSystemService(TelecomManager.class);
8399         return telecomManager.isTtySupported();
8400     }
8401 
8402     @Override
isHearingAidCompatibilitySupported()8403     public boolean isHearingAidCompatibilitySupported() {
8404         enforceTelephonyFeatureWithException(getCurrentPackageName(),
8405                 PackageManager.FEATURE_TELEPHONY_CALLING, "isHearingAidCompatibilitySupported");
8406 
8407         final long identity = Binder.clearCallingIdentity();
8408         try {
8409             return mApp.getResources().getBoolean(R.bool.hac_enabled);
8410         } finally {
8411             Binder.restoreCallingIdentity(identity);
8412         }
8413     }
8414 
8415     /**
8416      * Determines whether the device currently supports RTT (Real-time text). Based both on carrier
8417      * support for the feature and device firmware support.
8418      *
8419      * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
8420      */
8421     @Override
isRttSupported(int subscriptionId)8422     public boolean isRttSupported(int subscriptionId) {
8423         enforceTelephonyFeatureWithException(getCurrentPackageName(),
8424                 PackageManager.FEATURE_TELEPHONY_IMS, "isRttSupported");
8425 
8426         final long identity = Binder.clearCallingIdentity();
8427         final Phone phone = getPhone(subscriptionId);
8428         if (phone == null) {
8429             loge("isRttSupported: no Phone found. Invalid subId:" + subscriptionId);
8430             return false;
8431         }
8432         try {
8433             boolean isCarrierSupported = mApp.getCarrierConfigForSubId(subscriptionId).getBoolean(
8434                     CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
8435             boolean isDeviceSupported = (phone.getContext().getResources() != null)
8436                     ? phone.getContext().getResources().getBoolean(R.bool.config_support_rtt)
8437                     : false;
8438             return isCarrierSupported && isDeviceSupported;
8439         } finally {
8440             Binder.restoreCallingIdentity(identity);
8441         }
8442     }
8443 
8444     /**
8445      * Determines whether the user has turned on RTT. If the carrier wants to ignore the user-set
8446      * RTT setting, will return true if the device and carrier both support RTT.
8447      * Otherwise. only returns true if the device and carrier both also support RTT.
8448      */
isRttEnabled(int subscriptionId)8449     public boolean isRttEnabled(int subscriptionId) {
8450         final long identity = Binder.clearCallingIdentity();
8451         try {
8452             if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS)) {
8453                 return false;
8454             }
8455 
8456             boolean isRttSupported = isRttSupported(subscriptionId);
8457             boolean isUserRttSettingOn = Settings.Secure.getInt(
8458                     mApp.getContentResolver(), Settings.Secure.RTT_CALLING_MODE, 0) != 0;
8459             boolean shouldIgnoreUserRttSetting = mApp.getCarrierConfigForSubId(subscriptionId)
8460                     .getBoolean(CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL);
8461             return isRttSupported && (isUserRttSettingOn || shouldIgnoreUserRttSetting);
8462         } finally {
8463             Binder.restoreCallingIdentity(identity);
8464         }
8465     }
8466 
8467     @Deprecated
8468     @Override
getDeviceId(String callingPackage)8469     public String getDeviceId(String callingPackage) {
8470         return getDeviceIdWithFeature(callingPackage, null);
8471     }
8472 
8473     /**
8474      * Returns the unique device ID of phone, for example, the IMEI for
8475      * GSM and the MEID for CDMA phones. Return null if device ID is not available.
8476      *
8477      * <p>Requires Permission:
8478      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
8479      */
8480     @Override
getDeviceIdWithFeature(String callingPackage, String callingFeatureId)8481     public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
8482         try {
8483             mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
8484         } catch (SecurityException se) {
8485             EventLog.writeEvent(0x534e4554, "186530889", Binder.getCallingUid());
8486             throw new SecurityException("Package " + callingPackage + " does not belong to "
8487                     + Binder.getCallingUid());
8488         }
8489         final Phone phone = PhoneFactory.getPhone(0);
8490         if (phone == null) {
8491             return null;
8492         }
8493         int subId = phone.getSubId();
8494         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
8495                 callingPackage, callingFeatureId, "getDeviceId")) {
8496             return null;
8497         }
8498 
8499         final long identity = Binder.clearCallingIdentity();
8500         try {
8501             return phone.getDeviceId();
8502         } finally {
8503             Binder.restoreCallingIdentity(identity);
8504         }
8505     }
8506 
8507     /**
8508      * {@hide}
8509      * Returns the IMS Registration Status on a particular subid
8510      *
8511      * @param subId
8512      */
isImsRegistered(int subId)8513     public boolean isImsRegistered(int subId) {
8514         Phone phone = getPhone(subId);
8515         if (phone != null) {
8516             return phone.isImsRegistered();
8517         } else {
8518             return false;
8519         }
8520     }
8521 
8522     @Override
getSubIdForPhoneAccountHandle( PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId)8523     public int getSubIdForPhoneAccountHandle(
8524             PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId) {
8525         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, getDefaultSubscription(),
8526                 callingPackage, callingFeatureId, "getSubIdForPhoneAccountHandle")) {
8527             throw new SecurityException("Requires READ_PHONE_STATE permission.");
8528         }
8529         final long identity = Binder.clearCallingIdentity();
8530         try {
8531             return PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle);
8532         } finally {
8533             Binder.restoreCallingIdentity(identity);
8534         }
8535     }
8536 
8537     @Override
getPhoneAccountHandleForSubscriptionId(int subscriptionId)8538     public @Nullable PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId) {
8539         TelephonyPermissions
8540                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
8541                         mApp,
8542                         subscriptionId,
8543                         "getPhoneAccountHandleForSubscriptionId, " + "subscriptionId: "
8544                                 + subscriptionId);
8545 
8546         enforceTelephonyFeatureWithException(getCurrentPackageName(),
8547                 PackageManager.FEATURE_TELEPHONY_CALLING, "getPhoneAccountHandleForSubscriptionId");
8548 
8549         final long identity = Binder.clearCallingIdentity();
8550         try {
8551             Phone phone = getPhone(subscriptionId);
8552             if (phone == null) {
8553                 return null;
8554             }
8555             return PhoneUtils.makePstnPhoneAccountHandle(phone);
8556         } finally {
8557             Binder.restoreCallingIdentity(identity);
8558         }
8559     }
8560 
8561     /**
8562      * @return the VoWiFi calling availability.
8563      */
isWifiCallingAvailable(int subId)8564     public boolean isWifiCallingAvailable(int subId) {
8565         final long identity = Binder.clearCallingIdentity();
8566         try {
8567             Phone phone = getPhone(subId);
8568             if (phone != null) {
8569                 return phone.isWifiCallingEnabled();
8570             } else {
8571                 return false;
8572             }
8573         } finally {
8574             Binder.restoreCallingIdentity(identity);
8575         }
8576     }
8577 
8578     /**
8579      * @return the VT calling availability.
8580      */
isVideoTelephonyAvailable(int subId)8581     public boolean isVideoTelephonyAvailable(int subId) {
8582         final long identity = Binder.clearCallingIdentity();
8583         try {
8584             Phone phone = getPhone(subId);
8585             if (phone != null) {
8586                 return phone.isVideoEnabled();
8587             } else {
8588                 return false;
8589             }
8590         } finally {
8591             Binder.restoreCallingIdentity(identity);
8592         }
8593     }
8594 
8595     /**
8596      * @return the IMS registration technology for the MMTEL feature. Valid return values are
8597      * defined in {@link ImsRegistrationImplBase}.
8598      */
getImsRegTechnologyForMmTel(int subId)8599     public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
8600         final long identity = Binder.clearCallingIdentity();
8601         try {
8602             Phone phone = getPhone(subId);
8603             if (phone != null) {
8604                 return phone.getImsRegistrationTech();
8605             } else {
8606                 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
8607             }
8608         } finally {
8609             Binder.restoreCallingIdentity(identity);
8610         }
8611     }
8612 
8613     @Override
factoryReset(int subId, String callingPackage)8614     public void factoryReset(int subId, String callingPackage) {
8615         enforceSettingsPermission();
8616 
8617         enforceTelephonyFeatureWithException(callingPackage,
8618                 PackageManager.FEATURE_TELEPHONY, "factoryReset");
8619 
8620         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
8621             return;
8622         }
8623         Phone defaultPhone = getDefaultPhone();
8624         if (defaultPhone != null) {
8625             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8626                     mApp, getDefaultPhone().getSubId(), "factoryReset");
8627         }
8628         final long identity = Binder.clearCallingIdentity();
8629 
8630         try {
8631             if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
8632                     UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
8633                 setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_USER,
8634                         getDefaultDataEnabled(), callingPackage);
8635                 setNetworkSelectionModeAutomatic(subId);
8636                 Phone phone = getPhone(subId);
8637                 cleanUpAllowedNetworkTypes(phone, subId);
8638 
8639                 setDataRoamingEnabled(subId, phone == null ? false
8640                         : phone.getDataSettingsManager().isDefaultDataRoamingEnabled());
8641                 getPhone(subId).resetCarrierKeysForImsiEncryption(true);
8642             }
8643             // There has been issues when Sms raw table somehow stores orphan
8644             // fragments. They lead to garbled message when new fragments come
8645             // in and combined with those stale ones. In case this happens again,
8646             // user can reset all network settings which will clean up this table.
8647             cleanUpSmsRawTable(getDefaultPhone().getContext());
8648             // Clean up IMS settings as well here.
8649             int slotId = getSlotIndex(subId);
8650             if (isImsAvailableOnDevice() && slotId > SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
8651                 ImsManager.getInstance(mApp, slotId).factoryReset();
8652             }
8653 
8654             if (defaultPhone == null) {
8655                 return;
8656             }
8657             // Erase modem config if erase modem on network setting is enabled.
8658             String configValue = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_TELEPHONY,
8659                     RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED);
8660             if (configValue != null && Boolean.parseBoolean(configValue)) {
8661                 sendEraseModemConfig(defaultPhone);
8662             }
8663 
8664             sendEraseDataInSharedPreferences(defaultPhone);
8665         } finally {
8666             Binder.restoreCallingIdentity(identity);
8667         }
8668     }
8669 
8670     @VisibleForTesting
cleanUpAllowedNetworkTypes(Phone phone, int subId)8671     void cleanUpAllowedNetworkTypes(Phone phone, int subId) {
8672         if (phone == null || !SubscriptionManager.isUsableSubscriptionId(subId)) {
8673             return;
8674         }
8675         long defaultNetworkType = RadioAccessFamily.getRafFromNetworkType(
8676                 RILConstants.PREFERRED_NETWORK_MODE);
8677         SubscriptionManager.setSubscriptionProperty(subId,
8678                 SubscriptionManager.ALLOWED_NETWORK_TYPES,
8679                 "user=" + defaultNetworkType);
8680         phone.loadAllowedNetworksFromSubscriptionDatabase();
8681         phone.setAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER,
8682                 defaultNetworkType, null);
8683     }
8684 
cleanUpSmsRawTable(Context context)8685     private void cleanUpSmsRawTable(Context context) {
8686         ContentResolver resolver = context.getContentResolver();
8687         Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
8688         resolver.delete(uri, null, null);
8689     }
8690 
8691     @Override
getSimLocaleForSubscriber(int subId)8692     public String getSimLocaleForSubscriber(int subId) {
8693         enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
8694 
8695         enforceTelephonyFeatureWithException(getCurrentPackageName(),
8696                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSimLocaleForSubscriber");
8697 
8698         final Phone phone = getPhone(subId);
8699         if (phone == null) {
8700             log("getSimLocaleForSubscriber, invalid subId");
8701             return null;
8702         }
8703         final long identity = Binder.clearCallingIdentity();
8704         try {
8705             SubscriptionInfo info = getSubscriptionManagerService().getActiveSubscriptionInfo(subId,
8706                     phone.getContext().getOpPackageName(),
8707                     phone.getContext().getAttributionTag());
8708             if (info == null) {
8709                 log("getSimLocaleForSubscriber, inactive subId: " + subId);
8710                 return null;
8711             }
8712             // Try and fetch the locale from the carrier properties or from the SIM language
8713             // preferences (EF-PL and EF-LI)...
8714             final int mcc = info.getMcc();
8715             String simLanguage = null;
8716             final Locale localeFromDefaultSim = phone.getLocaleFromSimAndCarrierPrefs();
8717             if (localeFromDefaultSim != null) {
8718                 if (!localeFromDefaultSim.getCountry().isEmpty()) {
8719                     if (DBG) log("Using locale from subId: " + subId + " locale: "
8720                             + localeFromDefaultSim);
8721                     return matchLocaleFromSupportedLocaleList(phone, localeFromDefaultSim);
8722                 } else {
8723                     simLanguage = localeFromDefaultSim.getLanguage();
8724                 }
8725             }
8726 
8727             // The SIM language preferences only store a language (e.g. fr = French), not an
8728             // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
8729             // the SIM and carrier preferences does not include a country we add the country
8730             // determined from the SIM MCC to provide an exact locale.
8731             final Locale mccLocale = LocaleUtils.getLocaleFromMcc(mApp, mcc, simLanguage);
8732             if (mccLocale != null) {
8733                 if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale);
8734                 return matchLocaleFromSupportedLocaleList(phone, mccLocale);
8735             }
8736 
8737             if (DBG) log("No locale found - returning null");
8738             return null;
8739         } finally {
8740             Binder.restoreCallingIdentity(identity);
8741         }
8742     }
8743 
8744     @VisibleForTesting
matchLocaleFromSupportedLocaleList(Phone phone, @NonNull Locale inputLocale)8745     String matchLocaleFromSupportedLocaleList(Phone phone, @NonNull Locale inputLocale) {
8746         String[] supportedLocale = com.android.internal.app.LocalePicker.getSupportedLocales(
8747                 phone.getContext());
8748         for (String localeTag : supportedLocale) {
8749             if (LocaleList.matchesLanguageAndScript(inputLocale, Locale.forLanguageTag(localeTag))
8750                     && TextUtils.equals(inputLocale.getCountry(),
8751                     Locale.forLanguageTag(localeTag).getCountry())) {
8752                 return localeTag;
8753             }
8754         }
8755         return inputLocale.toLanguageTag();
8756     }
8757 
8758     /**
8759      * NOTE: this method assumes permission checks are done and caller identity has been cleared.
8760      */
getActiveSubscriptionInfoListPrivileged()8761     private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
8762         return getSubscriptionManagerService().getActiveSubscriptionInfoList(
8763                 mApp.getOpPackageName(), mApp.getAttributionTag(), true/*isForAllProfile*/);
8764     }
8765 
8766     private ActivityStatsTechSpecificInfo[] mLastModemActivitySpecificInfo = null;
8767     private ModemActivityInfo mLastModemActivityInfo = null;
8768 
8769     /**
8770      * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
8771      * representing the state of the modem.
8772      *
8773      * NOTE: The underlying implementation clears the modem state, so there should only ever be one
8774      * caller to it. Everyone should call this class to get cumulative data.
8775      * @hide
8776      */
8777     @Override
requestModemActivityInfo(ResultReceiver result)8778     public void requestModemActivityInfo(ResultReceiver result) {
8779         enforceModifyPermission();
8780 
8781         if (!mApp.getResources().getBoolean(
8782                     com.android.internal.R.bool.config_force_phone_globals_creation)) {
8783             enforceTelephonyFeatureWithException(getCurrentPackageName(),
8784                     PackageManager.FEATURE_TELEPHONY, "requestModemActivityInfo");
8785         }
8786 
8787         WorkSource workSource = getWorkSource(Binder.getCallingUid());
8788 
8789         final long identity = Binder.clearCallingIdentity();
8790         try {
8791             sendRequestAsync(CMD_GET_MODEM_ACTIVITY_INFO, result, null, workSource);
8792         } finally {
8793             Binder.restoreCallingIdentity(identity);
8794         }
8795     }
8796 
8797     // Checks that ModemActivityInfo is valid. Sleep time and Idle time should be
8798     // less than total activity duration.
isModemActivityInfoValid(ModemActivityInfo info)8799     private boolean isModemActivityInfoValid(ModemActivityInfo info) {
8800         if (info == null) {
8801             return false;
8802         }
8803         int activityDurationMs =
8804                 (int) (info.getTimestampMillis() - mLastModemActivityInfo.getTimestampMillis());
8805         activityDurationMs += MODEM_ACTIVITY_TIME_OFFSET_CORRECTION_MS;
8806 
8807         int totalTxTimeMs = Arrays.stream(info.getTransmitTimeMillis()).sum();
8808 
8809         return (info.isValid()
8810                 && (info.getSleepTimeMillis() <= activityDurationMs)
8811                 && (info.getIdleTimeMillis() <= activityDurationMs));
8812     }
8813 
updateLastModemActivityInfo(ModemActivityInfo info, int rat, int freq)8814     private void updateLastModemActivityInfo(ModemActivityInfo info, int rat, int freq) {
8815         int[] mergedTxTimeMs = new int [ModemActivityInfo.getNumTxPowerLevels()];
8816         int[] txTimeMs = info.getTransmitTimeMillis(rat, freq);
8817         int[] lastModemTxTimeMs = mLastModemActivityInfo.getTransmitTimeMillis(rat, freq);
8818 
8819         for (int lvl = 0; lvl < mergedTxTimeMs.length; lvl++) {
8820             mergedTxTimeMs[lvl] = txTimeMs[lvl] + lastModemTxTimeMs[lvl];
8821         }
8822 
8823         mLastModemActivityInfo.setTransmitTimeMillis(rat, freq, mergedTxTimeMs);
8824         mLastModemActivityInfo.setReceiveTimeMillis(
8825                 rat,
8826                 freq,
8827                 info.getReceiveTimeMillis(rat, freq)
8828                         + mLastModemActivityInfo.getReceiveTimeMillis(rat, freq));
8829     }
8830 
updateLastModemActivityInfo(ModemActivityInfo info, int rat)8831     private void updateLastModemActivityInfo(ModemActivityInfo info, int rat) {
8832         int[] mergedTxTimeMs = new int [ModemActivityInfo.getNumTxPowerLevels()];
8833         int[] txTimeMs = info.getTransmitTimeMillis(rat);
8834         int[] lastModemTxTimeMs = mLastModemActivityInfo.getTransmitTimeMillis(rat);
8835 
8836         for (int lvl = 0; lvl < mergedTxTimeMs.length; lvl++) {
8837             mergedTxTimeMs[lvl] = txTimeMs[lvl] + lastModemTxTimeMs[lvl];
8838         }
8839         mLastModemActivityInfo.setTransmitTimeMillis(rat, mergedTxTimeMs);
8840         mLastModemActivityInfo.setReceiveTimeMillis(
8841                 rat,
8842                 info.getReceiveTimeMillis(rat) + mLastModemActivityInfo.getReceiveTimeMillis(rat));
8843     }
8844 
8845     /**
8846      * Merge this ModemActivityInfo with mLastModemActivitySpecificInfo
8847      * @param info recent ModemActivityInfo
8848      */
mergeModemActivityInfo(ModemActivityInfo info)8849     private void mergeModemActivityInfo(ModemActivityInfo info) {
8850         List<ActivityStatsTechSpecificInfo> merged = new ArrayList<>();
8851         ActivityStatsTechSpecificInfo deltaSpecificInfo;
8852         boolean matched;
8853         for (int i = 0; i < info.getSpecificInfoLength(); i++) {
8854             matched = false;
8855             int rat = info.getSpecificInfoRat(i);
8856             int freq = info.getSpecificInfoFrequencyRange(i);
8857             //Check each ActivityStatsTechSpecificInfo in this ModemActivityInfo for new rat returns
8858             //Add a new ActivityStatsTechSpecificInfo if is a new rat, and merge with the original
8859             //if it already exists
8860             for (int j = 0; j < mLastModemActivitySpecificInfo.length; j++) {
8861                 if (rat == mLastModemActivityInfo.getSpecificInfoRat(j) && !matched) {
8862                     //Merged based on frequency range (MMWAVE vs SUB6) for 5G
8863                     if (rat == AccessNetworkConstants.AccessNetworkType.NGRAN) {
8864                         if (freq == mLastModemActivityInfo.getSpecificInfoFrequencyRange(j)) {
8865                             updateLastModemActivityInfo(info, rat, freq);
8866                             matched = true;
8867                         }
8868                     } else {
8869                         updateLastModemActivityInfo(info, rat);
8870                         matched = true;
8871                     }
8872                 }
8873             }
8874 
8875             if (!matched) {
8876                 deltaSpecificInfo =
8877                         new ActivityStatsTechSpecificInfo(
8878                                 rat,
8879                                 freq,
8880                                 info.getTransmitTimeMillis(rat, freq),
8881                                 (int) info.getReceiveTimeMillis(rat, freq));
8882                 merged.addAll(Arrays.asList(deltaSpecificInfo));
8883             }
8884         }
8885         merged.addAll(Arrays.asList(mLastModemActivitySpecificInfo));
8886         mLastModemActivitySpecificInfo =
8887                 new ActivityStatsTechSpecificInfo[merged.size()];
8888         merged.toArray(mLastModemActivitySpecificInfo);
8889 
8890         mLastModemActivityInfo.setTimestamp(info.getTimestampMillis());
8891         mLastModemActivityInfo.setSleepTimeMillis(
8892                 info.getSleepTimeMillis()
8893                         + mLastModemActivityInfo.getSleepTimeMillis());
8894         mLastModemActivityInfo.setIdleTimeMillis(
8895                 info.getIdleTimeMillis()
8896                         + mLastModemActivityInfo.getIdleTimeMillis());
8897 
8898         mLastModemActivityInfo =
8899                 new ModemActivityInfo(
8900                         mLastModemActivityInfo.getTimestampMillis(),
8901                         mLastModemActivityInfo.getSleepTimeMillis(),
8902                         mLastModemActivityInfo.getIdleTimeMillis(),
8903                         mLastModemActivitySpecificInfo);
8904     }
8905 
deepCopyModemActivitySpecificInfo( ActivityStatsTechSpecificInfo[] info)8906     private ActivityStatsTechSpecificInfo[] deepCopyModemActivitySpecificInfo(
8907             ActivityStatsTechSpecificInfo[] info) {
8908         int infoSize = info.length;
8909         ActivityStatsTechSpecificInfo[] ret = new ActivityStatsTechSpecificInfo[infoSize];
8910         for (int i = 0; i < infoSize; i++) {
8911             ret[i] = new ActivityStatsTechSpecificInfo(
8912                     info[i].getRat(), info[i].getFrequencyRange(),
8913                     info[i].getTransmitTimeMillis(),
8914                     (int) info[i].getReceiveTimeMillis());
8915         }
8916         return ret;
8917     }
8918 
8919     /**
8920      * Returns the service state information on specified SIM slot.
8921      */
8922     @Override
getServiceStateForSlot(int slotIndex, boolean renounceFineLocationAccess, boolean renounceCoarseLocationAccess, String callingPackage, String callingFeatureId)8923     public ServiceState getServiceStateForSlot(int slotIndex, boolean renounceFineLocationAccess,
8924             boolean renounceCoarseLocationAccess, String callingPackage, String callingFeatureId) {
8925         Phone phone = PhoneFactory.getPhone(slotIndex);
8926         if (phone == null) {
8927             loge("getServiceStateForSlot retuning null for invalid slotIndex=" + slotIndex);
8928             return null;
8929         }
8930 
8931         int subId = phone.getSubId();
8932         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
8933                 mApp, subId, callingPackage, callingFeatureId, "getServiceStateForSubscriber")) {
8934             return null;
8935         }
8936 
8937         enforceTelephonyFeatureWithException(callingPackage,
8938                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getServiceStateForSubscriber");
8939 
8940         boolean hasFinePermission = false;
8941         boolean hasCoarsePermission = false;
8942         if (!renounceFineLocationAccess) {
8943             LocationAccessPolicy.LocationPermissionResult fineLocationResult =
8944                     LocationAccessPolicy.checkLocationPermission(mApp,
8945                             new LocationAccessPolicy.LocationPermissionQuery.Builder()
8946                                     .setCallingPackage(callingPackage)
8947                                     .setCallingFeatureId(callingFeatureId)
8948                                     .setCallingPid(Binder.getCallingPid())
8949                                     .setCallingUid(Binder.getCallingUid())
8950                                     .setMethod("getServiceStateForSlot")
8951                                     .setLogAsInfo(true)
8952                                     .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
8953                                     .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
8954                                     .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
8955                                     .build());
8956             hasFinePermission =
8957                     fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
8958         }
8959 
8960         if (!renounceCoarseLocationAccess) {
8961             LocationAccessPolicy.LocationPermissionResult coarseLocationResult =
8962                     LocationAccessPolicy.checkLocationPermission(mApp,
8963                             new LocationAccessPolicy.LocationPermissionQuery.Builder()
8964                                     .setCallingPackage(callingPackage)
8965                                     .setCallingFeatureId(callingFeatureId)
8966                                     .setCallingPid(Binder.getCallingPid())
8967                                     .setCallingUid(Binder.getCallingUid())
8968                                     .setMethod("getServiceStateForSlot")
8969                                     .setLogAsInfo(true)
8970                                     .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
8971                                     .setMinSdkVersionForFine(Integer.MAX_VALUE)
8972                                     .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
8973                                     .build());
8974             hasCoarsePermission =
8975                     coarseLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
8976         }
8977 
8978         final long identity = Binder.clearCallingIdentity();
8979         try {
8980             SubscriptionInfoInternal subInfo = getSubscriptionManagerService()
8981                     .getSubscriptionInfoInternal(subId);
8982             if (subInfo != null && !subInfo.isActive()) {
8983                 log("getServiceStateForSlot returning null for inactive subId=" + subId);
8984                 return null;
8985             }
8986 
8987             ServiceState ss = phone.getServiceState();
8988             boolean isCallingPackageDataService = phone.getDataServicePackages()
8989                     .contains(callingPackage);
8990 
8991             // Scrub out the location info in ServiceState depending on what level of access
8992             // the caller has.
8993             if (hasFinePermission || isCallingPackageDataService) return ss;
8994             if (hasCoarsePermission) return ss.createLocationInfoSanitizedCopy(false);
8995             return ss.createLocationInfoSanitizedCopy(true);
8996         } finally {
8997             Binder.restoreCallingIdentity(identity);
8998         }
8999     }
9000 
9001     /**
9002      * Returns the URI for the per-account voicemail ringtone set in Phone settings.
9003      *
9004      * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
9005      * voicemail ringtone.
9006      * @return The URI for the ringtone to play when receiving a voicemail from a specific
9007      * PhoneAccount.
9008      */
9009     @Override
getVoicemailRingtoneUri(PhoneAccountHandle accountHandle)9010     public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
9011         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9012                 PackageManager.FEATURE_TELEPHONY_CALLING, "getVoicemailRingtoneUri");
9013 
9014         final long identity = Binder.clearCallingIdentity();
9015         try {
9016             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
9017             if (phone == null) {
9018                 phone = getDefaultPhone();
9019             }
9020 
9021             return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
9022         } finally {
9023             Binder.restoreCallingIdentity(identity);
9024         }
9025     }
9026 
9027     /**
9028      * Sets the per-account voicemail ringtone.
9029      *
9030      * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
9031      * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
9032      *
9033      * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
9034      * voicemail ringtone.
9035      * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
9036      * PhoneAccount.
9037      */
9038     @Override
setVoicemailRingtoneUri(String callingPackage, PhoneAccountHandle phoneAccountHandle, Uri uri)9039     public void setVoicemailRingtoneUri(String callingPackage,
9040             PhoneAccountHandle phoneAccountHandle, Uri uri) {
9041         final Phone defaultPhone = getDefaultPhone();
9042         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
9043         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
9044         if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
9045             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9046                     mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
9047                     "setVoicemailRingtoneUri");
9048         }
9049 
9050         enforceTelephonyFeatureWithException(callingPackage,
9051                 PackageManager.FEATURE_TELEPHONY_CALLING, "setVoicemailRingtoneUri");
9052 
9053         final long identity = Binder.clearCallingIdentity();
9054         try {
9055             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
9056             if (phone == null) {
9057                 phone = defaultPhone;
9058             }
9059             VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
9060         } finally {
9061             Binder.restoreCallingIdentity(identity);
9062         }
9063     }
9064 
9065     /**
9066      * Returns whether vibration is set for voicemail notification in Phone settings.
9067      *
9068      * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
9069      * voicemail vibration setting.
9070      * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
9071      */
9072     @Override
isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle)9073     public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
9074         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9075                 PackageManager.FEATURE_TELEPHONY_CALLING, "isVoicemailVibrationEnabled");
9076 
9077         final long identity = Binder.clearCallingIdentity();
9078         try {
9079             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
9080             if (phone == null) {
9081                 phone = getDefaultPhone();
9082             }
9083 
9084             return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
9085         } finally {
9086             Binder.restoreCallingIdentity(identity);
9087         }
9088     }
9089 
9090     /**
9091      * Sets the per-account voicemail vibration.
9092      *
9093      * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
9094      * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
9095      *
9096      * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
9097      * voicemail vibration setting.
9098      * @param enabled Whether to enable or disable vibration for voicemail notifications from a
9099      * specific PhoneAccount.
9100      */
9101     @Override
setVoicemailVibrationEnabled(String callingPackage, PhoneAccountHandle phoneAccountHandle, boolean enabled)9102     public void setVoicemailVibrationEnabled(String callingPackage,
9103             PhoneAccountHandle phoneAccountHandle, boolean enabled) {
9104         final Phone defaultPhone = getDefaultPhone();
9105         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
9106         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
9107         if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
9108             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9109                     mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
9110                     "setVoicemailVibrationEnabled");
9111         }
9112 
9113         enforceTelephonyFeatureWithException(callingPackage,
9114                 PackageManager.FEATURE_TELEPHONY_CALLING, "setVoicemailVibrationEnabled");
9115 
9116         final long identity = Binder.clearCallingIdentity();
9117         try {
9118             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
9119             if (phone == null) {
9120                 phone = defaultPhone;
9121             }
9122             VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
9123         } finally {
9124             Binder.restoreCallingIdentity(identity);
9125         }
9126     }
9127 
9128     /**
9129      * Make sure either called from same process as self (phone) or IPC caller has read privilege.
9130      *
9131      * @throws SecurityException if the caller does not have the required permission
9132      */
9133     @VisibleForTesting
enforceReadPrivilegedPermission(String message)9134     public void enforceReadPrivilegedPermission(String message) {
9135         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
9136                 message);
9137     }
9138 
9139     /**
9140      * Make sure either called from same process as self (phone) or IPC caller has send SMS
9141      * permission.
9142      *
9143      * @throws SecurityException if the caller does not have the required permission
9144      */
enforceSendSmsPermission()9145     private void enforceSendSmsPermission() {
9146         mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
9147     }
9148 
9149     /**
9150      * Make sure either called from same process as self (phone) or IPC caller has interact across
9151      * users permission.
9152      *
9153      * @throws SecurityException if the caller does not have the required permission
9154      */
enforceInteractAcrossUsersPermission(String message)9155     private void enforceInteractAcrossUsersPermission(String message) {
9156         mApp.enforceCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS, message);
9157     }
9158 
9159     /**
9160      * Make sure called from the package in charge of visual voicemail.
9161      *
9162      * @throws SecurityException if the caller is not the visual voicemail package.
9163      */
enforceVisualVoicemailPackage(String callingPackage, int subId)9164     private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
9165         final long identity = Binder.clearCallingIdentity();
9166         try {
9167             ComponentName componentName =
9168                     RemoteVvmTaskManager.getRemotePackage(mApp, subId);
9169             if (componentName == null) {
9170                 throw new SecurityException(
9171                         "Caller not current active visual voicemail package[null]");
9172             }
9173             String vvmPackage = componentName.getPackageName();
9174             if (!callingPackage.equals(vvmPackage)) {
9175                 throw new SecurityException("Caller not current active visual voicemail package");
9176             }
9177         } finally {
9178             Binder.restoreCallingIdentity(identity);
9179         }
9180     }
9181 
9182     /**
9183      * Return the application ID for the app type.
9184      *
9185      * @param subId the subscription ID that this request applies to.
9186      * @param appType the uicc app type.
9187      * @return Application ID for specificied app type, or null if no uicc.
9188      */
9189     @Override
getAidForAppType(int subId, int appType)9190     public String getAidForAppType(int subId, int appType) {
9191         enforceReadPrivilegedPermission("getAidForAppType");
9192 
9193         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9194                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getAidForAppType");
9195 
9196         Phone phone = getPhone(subId);
9197 
9198         final long identity = Binder.clearCallingIdentity();
9199         try {
9200             if (phone == null) {
9201                 return null;
9202             }
9203             String aid = null;
9204             try {
9205                 UiccCardApplication app = UiccController.getInstance()
9206                         .getUiccPort(phone.getPhoneId()).getApplicationByType(appType);
9207                 if (app == null) return null;
9208                 aid = app.getAid();
9209             } catch (Exception e) {
9210                 Log.e(LOG_TAG, "Not getting aid", e);
9211             }
9212             return aid;
9213         } finally {
9214             Binder.restoreCallingIdentity(identity);
9215         }
9216     }
9217 
9218     /**
9219      * Return the Electronic Serial Number.
9220      *
9221      * @param subId the subscription ID that this request applies to.
9222      * @return ESN or null if error.
9223      */
9224     @Override
getEsn(int subId)9225     public String getEsn(int subId) {
9226         enforceReadPrivilegedPermission("getEsn");
9227         Phone phone = getPhone(subId);
9228 
9229         final long identity = Binder.clearCallingIdentity();
9230         try {
9231             if (phone == null) {
9232                 return null;
9233             }
9234             String esn = null;
9235             try {
9236                 esn = phone.getEsn();
9237             } catch (Exception e) {
9238                 Log.e(LOG_TAG, "Not getting ESN", e);
9239             }
9240             return esn;
9241         } finally {
9242             Binder.restoreCallingIdentity(identity);
9243         }
9244     }
9245 
9246     /**
9247      * Return the Preferred Roaming List Version.
9248      *
9249      * @param subId the subscription ID that this request applies to.
9250      * @return PRLVersion or null if error.
9251      */
9252     @Override
getCdmaPrlVersion(int subId)9253     public String getCdmaPrlVersion(int subId) {
9254         if (mFeatureFlags.cleanupCdma()) return null;
9255 
9256         enforceReadPrivilegedPermission("getCdmaPrlVersion");
9257 
9258         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9259                 PackageManager.FEATURE_TELEPHONY_CDMA, "getCdmaPrlVersion");
9260 
9261         Phone phone = getPhone(subId);
9262 
9263         final long identity = Binder.clearCallingIdentity();
9264         try {
9265             if (phone == null) {
9266                 return null;
9267             }
9268             String cdmaPrlVersion = null;
9269             try {
9270                 cdmaPrlVersion = phone.getCdmaPrlVersion();
9271             } catch (Exception e) {
9272                 Log.e(LOG_TAG, "Not getting PRLVersion", e);
9273             }
9274             return cdmaPrlVersion;
9275         } finally {
9276             Binder.restoreCallingIdentity(identity);
9277         }
9278     }
9279 
9280     /**
9281      * Get snapshot of Telephony histograms
9282      * @return List of Telephony histograms
9283      * @hide
9284      */
9285     @Override
getTelephonyHistograms()9286     public List<TelephonyHistogram> getTelephonyHistograms() {
9287         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9288                 mApp, getDefaultSubscription(), "getTelephonyHistograms");
9289 
9290         final long identity = Binder.clearCallingIdentity();
9291         try {
9292             return RIL.getTelephonyRILTimingHistograms();
9293         } finally {
9294             Binder.restoreCallingIdentity(identity);
9295         }
9296     }
9297 
9298     /**
9299      * {@hide}
9300      * Set the allowed carrier list and the excluded carrier list, indicating the priority between
9301      * the two lists.
9302      * Require system privileges. In the future we may add this to carrier APIs.
9303      *
9304      * @return Integer with the result of the operation, as defined in {@link TelephonyManager}.
9305      */
9306     @Override
9307     @TelephonyManager.SetCarrierRestrictionResult
setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules)9308     public int setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules) {
9309         enforceModifyPermission();
9310 
9311         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9312                 PackageManager.FEATURE_TELEPHONY_CARRIERLOCK, "setAllowedCarriers");
9313 
9314         WorkSource workSource = getWorkSource(Binder.getCallingUid());
9315 
9316         if (carrierRestrictionRules == null) {
9317             throw new NullPointerException("carrier restriction cannot be null");
9318         }
9319 
9320         final long identity = Binder.clearCallingIdentity();
9321         try {
9322             return (int) sendRequest(CMD_SET_ALLOWED_CARRIERS, carrierRestrictionRules,
9323                     workSource);
9324         } finally {
9325             Binder.restoreCallingIdentity(identity);
9326         }
9327     }
9328 
9329     /**
9330      * {@hide}
9331      * Get the allowed carrier list and the excluded carrier list, including the priority between
9332      * the two lists.
9333      * Require system privileges. In the future we may add this to carrier APIs.
9334      *
9335      * @return {@link android.telephony.CarrierRestrictionRules}
9336      */
9337     @Override
getAllowedCarriers()9338     public CarrierRestrictionRules getAllowedCarriers() {
9339         enforceReadPrivilegedPermission("getAllowedCarriers");
9340 
9341         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9342                 PackageManager.FEATURE_TELEPHONY_CARRIERLOCK, "getAllowedCarriers");
9343 
9344         WorkSource workSource = getWorkSource(Binder.getCallingUid());
9345 
9346         final long identity = Binder.clearCallingIdentity();
9347         try {
9348             Object response = sendRequest(CMD_GET_ALLOWED_CARRIERS, null, workSource);
9349             if (response instanceof CarrierRestrictionRules) {
9350                 return (CarrierRestrictionRules) response;
9351             }
9352             // Response is an Exception of some kind,
9353             // which is signalled to the user as a NULL retval
9354             return null;
9355         } catch (Exception e) {
9356             Log.e(LOG_TAG, "getAllowedCarriers. Exception ex=" + e);
9357             return null;
9358         } finally {
9359             Binder.restoreCallingIdentity(identity);
9360         }
9361     }
9362 
9363     /**
9364      * Fetches the carrier restriction status of the device and sends the status to the caller
9365      * through the callback.
9366      *
9367      * @param callback The callback that will be used to send the result.
9368      * @throws SecurityException if the caller does not have the required permission/privileges or
9369      *                           the caller is not allowlisted.
9370      */
9371     @Override
getCarrierRestrictionStatus(IIntegerConsumer callback, String packageName)9372     public void getCarrierRestrictionStatus(IIntegerConsumer callback, String packageName) {
9373         String functionName = "getCarrierRestrictionStatus";
9374         enforceTelephonyFeatureWithException(packageName,
9375                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, functionName);
9376         try {
9377             mApp.enforceCallingOrSelfPermission(
9378                     android.Manifest.permission.READ_BASIC_PHONE_STATE,
9379                     functionName);
9380         } catch (SecurityException e) {
9381             mApp.enforceCallingOrSelfPermission(permission.READ_PHONE_STATE,
9382                     functionName);
9383         }
9384         Set<Integer> carrierIds = validateCallerAndGetCarrierIds(packageName);
9385         if (carrierIds.contains(CarrierAllowListInfo.INVALID_CARRIER_ID)) {
9386             Rlog.e(LOG_TAG, "getCarrierRestrictionStatus: caller is not registered");
9387             throw new SecurityException("Not an authorized caller");
9388         }
9389         final long identity = Binder.clearCallingIdentity();
9390         try {
9391             Consumer<Integer> consumer = FunctionalUtils.ignoreRemoteException(callback::accept);
9392             CallerCallbackInfo callbackInfo = new CallerCallbackInfo(consumer, carrierIds);
9393             sendRequestAsync(CMD_GET_ALLOWED_CARRIERS, callbackInfo);
9394         } finally {
9395             Binder.restoreCallingIdentity(identity);
9396         }
9397     }
9398 
9399     @Override
getShaIdFromAllowList(String pkgName, int carrierId)9400     public List<String> getShaIdFromAllowList(String pkgName, int carrierId) {
9401         enforceReadPrivilegedPermission("checkCarrierRestrictionFileForNoChange");
9402         CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mApp);
9403         return allowListInfo.getShaIdList(pkgName, carrierId);
9404     }
9405 
9406     @VisibleForTesting
validateCallerAndGetCarrierIds(String packageName)9407     public Set<Integer> validateCallerAndGetCarrierIds(String packageName) {
9408         CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mApp);
9409         return allowListInfo.validateCallerAndGetCarrierIds(packageName);
9410     }
9411 
9412     /**
9413      * Action set from carrier signalling broadcast receivers to enable/disable radio
9414      * @param subId the subscription ID that this action applies to.
9415      * @param enabled control enable or disable radio.
9416      * {@hide}
9417      */
9418     @Override
carrierActionSetRadioEnabled(int subId, boolean enabled)9419     public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
9420         enforceModifyPermission();
9421         final Phone phone = getPhone(subId);
9422 
9423         final long identity = Binder.clearCallingIdentity();
9424         if (phone == null) {
9425             loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
9426             return;
9427         }
9428         try {
9429             phone.carrierActionSetRadioEnabled(enabled);
9430         } catch (Exception e) {
9431             Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
9432         } finally {
9433             Binder.restoreCallingIdentity(identity);
9434         }
9435     }
9436 
9437     /**
9438      * Enable or disable Voice over NR (VoNR)
9439      * @param subId the subscription ID that this action applies to.
9440      * @param enabled enable or disable VoNR.
9441      * @return operation result.
9442      */
9443     @Override
setVoNrEnabled(int subId, boolean enabled)9444     public int setVoNrEnabled(int subId, boolean enabled) {
9445         enforceModifyPermission();
9446         final Phone phone = getPhone(subId);
9447 
9448         final long identity = Binder.clearCallingIdentity();
9449         if (phone == null) {
9450             loge("setVoNrEnabled fails with no phone object for subId: " + subId);
9451             return TelephonyManager.ENABLE_VONR_RADIO_NOT_AVAILABLE;
9452         }
9453 
9454         WorkSource workSource = getWorkSource(Binder.getCallingUid());
9455         try {
9456             int result = (int) sendRequest(CMD_ENABLE_VONR, enabled, subId,
9457                     workSource);
9458             if (DBG) log("setVoNrEnabled result: " + result);
9459 
9460             if (result == TelephonyManager.ENABLE_VONR_SUCCESS) {
9461                 if (DBG) {
9462                     log("Set VoNR settings in siminfo db; subId=" + subId + ", value:" + enabled);
9463                 }
9464                 SubscriptionManager.setSubscriptionProperty(
9465                         subId, SubscriptionManager.NR_ADVANCED_CALLING_ENABLED,
9466                         (enabled ? "1" : "0"));
9467             }
9468 
9469             return result;
9470         } finally {
9471             Binder.restoreCallingIdentity(identity);
9472         }
9473     }
9474 
9475     /**
9476      * Is voice over NR enabled
9477      * @return true if VoNR is enabled else false
9478      */
9479     @Override
isVoNrEnabled(int subId)9480     public boolean isVoNrEnabled(int subId) {
9481         enforceReadPrivilegedPermission("isVoNrEnabled");
9482         WorkSource workSource = getWorkSource(Binder.getCallingUid());
9483         final long identity = Binder.clearCallingIdentity();
9484         try {
9485             boolean isEnabled = (boolean) sendRequest(CMD_IS_VONR_ENABLED,
9486                     null, subId, workSource);
9487             if (DBG) log("isVoNrEnabled: " + isEnabled);
9488             return isEnabled;
9489         } finally {
9490             Binder.restoreCallingIdentity(identity);
9491         }
9492     }
9493 
9494     /**
9495      * Action set from carrier signalling broadcast receivers to start/stop reporting the default
9496      * network status based on which carrier apps could apply actions accordingly,
9497      * enable/disable default url handler for example.
9498      *
9499      * @param subId the subscription ID that this action applies to.
9500      * @param report control start/stop reporting the default network status.
9501      * {@hide}
9502      */
9503     @Override
carrierActionReportDefaultNetworkStatus(int subId, boolean report)9504     public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
9505         enforceModifyPermission();
9506 
9507         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9508                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS,
9509                 "carrierActionReportDefaultNetworkStatus");
9510 
9511         final Phone phone = getPhone(subId);
9512 
9513         final long identity = Binder.clearCallingIdentity();
9514         if (phone == null) {
9515             loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
9516             return;
9517         }
9518         try {
9519             phone.carrierActionReportDefaultNetworkStatus(report);
9520         } catch (Exception e) {
9521             Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
9522         } finally {
9523             Binder.restoreCallingIdentity(identity);
9524         }
9525     }
9526 
9527     /**
9528      * Action set from carrier signalling broadcast receivers to reset all carrier actions
9529      * @param subId the subscription ID that this action applies to.
9530      * {@hide}
9531      */
9532     @Override
carrierActionResetAll(int subId)9533     public void carrierActionResetAll(int subId) {
9534         enforceModifyPermission();
9535 
9536         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9537                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "carrierActionResetAll");
9538 
9539         final Phone phone = getPhone(subId);
9540         if (phone == null) {
9541             loge("carrierAction: ResetAll fails with invalid sibId: " + subId);
9542             return;
9543         }
9544         try {
9545             phone.carrierActionResetAll();
9546         } catch (Exception e) {
9547             Log.e(LOG_TAG, "carrierAction: ResetAll fails. Exception ex=" + e);
9548         }
9549     }
9550 
9551     /**
9552      * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
9553      * bug report is being generated.
9554      */
9555     @Override
dump(FileDescriptor fd, PrintWriter writer, String[] args)9556     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
9557         if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
9558                 != PackageManager.PERMISSION_GRANTED) {
9559             writer.println("Permission Denial: can't dump Phone from pid="
9560                     + Binder.getCallingPid()
9561                     + ", uid=" + Binder.getCallingUid()
9562                     + "without permission "
9563                     + android.Manifest.permission.DUMP);
9564             return;
9565         }
9566         try {
9567             DumpsysHandler.dump(mApp, fd, writer, args);
9568         } catch (Exception e) {
9569             writer.println("Failed to dump phone information: " + e);
9570         }
9571     }
9572 
9573     @Override
handleShellCommand(@onNull ParcelFileDescriptor in, @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, @NonNull String[] args)9574     public int handleShellCommand(@NonNull ParcelFileDescriptor in,
9575             @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
9576             @NonNull String[] args) {
9577         return new TelephonyShellCommand(this, getDefaultPhone().getContext()).exec(
9578                 this, in.getFileDescriptor(), out.getFileDescriptor(),
9579                 err.getFileDescriptor(), args);
9580     }
9581 
9582     /**
9583      * Policy control of data connection with reason {@@TelephonyManager.DataEnabledReason}
9584      * @param subId Subscription index
9585      * @param reason The reason the data enable change is taking place.
9586      * @param enabled True if enabling the data, otherwise disabling.
9587      * @param callingPackage The package that changed the data enabled state.
9588      * @hide
9589      */
9590     @Override
setDataEnabledForReason(int subId, @TelephonyManager.DataEnabledReason int reason, boolean enabled, String callingPackage)9591     public void setDataEnabledForReason(int subId, @TelephonyManager.DataEnabledReason int reason,
9592             boolean enabled, String callingPackage) {
9593         if (reason == TelephonyManager.DATA_ENABLED_REASON_USER
9594                 || reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
9595             try {
9596                 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
9597                         mApp, subId, "setDataEnabledForReason");
9598             } catch (SecurityException se) {
9599                 enforceModifyPermission();
9600             }
9601         } else {
9602             enforceModifyPermission();
9603         }
9604 
9605         enforceTelephonyFeatureWithException(callingPackage,
9606                 PackageManager.FEATURE_TELEPHONY_DATA, "setDataEnabledForReason");
9607 
9608         int callingUid = Binder.getCallingUid();
9609         final long identity = Binder.clearCallingIdentity();
9610         try {
9611             if (reason == TelephonyManager.DATA_ENABLED_REASON_USER && enabled
9612                     && null != callingPackage && opEnableMobileDataByUser()) {
9613                 mAppOps.noteOpNoThrow(AppOpsManager.OPSTR_ENABLE_MOBILE_DATA_BY_USER,
9614                         callingUid, callingPackage, null, null);
9615             }
9616             Phone phone = getPhone(subId);
9617             if (phone != null) {
9618                 if (reason == TelephonyManager.DATA_ENABLED_REASON_CARRIER) {
9619                     phone.carrierActionSetMeteredApnsEnabled(enabled);
9620                 } else if (phone.getDataSettingsManager() != null) {
9621                     phone.getDataSettingsManager().setDataEnabled(
9622                             reason, enabled, callingPackage);
9623                 }
9624             }
9625         } finally {
9626             Binder.restoreCallingIdentity(identity);
9627         }
9628     }
9629 
9630     /**
9631      * Get Client request stats
9632      * @return List of Client Request Stats
9633      * @hide
9634      */
9635     @Override
getClientRequestStats(String callingPackage, String callingFeatureId, int subId)9636     public List<ClientRequestStats> getClientRequestStats(String callingPackage,
9637             String callingFeatureId, int subId) {
9638         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
9639                 mApp, subId, callingPackage, callingFeatureId, "getClientRequestStats")) {
9640             return null;
9641         }
9642         Phone phone = getPhone(subId);
9643 
9644         final long identity = Binder.clearCallingIdentity();
9645         try {
9646             if (phone != null) {
9647                 return phone.getClientRequestStats();
9648             }
9649 
9650             return null;
9651         } finally {
9652             Binder.restoreCallingIdentity(identity);
9653         }
9654     }
9655 
getWorkSource(int uid)9656     private WorkSource getWorkSource(int uid) {
9657         PackageManager pm;
9658         if (mFeatureFlags.hsumPackageManager()) {
9659             pm = mApp.getBaseContext().createContextAsUser(UserHandle.getUserHandleForUid(uid), 0)
9660                     .getPackageManager();
9661         } else {
9662             pm = mApp.getPackageManager();
9663         }
9664 
9665         String packageName = pm.getNameForUid(uid);
9666         if (UserHandle.isSameApp(uid, Process.ROOT_UID) && packageName == null) {
9667             // Downstream WorkSource attribution inside the RIL requires both a UID and package name
9668             // to be set for wakelock tracking, otherwise RIL requests fail with a runtime
9669             // exception. ROOT_UID seems not to have a valid package name returned by
9670             // PackageManager, so just fake it here to avoid issues when running telephony shell
9671             // commands that plumb through the RIL as root, like so:
9672             // $ adb root
9673             // $ adb shell cmd phone ...
9674             packageName = "root";
9675         }
9676         return new WorkSource(uid, packageName);
9677     }
9678 
9679     /**
9680      * Set SIM card power state.
9681      *
9682      * @param slotIndex SIM slot id.
9683      * @param state  State of SIM (power down, power up, pass through)
9684      * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
9685      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
9686      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
9687      *
9688      **/
9689     @Override
setSimPowerStateForSlot(int slotIndex, int state)9690     public void setSimPowerStateForSlot(int slotIndex, int state) {
9691         enforceModifyPermission();
9692 
9693         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9694                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "setSimPowerStateForSlot");
9695 
9696         Phone phone = PhoneFactory.getPhone(slotIndex);
9697 
9698         WorkSource workSource = getWorkSource(Binder.getCallingUid());
9699 
9700         final long identity = Binder.clearCallingIdentity();
9701         try {
9702             if (phone != null) {
9703                 phone.setSimPowerState(state, null, workSource);
9704             }
9705         } finally {
9706             Binder.restoreCallingIdentity(identity);
9707         }
9708     }
9709 
9710     /**
9711      * Set SIM card power state.
9712      *
9713      * @param slotIndex SIM slot id.
9714      * @param state  State of SIM (power down, power up, pass through)
9715      * @param callback  callback to trigger after success or failure
9716      * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
9717      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
9718      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
9719      *
9720      **/
9721     @Override
setSimPowerStateForSlotWithCallback(int slotIndex, int state, IIntegerConsumer callback)9722     public void setSimPowerStateForSlotWithCallback(int slotIndex, int state,
9723             IIntegerConsumer callback) {
9724         enforceModifyPermission();
9725 
9726         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9727                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
9728                 "setSimPowerStateForSlotWithCallback");
9729 
9730         Phone phone = PhoneFactory.getPhone(slotIndex);
9731 
9732         WorkSource workSource = getWorkSource(Binder.getCallingUid());
9733 
9734         final long identity = Binder.clearCallingIdentity();
9735         try {
9736             if (phone != null) {
9737                 Pair<Integer, IIntegerConsumer> arguments = Pair.create(state, callback);
9738                 sendRequestAsync(CMD_SET_SIM_POWER, arguments, phone, workSource);
9739             }
9740         } finally {
9741             Binder.restoreCallingIdentity(identity);
9742         }
9743     }
9744 
isUssdApiAllowed(int subId)9745     private boolean isUssdApiAllowed(int subId) {
9746         CarrierConfigManager configManager =
9747                 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
9748         if (configManager == null) {
9749             return false;
9750         }
9751         PersistableBundle pb = configManager.getConfigForSubId(subId);
9752         if (pb == null) {
9753             return false;
9754         }
9755         return pb.getBoolean(
9756                 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
9757     }
9758 
9759     /**
9760      * Check if phone is in emergency callback mode.
9761      * @return true if phone is in emergency callback mode
9762      * @param subId sub Id, but the check is in fact irrlevant to sub Id.
9763      */
9764     @Override
getEmergencyCallbackMode(int subId)9765     public boolean getEmergencyCallbackMode(int subId) {
9766         enforceReadPrivilegedPermission("getEmergencyCallbackMode");
9767 
9768         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9769                 PackageManager.FEATURE_TELEPHONY_CALLING, "getEmergencyCallbackMode");
9770 
9771         final long identity = Binder.clearCallingIdentity();
9772         try {
9773             return getPhoneFromSubIdOrDefault(subId).isInEcm();
9774         } finally {
9775             Binder.restoreCallingIdentity(identity);
9776         }
9777     }
9778 
9779     /**
9780      * Get the current signal strength information for the given subscription.
9781      * Because this information is not updated when the device is in a low power state
9782      * it should not be relied-upon to be current.
9783      * @param subId Subscription index
9784      * @return the most recent cached signal strength info from the modem
9785      */
9786     @Override
getSignalStrength(int subId)9787     public SignalStrength getSignalStrength(int subId) {
9788         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9789                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getSignalStrength");
9790 
9791         final long identity = Binder.clearCallingIdentity();
9792         try {
9793             Phone p = getPhone(subId);
9794             if (p == null) {
9795                 return null;
9796             }
9797 
9798             return p.getSignalStrength();
9799         } finally {
9800             Binder.restoreCallingIdentity(identity);
9801         }
9802     }
9803 
9804     /**
9805      * Get the current modem radio state for the given slot.
9806      * @param slotIndex slot index.
9807      * @param callingPackage the name of the package making the call.
9808      * @param callingFeatureId The feature in the package.
9809      * @return the current radio power state from the modem
9810      */
9811     @Override
getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId)9812     public int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId) {
9813         Phone phone = PhoneFactory.getPhone(slotIndex);
9814         if (phone != null) {
9815             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, phone.getSubId(),
9816                     callingPackage, callingFeatureId, "getRadioPowerState")) {
9817                 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
9818             }
9819 
9820             enforceTelephonyFeatureWithException(callingPackage,
9821                     PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getRadioPowerState");
9822 
9823             final long identity = Binder.clearCallingIdentity();
9824             try {
9825                 return phone.getRadioPowerState();
9826             } finally {
9827                 Binder.restoreCallingIdentity(identity);
9828             }
9829         }
9830         return TelephonyManager.RADIO_POWER_UNAVAILABLE;
9831     }
9832 
9833     /**
9834      * Checks if data roaming is enabled on the subscription with id {@code subId}.
9835      *
9836      * <p>Requires one of the following permissions:
9837      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
9838      * {@link android.Manifest.permission#READ_BASIC_PHONE_STATE},
9839      * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
9840      * privileges.
9841      *
9842      * @param subId subscription id
9843      * @return {@code true} if data roaming is enabled on this subscription, otherwise return
9844      * {@code false}.
9845      */
9846     @Override
isDataRoamingEnabled(int subId)9847     public boolean isDataRoamingEnabled(int subId) {
9848         String functionName = "isDataRoamingEnabled";
9849         try {
9850             try {
9851                 mApp.enforceCallingOrSelfPermission(
9852                         android.Manifest.permission.ACCESS_NETWORK_STATE,
9853                         functionName);
9854             } catch (SecurityException e) {
9855                 mApp.enforceCallingOrSelfPermission(
9856                         permission.READ_BASIC_PHONE_STATE, functionName);
9857             }
9858         } catch (SecurityException e) {
9859             TelephonyPermissions.enforceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
9860                     mApp, subId, functionName);
9861         }
9862 
9863         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9864                 PackageManager.FEATURE_TELEPHONY_DATA, "isDataRoamingEnabled");
9865 
9866         boolean isEnabled = false;
9867         final long identity = Binder.clearCallingIdentity();
9868         try {
9869             Phone phone = getPhone(subId);
9870             isEnabled =  phone != null ? phone.getDataRoamingEnabled() : false;
9871         } finally {
9872             Binder.restoreCallingIdentity(identity);
9873         }
9874         return isEnabled;
9875     }
9876 
9877 
9878     /**
9879      * Enables/Disables the data roaming on the subscription with id {@code subId}.
9880      *
9881      * <p> Requires permission:
9882      * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
9883      * privileges.
9884      *
9885      * @param subId subscription id
9886      * @param isEnabled {@code true} means enable, {@code false} means disable.
9887      */
9888     @Override
setDataRoamingEnabled(int subId, boolean isEnabled)9889     public void setDataRoamingEnabled(int subId, boolean isEnabled) {
9890         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
9891                 mApp, subId, "setDataRoamingEnabled");
9892 
9893         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9894                 PackageManager.FEATURE_TELEPHONY_DATA, "setDataRoamingEnabled");
9895 
9896         final long identity = Binder.clearCallingIdentity();
9897         try {
9898             Phone phone = getPhone(subId);
9899             if (phone != null) {
9900                 phone.setDataRoamingEnabled(isEnabled);
9901             }
9902         } finally {
9903             Binder.restoreCallingIdentity(identity);
9904         }
9905     }
9906 
9907     @Override
isManualNetworkSelectionAllowed(int subId)9908     public boolean isManualNetworkSelectionAllowed(int subId) {
9909         TelephonyPermissions
9910                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
9911                         mApp, subId, "isManualNetworkSelectionAllowed");
9912 
9913         enforceTelephonyFeatureWithException(getCurrentPackageName(),
9914                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "isManualNetworkSelectionAllowed");
9915 
9916         boolean isAllowed = true;
9917         final long identity = Binder.clearCallingIdentity();
9918         try {
9919             Phone phone = getPhone(subId);
9920             if (phone != null) {
9921                 isAllowed = phone.isCspPlmnEnabled();
9922             }
9923         } finally {
9924             Binder.restoreCallingIdentity(identity);
9925         }
9926         return isAllowed;
9927     }
9928 
haveCarrierPrivilegeAccess(UiccPort port, String callingPackage)9929     private boolean haveCarrierPrivilegeAccess(UiccPort port, String callingPackage) {
9930         UiccProfile profile = port.getUiccProfile();
9931         if (profile == null) {
9932             return false;
9933         }
9934         Phone phone = PhoneFactory.getPhone(profile.getPhoneId());
9935         if (phone == null) {
9936             return false;
9937         }
9938         CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
9939         return cpt != null && cpt.getCarrierPrivilegeStatusForPackage(callingPackage)
9940                 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
9941     }
9942 
9943     @Override
getUiccCardsInfo(String callingPackage)9944     public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
9945         // Verify that the callingPackage belongs to the calling UID
9946         mApp.getSystemService(AppOpsManager.class)
9947                 .checkPackage(Binder.getCallingUid(), callingPackage);
9948 
9949         boolean hasReadPermission = false;
9950         boolean isIccIdAccessRestricted = false;
9951         try {
9952             enforceReadPrivilegedPermission("getUiccCardsInfo");
9953             hasReadPermission = true;
9954         } catch (SecurityException e) {
9955             // even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
9956             // has carrier privileges on an active UICC
9957             if (checkCarrierPrivilegesForPackageAnyPhoneWithPermission(callingPackage)
9958                     != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
9959                 throw new SecurityException("Caller does not have permission.");
9960             }
9961         }
9962 
9963         enforceTelephonyFeatureWithException(callingPackage,
9964                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getUiccCardsInfo");
9965 
9966         // checking compatibility, if calling app's target SDK is T and beyond.
9967         if (CompatChanges.isChangeEnabled(GET_API_SIGNATURES_FROM_UICC_PORT_INFO,
9968                 Binder.getCallingUid())) {
9969             isIccIdAccessRestricted = true;
9970         }
9971         final long identity = Binder.clearCallingIdentity();
9972         try {
9973             UiccController uiccController = UiccController.getInstance();
9974             ArrayList<UiccCardInfo> cardInfos = uiccController.getAllUiccCardInfos();
9975             if (hasReadPermission) {
9976                 return cardInfos;
9977             }
9978 
9979             // Remove private info if the caller doesn't have access
9980             ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
9981             for (UiccCardInfo cardInfo : cardInfos) {
9982                 //setting the value after compatibility check
9983                 cardInfo.setIccIdAccessRestricted(isIccIdAccessRestricted);
9984                 // For an inactive eUICC, the UiccCard will be null even though the UiccCardInfo
9985                 // is available
9986                 UiccCard card = uiccController.getUiccCardForSlot(cardInfo.getPhysicalSlotIndex());
9987                 if (card == null) {
9988                     // assume no access if the card is unavailable
9989                     filteredInfos.add(getUiccCardInfoUnPrivileged(cardInfo));
9990                     continue;
9991                 }
9992                 Collection<UiccPortInfo> portInfos = cardInfo.getPorts();
9993                 if (portInfos.isEmpty()) {
9994                     filteredInfos.add(getUiccCardInfoUnPrivileged(cardInfo));
9995                     continue;
9996                 }
9997                 List<UiccPortInfo> uiccPortInfos = new  ArrayList<>();
9998                 for (UiccPortInfo portInfo : portInfos) {
9999                     UiccPort port = uiccController.getUiccPortForSlot(
10000                             cardInfo.getPhysicalSlotIndex(), portInfo.getPortIndex());
10001                     if (port == null) {
10002                         // assume no access if port is null
10003                         uiccPortInfos.add(getUiccPortInfoUnPrivileged(portInfo));
10004                         continue;
10005                     }
10006                     if (haveCarrierPrivilegeAccess(port, callingPackage)) {
10007                         uiccPortInfos.add(portInfo);
10008                     } else {
10009                         uiccPortInfos.add(getUiccPortInfoUnPrivileged(portInfo));
10010                     }
10011                 }
10012                 filteredInfos.add(new UiccCardInfo(
10013                         cardInfo.isEuicc(),
10014                         cardInfo.getCardId(),
10015                         null,
10016                         cardInfo.getPhysicalSlotIndex(),
10017                         cardInfo.isRemovable(),
10018                         cardInfo.isMultipleEnabledProfilesSupported(),
10019                         uiccPortInfos));
10020             }
10021             return filteredInfos;
10022         } finally {
10023             Binder.restoreCallingIdentity(identity);
10024         }
10025     }
10026 
10027     /**
10028      * Returns a copy of the UiccCardinfo with the EID and ICCID set to null. These values are
10029      * generally private and require carrier privileges to view.
10030      *
10031      * @hide
10032      */
10033     @NonNull
getUiccCardInfoUnPrivileged(UiccCardInfo cardInfo)10034     public UiccCardInfo getUiccCardInfoUnPrivileged(UiccCardInfo cardInfo) {
10035         List<UiccPortInfo> portinfo = new  ArrayList<>();
10036         for (UiccPortInfo portinfos : cardInfo.getPorts()) {
10037             portinfo.add(getUiccPortInfoUnPrivileged(portinfos));
10038         }
10039         return new UiccCardInfo(
10040                 cardInfo.isEuicc(),
10041                 cardInfo.getCardId(),
10042                 null,
10043                 cardInfo.getPhysicalSlotIndex(),
10044                 cardInfo.isRemovable(),
10045                 cardInfo.isMultipleEnabledProfilesSupported(),
10046                 portinfo
10047         );
10048     }
10049 
10050     /**
10051      * @hide
10052      * @return a copy of the UiccPortInfo with ICCID set to {@link UiccPortInfo#ICCID_REDACTED}.
10053      * These values are generally private and require carrier privileges to view.
10054      */
10055     @NonNull
getUiccPortInfoUnPrivileged(UiccPortInfo portInfo)10056     public UiccPortInfo getUiccPortInfoUnPrivileged(UiccPortInfo portInfo) {
10057         return new UiccPortInfo(
10058                 UiccPortInfo.ICCID_REDACTED,
10059                 portInfo.getPortIndex(),
10060                 portInfo.getLogicalSlotIndex(),
10061                 portInfo.isActive()
10062         );
10063     }
10064     @Override
getUiccSlotsInfo(String callingPackage)10065     public UiccSlotInfo[] getUiccSlotsInfo(String callingPackage) {
10066         // Verify that the callingPackage belongs to the calling UID
10067         mApp.getSystemService(AppOpsManager.class)
10068                 .checkPackage(Binder.getCallingUid(), callingPackage);
10069 
10070         boolean isLogicalSlotAccessRestricted = false;
10071 
10072         // This will make sure caller has the READ_PRIVILEGED_PHONE_STATE. Do not remove this as
10073         // we are reading iccId which is PII data.
10074         enforceReadPrivilegedPermission("getUiccSlotsInfo");
10075 
10076         enforceTelephonyFeatureWithException(callingPackage,
10077                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getUiccSlotsInfo");
10078 
10079         // checking compatibility, if calling app's target SDK is T and beyond.
10080         if (CompatChanges.isChangeEnabled(GET_API_SIGNATURES_FROM_UICC_PORT_INFO,
10081                 Binder.getCallingUid())) {
10082             isLogicalSlotAccessRestricted  = true;
10083         }
10084         final long identity = Binder.clearCallingIdentity();
10085         try {
10086             UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
10087             if (slots == null || slots.length == 0) {
10088                 Rlog.i(LOG_TAG, "slots is null or empty.");
10089                 return null;
10090             }
10091             UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
10092             for (int i = 0; i < slots.length; i++) {
10093                 UiccSlot slot = slots[i];
10094                 if (slot == null) {
10095                     continue;
10096                 }
10097 
10098                 String cardId;
10099                 UiccCard card = slot.getUiccCard();
10100                 if (card != null) {
10101                     cardId = card.getCardId();
10102                 } else {
10103                     cardId = slot.getEid();
10104                     if (TextUtils.isEmpty(cardId)) {
10105                         // If cardId is null, use iccId of default port as cardId.
10106                         cardId = slot.getIccId(TelephonyManager.DEFAULT_PORT_INDEX);
10107                     }
10108                 }
10109 
10110                 if (cardId != null) {
10111                     // if cardId is an ICCID, strip off trailing Fs before exposing to user
10112                     // if cardId is an EID, it's all digits so this is fine
10113                     cardId = IccUtils.stripTrailingFs(cardId);
10114                 }
10115 
10116                 int cardState = 0;
10117                 switch (slot.getCardState()) {
10118                     case CARDSTATE_ABSENT:
10119                         cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
10120                         break;
10121                     case CARDSTATE_PRESENT:
10122                         cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
10123                         break;
10124                     case CARDSTATE_ERROR:
10125                         cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
10126                         break;
10127                     case CARDSTATE_RESTRICTED:
10128                         cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
10129                         break;
10130                     default:
10131                         break;
10132 
10133                 }
10134                 List<UiccPortInfo> portInfos = new ArrayList<>();
10135                 int[] portIndexes = slot.getPortList();
10136                 for (int portIdx : portIndexes) {
10137                     String iccId = IccUtils.stripTrailingFs(getIccId(slot, portIdx,
10138                             callingPackage, /* hasReadPermission= */ true));
10139                     portInfos.add(new UiccPortInfo(iccId, portIdx,
10140                             slot.getPhoneIdFromPortIndex(portIdx), slot.isPortActive(portIdx)));
10141                 }
10142                 infos[i] = new UiccSlotInfo(
10143                         slot.isEuicc(),
10144                         cardId,
10145                         cardState,
10146                         slot.isExtendedApduSupported(),
10147                         slot.isRemovable(), portInfos);
10148                 //setting the value after compatibility check
10149                 infos[i].setLogicalSlotAccessRestricted(isLogicalSlotAccessRestricted);
10150             }
10151             return infos;
10152         } finally {
10153             Binder.restoreCallingIdentity(identity);
10154         }
10155     }
10156 
10157     /* Returns null if doesn't have read permission or carrier privilege access. */
getIccId(UiccSlot slot, int portIndex, String callingPackage, boolean hasReadPermission)10158     private String getIccId(UiccSlot slot, int portIndex, String callingPackage,
10159             boolean hasReadPermission) {
10160         String iccId = slot.getIccId(portIndex);
10161         if (hasReadPermission) { // if has read permission
10162             return iccId;
10163         } else {
10164             if (slot.getUiccCard() != null && slot.getUiccCard().getUiccPort(portIndex) != null) {
10165                 UiccPort port = slot.getUiccCard().getUiccPort(portIndex);
10166                 // if no read permission, checking carrier privilege access
10167                 if (haveCarrierPrivilegeAccess(port, callingPackage)) {
10168                     return iccId;
10169                 }
10170             }
10171         }
10172         // No read permission or carrier privilege access.
10173         return UiccPortInfo.ICCID_REDACTED;
10174     }
10175 
10176     @Override
10177     @Deprecated
switchSlots(int[] physicalSlots)10178     public boolean switchSlots(int[] physicalSlots) {
10179         enforceModifyPermission();
10180 
10181         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10182                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "switchSlots");
10183 
10184         final long identity = Binder.clearCallingIdentity();
10185         try {
10186             List<UiccSlotMapping> slotMappings = new ArrayList<>();
10187             for (int i = 0; i < physicalSlots.length; i++) {
10188                 // Deprecated API, hence MEP is not supported. Adding default portIndex 0.
10189                 slotMappings.add(new UiccSlotMapping(TelephonyManager.DEFAULT_PORT_INDEX,
10190                         physicalSlots[i], i));
10191             }
10192             return (Boolean) sendRequest(CMD_SWITCH_SLOTS, slotMappings);
10193         } finally {
10194             Binder.restoreCallingIdentity(identity);
10195         }
10196     }
10197 
10198     @Override
10199     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setSimSlotMapping(@onNull List<UiccSlotMapping> slotMapping)10200     public boolean setSimSlotMapping(@NonNull List<UiccSlotMapping> slotMapping) {
10201         enforceModifyPermission();
10202 
10203         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10204                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "setSimSlotMapping");
10205 
10206         final long identity = Binder.clearCallingIdentity();
10207         try {
10208             return (Boolean) sendRequest(CMD_SWITCH_SLOTS, slotMapping);
10209         } finally {
10210             Binder.restoreCallingIdentity(identity);
10211         }
10212     }
10213 
10214     @Override
getCardIdForDefaultEuicc(int subId, String callingPackage)10215     public int getCardIdForDefaultEuicc(int subId, String callingPackage) {
10216         enforceTelephonyFeatureWithException(callingPackage,
10217                 PackageManager.FEATURE_TELEPHONY_EUICC, "getCardIdForDefaultEuicc");
10218 
10219         final long identity = Binder.clearCallingIdentity();
10220         try {
10221             return UiccController.getInstance().getCardIdForDefaultEuicc();
10222         } finally {
10223             Binder.restoreCallingIdentity(identity);
10224         }
10225     }
10226 
10227     /**
10228      * A test API to reload the UICC profile.
10229      *
10230      * <p>Requires that the calling app has permission
10231      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
10232      * @hide
10233      */
10234     @Override
refreshUiccProfile(int subId)10235     public void refreshUiccProfile(int subId) {
10236         enforceModifyPermission();
10237 
10238         final long identity = Binder.clearCallingIdentity();
10239         try {
10240             Phone phone = getPhone(subId);
10241             if (phone == null) {
10242                 return;
10243             }
10244             UiccPort uiccPort = phone.getUiccPort();
10245             if (uiccPort == null) {
10246                 return;
10247             }
10248             UiccProfile uiccProfile = uiccPort.getUiccProfile();
10249             if (uiccProfile == null) {
10250                 return;
10251             }
10252             uiccProfile.refresh();
10253         } finally {
10254             Binder.restoreCallingIdentity(identity);
10255         }
10256     }
10257 
10258     /**
10259      * Returns false if the mobile data is disabled by default, otherwise return true.
10260      */
getDefaultDataEnabled()10261     private boolean getDefaultDataEnabled() {
10262         return TelephonyProperties.mobile_data().orElse(true);
10263     }
10264 
10265     /**
10266      * Returns the default network type for the given {@code subId}, if the default network type is
10267      * not set, return {@link Phone#PREFERRED_NT_MODE}.
10268      */
getDefaultNetworkType(int subId)10269     private int getDefaultNetworkType(int subId) {
10270         List<Integer> list = TelephonyProperties.default_network();
10271         int phoneId = SubscriptionManager.getPhoneId(subId);
10272         if (phoneId >= 0 && phoneId < list.size() && list.get(phoneId) != null) {
10273             return list.get(phoneId);
10274         }
10275         return Phone.PREFERRED_NT_MODE;
10276     }
10277 
10278     @Override
setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn)10279     public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
10280             gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn) {
10281         enforceModifyPermission();
10282 
10283         final long identity = Binder.clearCallingIdentity();
10284         try {
10285             final Phone phone = getPhone(subId);
10286             if (phone == null) {
10287                 loge("setCarrierTestOverride fails with invalid subId: " + subId);
10288                 return;
10289             }
10290             CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
10291             if (cpt != null) {
10292                 cpt.setTestOverrideCarrierPrivilegeRules(carrierPrivilegeRules);
10293             }
10294             // TODO(b/211796398): remove the legacy logic below once CPT migration is done.
10295             phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn,
10296                     carrierPrivilegeRules, apn);
10297             if (carrierPrivilegeRules == null) {
10298                 mCarrierPrivilegeTestOverrideSubIds.remove(subId);
10299             } else {
10300                 mCarrierPrivilegeTestOverrideSubIds.add(subId);
10301             }
10302         } finally {
10303             Binder.restoreCallingIdentity(identity);
10304         }
10305     }
10306 
10307     @Override
setCarrierServicePackageOverride( int subId, String carrierServicePackage, String callingPackage)10308     public void setCarrierServicePackageOverride(
10309             int subId, String carrierServicePackage, String callingPackage) {
10310         TelephonyPermissions.enforceShellOnly(
10311                 Binder.getCallingUid(), "setCarrierServicePackageOverride");
10312 
10313         final long identity = Binder.clearCallingIdentity();
10314         try {
10315             final Phone phone = getPhone(subId);
10316             if (phone == null || phone.getSubId() != subId) {
10317                 loge("setCarrierServicePackageOverride fails with invalid subId: " + subId);
10318                 throw new IllegalArgumentException("No phone for subid");
10319             }
10320             CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
10321             if (cpt == null) {
10322                 loge("setCarrierServicePackageOverride failed with no CPT for phone");
10323                 throw new IllegalStateException("No CPT for phone");
10324             }
10325             cpt.setTestOverrideCarrierServicePackage(carrierServicePackage);
10326         } finally {
10327             Binder.restoreCallingIdentity(identity);
10328         }
10329     }
10330 
10331     @Override
getCarrierIdListVersion(int subId)10332     public int getCarrierIdListVersion(int subId) {
10333         enforceReadPrivilegedPermission("getCarrierIdListVersion");
10334 
10335         final long identity = Binder.clearCallingIdentity();
10336         try {
10337             final Phone phone = getPhone(subId);
10338             if (phone == null) {
10339                 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
10340                 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
10341             }
10342             return phone.getCarrierIdListVersion();
10343         } finally {
10344             Binder.restoreCallingIdentity(identity);
10345         }
10346     }
10347 
10348     @Override
getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage, String callingFeatureId)10349     public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage,
10350             String callingFeatureId) {
10351         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
10352                 mApp, subId, callingPackage, callingFeatureId,
10353                 "getNumberOfModemsWithSimultaneousDataConnections")) {
10354             return -1;
10355         }
10356 
10357         final long identity = Binder.clearCallingIdentity();
10358         try {
10359             return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
10360         } finally {
10361             Binder.restoreCallingIdentity(identity);
10362         }
10363     }
10364 
10365     @Override
getCdmaRoamingMode(int subId)10366     public int getCdmaRoamingMode(int subId) {
10367         if (mFeatureFlags.cleanupCdma()) return TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
10368 
10369         TelephonyPermissions
10370                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
10371                         mApp, subId, "getCdmaRoamingMode");
10372 
10373         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10374                 PackageManager.FEATURE_TELEPHONY_CDMA, "getCdmaRoamingMode");
10375 
10376         final long identity = Binder.clearCallingIdentity();
10377         try {
10378             return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
10379         } finally {
10380             Binder.restoreCallingIdentity(identity);
10381         }
10382     }
10383 
10384     @Override
setCdmaRoamingMode(int subId, int mode)10385     public boolean setCdmaRoamingMode(int subId, int mode) {
10386         if (mFeatureFlags.cleanupCdma()) return false;
10387 
10388         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
10389                 mApp, subId, "setCdmaRoamingMode");
10390 
10391         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10392                 PackageManager.FEATURE_TELEPHONY_CDMA, "setCdmaRoamingMode");
10393 
10394         final long identity = Binder.clearCallingIdentity();
10395         try {
10396             return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
10397         } finally {
10398             Binder.restoreCallingIdentity(identity);
10399         }
10400     }
10401 
10402     @Override
getCdmaSubscriptionMode(int subId)10403     public int getCdmaSubscriptionMode(int subId) {
10404         if (mFeatureFlags.cleanupCdma()) return TelephonyManager.CDMA_SUBSCRIPTION_UNKNOWN;
10405 
10406         TelephonyPermissions
10407                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
10408                         mApp, subId, "getCdmaSubscriptionMode");
10409 
10410         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10411                 PackageManager.FEATURE_TELEPHONY_CDMA, "getCdmaSubscriptionMode");
10412 
10413         final long identity = Binder.clearCallingIdentity();
10414         try {
10415             return (int) sendRequest(CMD_GET_CDMA_SUBSCRIPTION_MODE, null /* argument */, subId);
10416         } finally {
10417             Binder.restoreCallingIdentity(identity);
10418         }
10419     }
10420 
10421     @Override
setCdmaSubscriptionMode(int subId, int mode)10422     public boolean setCdmaSubscriptionMode(int subId, int mode) {
10423         if (mFeatureFlags.cleanupCdma()) return false;
10424 
10425         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
10426                 mApp, subId, "setCdmaSubscriptionMode");
10427 
10428         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10429                 PackageManager.FEATURE_TELEPHONY_CDMA, "setCdmaSubscriptionMode");
10430 
10431         final long identity = Binder.clearCallingIdentity();
10432         try {
10433             return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
10434         } finally {
10435             Binder.restoreCallingIdentity(identity);
10436         }
10437     }
10438 
10439     @Override
getEmergencyNumberList( String callingPackage, String callingFeatureId)10440     public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
10441             String callingPackage, String callingFeatureId) {
10442         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
10443                 mApp, getDefaultSubscription(), callingPackage, callingFeatureId,
10444                 "getEmergencyNumberList")) {
10445             throw new SecurityException("Requires READ_PHONE_STATE permission.");
10446         }
10447 
10448         enforceTelephonyFeatureWithException(
10449                 callingPackage,
10450                 Arrays.asList(
10451                         PackageManager.FEATURE_TELEPHONY_CALLING,
10452                         PackageManager.FEATURE_TELEPHONY_MESSAGING),
10453                 "getEmergencyNumberList");
10454 
10455         final long identity = Binder.clearCallingIdentity();
10456         try {
10457             Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
10458             for (Phone phone: PhoneFactory.getPhones()) {
10459                 if (phone.getEmergencyNumberTracker() != null
10460                         && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
10461                     emergencyNumberListInternal.put(
10462                             phone.getSubId(),
10463                             phone.getEmergencyNumberTracker().getEmergencyNumberList());
10464                 }
10465             }
10466             return emergencyNumberListInternal;
10467         } finally {
10468             Binder.restoreCallingIdentity(identity);
10469         }
10470     }
10471 
10472     @Override
isEmergencyNumber(String number, boolean exactMatch)10473     public boolean isEmergencyNumber(String number, boolean exactMatch) {
10474         final Phone defaultPhone = getDefaultPhone();
10475         if (!exactMatch) {
10476             TelephonyPermissions
10477                     .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
10478                             mApp, defaultPhone.getSubId(), "isEmergencyNumber(Potential)");
10479         }
10480 
10481         if (!mApp.getResources().getBoolean(
10482                 com.android.internal.R.bool.config_force_phone_globals_creation)) {
10483             enforceTelephonyFeatureWithException(
10484                     getCurrentPackageName(),
10485                     Arrays.asList(
10486                             PackageManager.FEATURE_TELEPHONY_CALLING,
10487                             PackageManager.FEATURE_TELEPHONY_MESSAGING),
10488                     "isEmergencyNumber");
10489         }
10490 
10491         final long identity = Binder.clearCallingIdentity();
10492         try {
10493             for (Phone phone: PhoneFactory.getPhones()) {
10494                 //Note: we ignore passed in param exactMatch. We can remove it once
10495                 // TelephonyManager#isPotentialEmergencyNumber is removed completely
10496                 if (phone.getEmergencyNumberTracker() != null
10497                         && phone.getEmergencyNumberTracker()
10498                         .isEmergencyNumber(number)) {
10499                     return true;
10500                 }
10501             }
10502             return false;
10503         } finally {
10504             Binder.restoreCallingIdentity(identity);
10505         }
10506     }
10507 
10508     /**
10509      * Start emergency callback mode for GsmCdmaPhone for testing.
10510      */
10511     @Override
startEmergencyCallbackMode()10512     public void startEmergencyCallbackMode() {
10513         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10514                 "startEmergencyCallbackMode");
10515         enforceModifyPermission();
10516         final long identity = Binder.clearCallingIdentity();
10517         try {
10518             for (Phone phone : PhoneFactory.getPhones()) {
10519                 Rlog.d(LOG_TAG, "startEmergencyCallbackMode phone type: " + phone.getPhoneType());
10520                 if (phone != null && ((phone.getPhoneType() == PHONE_TYPE_GSM)
10521                         || (phone.getPhoneType() == PHONE_TYPE_CDMA))) {
10522                     GsmCdmaPhone gsmCdmaPhone = (GsmCdmaPhone) phone;
10523                     gsmCdmaPhone.obtainMessage(
10524                             GsmCdmaPhone.EVENT_EMERGENCY_CALLBACK_MODE_ENTER).sendToTarget();
10525                     Rlog.d(LOG_TAG, "startEmergencyCallbackMode: triggered");
10526                 }
10527             }
10528         } finally {
10529             Binder.restoreCallingIdentity(identity);
10530         }
10531     }
10532 
10533     /**
10534      * Update emergency number list for test mode.
10535      */
10536     @Override
updateEmergencyNumberListTestMode(int action, EmergencyNumber num)10537     public void updateEmergencyNumberListTestMode(int action, EmergencyNumber num) {
10538         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10539                 "updateEmergencyNumberListTestMode");
10540 
10541         final long identity = Binder.clearCallingIdentity();
10542         try {
10543             for (Phone phone: PhoneFactory.getPhones()) {
10544                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
10545                 if (tracker != null) {
10546                     tracker.executeEmergencyNumberTestModeCommand(action, num);
10547                 }
10548             }
10549         } finally {
10550             Binder.restoreCallingIdentity(identity);
10551         }
10552     }
10553 
10554     /**
10555      * Get the full emergency number list for test mode.
10556      */
10557     @Override
getEmergencyNumberListTestMode()10558     public List<String> getEmergencyNumberListTestMode() {
10559         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
10560                 "getEmergencyNumberListTestMode");
10561 
10562         final long identity = Binder.clearCallingIdentity();
10563         try {
10564             Set<String> emergencyNumbers = new HashSet<>();
10565             for (Phone phone: PhoneFactory.getPhones()) {
10566                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
10567                 if (tracker != null) {
10568                     for (EmergencyNumber num : tracker.getEmergencyNumberList()) {
10569                         emergencyNumbers.add(num.getNumber());
10570                     }
10571                 }
10572             }
10573             return new ArrayList<>(emergencyNumbers);
10574         } finally {
10575             Binder.restoreCallingIdentity(identity);
10576         }
10577     }
10578 
10579     @Override
getEmergencyNumberDbVersion(int subId)10580     public int getEmergencyNumberDbVersion(int subId) {
10581         enforceReadPrivilegedPermission("getEmergencyNumberDbVersion");
10582 
10583         enforceTelephonyFeatureWithException(
10584                 getCurrentPackageName(),
10585                 Arrays.asList(
10586                         PackageManager.FEATURE_TELEPHONY_CALLING,
10587                         PackageManager.FEATURE_TELEPHONY_MESSAGING),
10588                 "getEmergencyNumberDbVersion");
10589 
10590         final long identity = Binder.clearCallingIdentity();
10591         try {
10592             final Phone phone = getPhone(subId);
10593             if (phone == null) {
10594                 loge("getEmergencyNumberDbVersion fails with invalid subId: " + subId);
10595                 return TelephonyManager.INVALID_EMERGENCY_NUMBER_DB_VERSION;
10596             }
10597             return phone.getEmergencyNumberDbVersion();
10598         } finally {
10599             Binder.restoreCallingIdentity(identity);
10600         }
10601     }
10602 
10603     @Override
notifyOtaEmergencyNumberDbInstalled()10604     public void notifyOtaEmergencyNumberDbInstalled() {
10605         enforceModifyPermission();
10606 
10607         enforceTelephonyFeatureWithException(
10608                 getCurrentPackageName(),
10609                 Arrays.asList(
10610                         PackageManager.FEATURE_TELEPHONY_CALLING,
10611                         PackageManager.FEATURE_TELEPHONY_MESSAGING),
10612                 "notifyOtaEmergencyNumberDbInstalled");
10613 
10614         final long identity = Binder.clearCallingIdentity();
10615         try {
10616             for (Phone phone: PhoneFactory.getPhones()) {
10617                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
10618                 if (tracker != null) {
10619                     tracker.updateOtaEmergencyNumberDatabase();
10620                 }
10621             }
10622         } finally {
10623             Binder.restoreCallingIdentity(identity);
10624         }
10625     }
10626 
10627     @Override
updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor)10628     public void updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor) {
10629         enforceActiveEmergencySessionPermission();
10630 
10631         enforceTelephonyFeatureWithException(
10632                 getCurrentPackageName(),
10633                 Arrays.asList(
10634                         PackageManager.FEATURE_TELEPHONY_CALLING,
10635                         PackageManager.FEATURE_TELEPHONY_MESSAGING),
10636                 "updateOtaEmergencyNumberDbFilePath");
10637 
10638         final long identity = Binder.clearCallingIdentity();
10639         try {
10640             for (Phone phone: PhoneFactory.getPhones()) {
10641                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
10642                 if (tracker != null) {
10643                     tracker.updateOtaEmergencyNumberDbFilePath(otaParcelFileDescriptor);
10644                 }
10645             }
10646         } finally {
10647             Binder.restoreCallingIdentity(identity);
10648         }
10649     }
10650 
10651     @Override
resetOtaEmergencyNumberDbFilePath()10652     public void resetOtaEmergencyNumberDbFilePath() {
10653         enforceActiveEmergencySessionPermission();
10654 
10655         enforceTelephonyFeatureWithException(
10656                 getCurrentPackageName(),
10657                 Arrays.asList(
10658                         PackageManager.FEATURE_TELEPHONY_CALLING,
10659                         PackageManager.FEATURE_TELEPHONY_MESSAGING),
10660                 "resetOtaEmergencyNumberDbFilePath");
10661 
10662         final long identity = Binder.clearCallingIdentity();
10663         try {
10664             for (Phone phone: PhoneFactory.getPhones()) {
10665                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
10666                 if (tracker != null) {
10667                     tracker.resetOtaEmergencyNumberDbFilePath();
10668                 }
10669             }
10670         } finally {
10671             Binder.restoreCallingIdentity(identity);
10672         }
10673     }
10674 
10675     @Override
getCertsFromCarrierPrivilegeAccessRules(int subId)10676     public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
10677         enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
10678         Phone phone = getPhone(subId);
10679         if (phone == null) {
10680             return null;
10681         }
10682         final long identity = Binder.clearCallingIdentity();
10683         try {
10684             UiccProfile profile = UiccController.getInstance()
10685                     .getUiccProfileForPhone(phone.getPhoneId());
10686             if (profile != null) {
10687                 return profile.getCertsFromCarrierPrivilegeAccessRules();
10688             }
10689         } finally {
10690             Binder.restoreCallingIdentity(identity);
10691         }
10692         return null;
10693     }
10694 
10695     /**
10696      * Enable or disable a modem stack.
10697      */
10698     @Override
enableModemForSlot(int slotIndex, boolean enable)10699     public boolean enableModemForSlot(int slotIndex, boolean enable) {
10700         enforceModifyPermission();
10701 
10702         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10703                 PackageManager.FEATURE_TELEPHONY, "enableModemForSlot");
10704 
10705         final long identity = Binder.clearCallingIdentity();
10706         try {
10707             Phone phone = PhoneFactory.getPhone(slotIndex);
10708             if (phone == null) {
10709                 return false;
10710             } else {
10711                 return (Boolean) sendRequest(CMD_REQUEST_ENABLE_MODEM, enable, phone, null);
10712             }
10713         } finally {
10714             Binder.restoreCallingIdentity(identity);
10715         }
10716     }
10717 
10718     /**
10719      * Whether a modem stack is enabled or not.
10720      */
10721     @Override
isModemEnabledForSlot(int slotIndex, String callingPackage, String callingFeatureId)10722     public boolean isModemEnabledForSlot(int slotIndex, String callingPackage,
10723             String callingFeatureId) {
10724         Phone phone = PhoneFactory.getPhone(slotIndex);
10725         if (phone == null) return false;
10726 
10727         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
10728                 mApp, phone.getSubId(), callingPackage, callingFeatureId,
10729                 "isModemEnabledForSlot")) {
10730             throw new SecurityException("Requires READ_PHONE_STATE permission.");
10731         }
10732 
10733         enforceTelephonyFeatureWithException(callingPackage,
10734                 PackageManager.FEATURE_TELEPHONY, "isModemEnabledForSlot");
10735 
10736         final long identity = Binder.clearCallingIdentity();
10737         try {
10738             try {
10739                 return mPhoneConfigurationManager.getPhoneStatusFromCache(phone.getPhoneId());
10740             } catch (NoSuchElementException ex) {
10741                 return (Boolean) sendRequest(CMD_GET_MODEM_STATUS, null, phone, null);
10742             }
10743         } finally {
10744             Binder.restoreCallingIdentity(identity);
10745         }
10746     }
10747 
10748     @Override
setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted)10749     public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
10750         enforceModifyPermission();
10751 
10752         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10753                 PackageManager.FEATURE_TELEPHONY_CARRIERLOCK, "setMultiSimCarrierRestriction");
10754 
10755         final long identity = Binder.clearCallingIdentity();
10756         try {
10757             mTelephonySharedPreferences.edit()
10758                     .putBoolean(PREF_MULTI_SIM_RESTRICTED, isMultiSimCarrierRestricted)
10759                     .commit();
10760         } finally {
10761             Binder.restoreCallingIdentity(identity);
10762         }
10763     }
10764 
10765     @Override
10766     @TelephonyManager.IsMultiSimSupportedResult
isMultiSimSupported(String callingPackage, String callingFeatureId)10767     public int isMultiSimSupported(String callingPackage, String callingFeatureId) {
10768         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
10769                 getDefaultPhone().getSubId(), callingPackage, callingFeatureId,
10770                 "isMultiSimSupported")) {
10771             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
10772         }
10773 
10774         enforceTelephonyFeatureWithException(callingPackage,
10775                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "isMultiSimSupported");
10776 
10777         final long identity = Binder.clearCallingIdentity();
10778         try {
10779             return isMultiSimSupportedInternal();
10780         } finally {
10781             Binder.restoreCallingIdentity(identity);
10782         }
10783     }
10784 
10785     @TelephonyManager.IsMultiSimSupportedResult
isMultiSimSupportedInternal()10786     private int isMultiSimSupportedInternal() {
10787         // If the device has less than 2 SIM cards, indicate that multisim is restricted.
10788         int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
10789         if (numPhysicalSlots < 2) {
10790             loge("isMultiSimSupportedInternal: requires at least 2 cards");
10791             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
10792         }
10793         // Check if the hardware supports multisim functionality. If usage of multisim is not
10794         // supported by the modem, indicate that it is restricted.
10795         PhoneCapability staticCapability =
10796                 mPhoneConfigurationManager.getStaticPhoneCapability();
10797         if (staticCapability == null) {
10798             loge("isMultiSimSupportedInternal: no static configuration available");
10799             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
10800         }
10801         if (staticCapability.getLogicalModemList().size() < 2) {
10802             loge("isMultiSimSupportedInternal: maximum number of modem is < 2");
10803             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
10804         }
10805         // Check if support of multiple SIMs is restricted by carrier
10806         if (mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false)) {
10807             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_CARRIER;
10808         }
10809 
10810         return TelephonyManager.MULTISIM_ALLOWED;
10811     }
10812 
10813     /**
10814      * Switch configs to enable multi-sim or switch back to single-sim
10815      * Note: Switch from multi-sim to single-sim is only possible with MODIFY_PHONE_STATE
10816      * permission, but the other way around is possible with either MODIFY_PHONE_STATE
10817      * or carrier privileges
10818      * @param numOfSims number of active sims we want to switch to
10819      */
10820     @Override
switchMultiSimConfig(int numOfSims)10821     public void switchMultiSimConfig(int numOfSims) {
10822         if (numOfSims == 1) {
10823             enforceModifyPermission();
10824         } else {
10825             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
10826                     mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
10827         }
10828 
10829         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10830                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "switchMultiSimConfig");
10831 
10832         final long identity = Binder.clearCallingIdentity();
10833 
10834         try {
10835             //only proceed if multi-sim is not restricted
10836             if (isMultiSimSupportedInternal() != TelephonyManager.MULTISIM_ALLOWED) {
10837                 loge("switchMultiSimConfig not possible. It is restricted or not supported.");
10838                 return;
10839             }
10840             mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
10841         } finally {
10842             Binder.restoreCallingIdentity(identity);
10843         }
10844     }
10845 
10846     @Override
isApplicationOnUicc(int subId, int appType)10847     public boolean isApplicationOnUicc(int subId, int appType) {
10848         enforceReadPrivilegedPermission("isApplicationOnUicc");
10849 
10850         enforceTelephonyFeatureWithException(getCurrentPackageName(),
10851                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "isApplicationOnUicc");
10852 
10853         Phone phone = getPhone(subId);
10854         if (phone == null) {
10855             return false;
10856         }
10857         final long identity = Binder.clearCallingIdentity();
10858         try {
10859             UiccPort uiccPort = phone.getUiccPort();
10860             if (uiccPort == null) {
10861                 return false;
10862             }
10863             UiccProfile uiccProfile = uiccPort.getUiccProfile();
10864             if (uiccProfile == null) {
10865                 return false;
10866             }
10867             if (TelephonyManager.APPTYPE_SIM <= appType
10868                     && appType <= TelephonyManager.APPTYPE_ISIM) {
10869                 return uiccProfile.isApplicationOnIcc(AppType.values()[appType]);
10870             }
10871             return false;
10872         } finally {
10873             Binder.restoreCallingIdentity(identity);
10874         }
10875     }
10876 
10877     /**
10878      * Get whether making changes to modem configurations will trigger reboot.
10879      * Return value defaults to true.
10880      */
10881     @Override
doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage, String callingFeatureId)10882     public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage,
10883             String callingFeatureId) {
10884         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
10885                 mApp, subId, callingPackage, callingFeatureId,
10886                 "doesSwitchMultiSimConfigTriggerReboot")) {
10887             return false;
10888         }
10889 
10890         enforceTelephonyFeatureWithException(callingPackage,
10891                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION,
10892                 "doesSwitchMultiSimConfigTriggerReboot");
10893 
10894         final long identity = Binder.clearCallingIdentity();
10895         try {
10896             return mPhoneConfigurationManager.isRebootRequiredForModemConfigChange();
10897         } finally {
10898             Binder.restoreCallingIdentity(identity);
10899         }
10900     }
10901 
updateModemStateMetrics()10902     private void updateModemStateMetrics() {
10903         TelephonyMetrics metrics = TelephonyMetrics.getInstance();
10904         // TODO: check the state for each modem if the api is ready.
10905         metrics.updateEnabledModemBitmap((1 << TelephonyManager.from(mApp).getPhoneCount()) - 1);
10906     }
10907 
10908     @Override
getSlotsMapping(String callingPackage)10909     public List<UiccSlotMapping> getSlotsMapping(String callingPackage) {
10910         enforceReadPrivilegedPermission("getSlotsMapping");
10911         // Verify that the callingPackage belongs to the calling UID
10912         mApp.getSystemService(AppOpsManager.class)
10913                 .checkPackage(Binder.getCallingUid(), callingPackage);
10914 
10915         enforceTelephonyFeatureWithException(callingPackage,
10916                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSlotsMapping");
10917 
10918         final long identity = Binder.clearCallingIdentity();
10919         List<UiccSlotMapping> slotMap = new ArrayList<>();
10920         try {
10921             UiccSlotInfo[] slotInfos = getUiccSlotsInfo(mApp.getOpPackageName());
10922             if (slotInfos != null) {
10923                 for (int i = 0; i < slotInfos.length; i++) {
10924                     for (UiccPortInfo portInfo : slotInfos[i].getPorts()) {
10925                         if (SubscriptionManager.isValidPhoneId(portInfo.getLogicalSlotIndex())) {
10926                             slotMap.add(new UiccSlotMapping(portInfo.getPortIndex(), i,
10927                                     portInfo.getLogicalSlotIndex()));
10928                         }
10929                     }
10930                 }
10931             }
10932             return slotMap;
10933         } finally {
10934             Binder.restoreCallingIdentity(identity);
10935         }
10936     }
10937 
10938     /**
10939      * Get the IRadio HAL Version
10940      * @deprecated use getHalVersion instead
10941      */
10942     @Deprecated
10943     @Override
getRadioHalVersion()10944     public int getRadioHalVersion() {
10945         return getHalVersion(HAL_SERVICE_RADIO);
10946     }
10947 
10948     /**
10949      * Get the HAL Version of a specific service
10950      */
10951     @Override
getHalVersion(int service)10952     public int getHalVersion(int service) {
10953         Phone phone = getDefaultPhone();
10954         if (phone == null) return -1;
10955         HalVersion hv = phone.getHalVersion(service);
10956         if (hv.equals(HalVersion.UNKNOWN)) return -1;
10957         return hv.major * 100 + hv.minor;
10958     }
10959 
10960     /**
10961      * Get the current calling package name.
10962      *
10963      * @return the current calling package name, or null if there is no known package.
10964      */
10965     @Override
getCurrentPackageName()10966     public @Nullable String getCurrentPackageName() {
10967         if (mFeatureFlags.hsumPackageManager()) {
10968             PackageManager pm = mApp.getBaseContext().createContextAsUser(
10969                     Binder.getCallingUserHandle(), 0).getPackageManager();
10970             if (pm == null) return null;
10971             String[] callingUids = pm.getPackagesForUid(Binder.getCallingUid());
10972             return (callingUids == null) ? null : callingUids[0];
10973         }
10974         if (mPackageManager == null) return null;
10975         String[] callingUids = mPackageManager.getPackagesForUid(Binder.getCallingUid());
10976         return (callingUids == null) ? null : callingUids[0];
10977     }
10978 
10979     /**
10980      * @return The calling package name or "phone" if the caller is the phone process. This is done
10981      * because multiple Phone has multiple packages in it and the first element in the array is not
10982      * actually always the caller.
10983      * Note: This is for logging purposes only and should not be used for security checks.
10984      */
getCurrentPackageNameOrPhone()10985     private String getCurrentPackageNameOrPhone() {
10986         PackageManager pm;
10987         if (mFeatureFlags.hsumPackageManager()) {
10988             pm = mApp.getBaseContext().createContextAsUser(
10989                     Binder.getCallingUserHandle(), 0).getPackageManager();
10990         } else {
10991             pm = mApp.getPackageManager();
10992         }
10993         String uidName = pm == null ? null : pm.getNameForUid(Binder.getCallingUid());
10994         if (uidName != null && !uidName.isEmpty()) return uidName;
10995         return getCurrentPackageName();
10996     }
10997 
10998     /**
10999      * Return whether data is enabled for certain APN type. This will tell if framework will accept
11000      * corresponding network requests on a subId.
11001      *
11002      *  Data is enabled if:
11003      *  1) user data is turned on, or
11004      *  2) APN is un-metered for this subscription, or
11005      *  3) APN type is whitelisted. E.g. MMS is whitelisted if
11006      *  {@link TelephonyManager#MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED} is enabled.
11007      *
11008      * @return whether data is allowed for a apn type.
11009      *
11010      * @hide
11011      */
11012     @Override
isDataEnabledForApn(int apnType, int subId, String callingPackage)11013     public boolean isDataEnabledForApn(int apnType, int subId, String callingPackage) {
11014         enforceReadPrivilegedPermission("Needs READ_PRIVILEGED_PHONE_STATE for "
11015                 + "isDataEnabledForApn");
11016 
11017         enforceTelephonyFeatureWithException(callingPackage,
11018                 PackageManager.FEATURE_TELEPHONY_DATA, "isDataEnabledForApn");
11019 
11020         // Now that all security checks passes, perform the operation as ourselves.
11021         final long identity = Binder.clearCallingIdentity();
11022         try {
11023             Phone phone = getPhone(subId);
11024             if (phone == null) return false;
11025 
11026             boolean isMetered;
11027             boolean isDataEnabled;
11028             isMetered = phone.getDataNetworkController().getDataConfigManager()
11029                     .isMeteredCapability(DataUtils.apnTypeToNetworkCapability(apnType),
11030                             phone.getServiceState().getDataRoaming());
11031             isDataEnabled = (phone.getDataSettingsManager() != null)
11032                     ?  phone.getDataSettingsManager().isDataEnabled(apnType) : false;
11033             return !isMetered || isDataEnabled;
11034         } finally {
11035             Binder.restoreCallingIdentity(identity);
11036         }
11037     }
11038 
11039     @Override
isApnMetered(@pnType int apnType, int subId)11040     public boolean isApnMetered(@ApnType int apnType, int subId) {
11041         enforceReadPrivilegedPermission("isApnMetered");
11042 
11043         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11044                 PackageManager.FEATURE_TELEPHONY_DATA, "isApnMetered");
11045 
11046         // Now that all security checks passes, perform the operation as ourselves.
11047         final long identity = Binder.clearCallingIdentity();
11048         try {
11049             Phone phone = getPhone(subId);
11050             if (phone == null) return true; // By default return true.
11051             return phone.getDataNetworkController().getDataConfigManager().isMeteredCapability(
11052                     DataUtils.apnTypeToNetworkCapability(apnType),
11053                     phone.getServiceState().getDataRoaming());
11054         } finally {
11055             Binder.restoreCallingIdentity(identity);
11056         }
11057     }
11058 
11059     @Override
setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers, int subscriptionId, IBooleanConsumer resultCallback)11060     public void setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers,
11061             int subscriptionId, IBooleanConsumer resultCallback) {
11062         enforceModifyPermission();
11063 
11064         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11065                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "setSystemSelectionChannels");
11066 
11067         long token = Binder.clearCallingIdentity();
11068         try {
11069             Phone phone = getPhone(subscriptionId);
11070             if (phone == null) {
11071                 try {
11072                     if (resultCallback != null) {
11073                         resultCallback.accept(false);
11074                     }
11075                 } catch (RemoteException e) {
11076                     // ignore
11077                 }
11078                 return;
11079             }
11080             Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> argument =
11081                     Pair.create(specifiers, (x) -> {
11082                         try {
11083                             if (resultCallback != null) {
11084                                 resultCallback.accept(x);
11085                             }
11086                         } catch (RemoteException e) {
11087                             // ignore
11088                         }
11089                     });
11090             sendRequestAsync(CMD_SET_SYSTEM_SELECTION_CHANNELS, argument, phone, null);
11091         } finally {
11092             Binder.restoreCallingIdentity(token);
11093         }
11094     }
11095 
11096     @Override
getSystemSelectionChannels(int subId)11097     public List<RadioAccessSpecifier> getSystemSelectionChannels(int subId) {
11098         TelephonyPermissions
11099                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
11100                         mApp, subId, "getSystemSelectionChannels");
11101 
11102         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11103                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "getSystemSelectionChannels");
11104 
11105         WorkSource workSource = getWorkSource(Binder.getCallingUid());
11106         final long identity = Binder.clearCallingIdentity();
11107         try {
11108             Object result = sendRequest(CMD_GET_SYSTEM_SELECTION_CHANNELS, null, subId, workSource);
11109             if (result instanceof IllegalStateException) {
11110                 throw (IllegalStateException) result;
11111             }
11112             List<RadioAccessSpecifier> specifiers = (List<RadioAccessSpecifier>) result;
11113             if (DBG) log("getSystemSelectionChannels: " + specifiers);
11114             return specifiers;
11115         } finally {
11116             Binder.restoreCallingIdentity(identity);
11117         }
11118     }
11119 
11120     @Override
isMvnoMatched(int slotIndex, int mvnoType, @NonNull String mvnoMatchData)11121     public boolean isMvnoMatched(int slotIndex, int mvnoType, @NonNull String mvnoMatchData) {
11122         enforceReadPrivilegedPermission("isMvnoMatched");
11123 
11124         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11125                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "isMvnoMatched");
11126 
11127         return UiccController.getInstance().mvnoMatches(slotIndex, mvnoType, mvnoMatchData);
11128     }
11129 
11130     @Override
enqueueSmsPickResult(String callingPackage, String callingAttributionTag, IIntegerConsumer pendingSubIdResult)11131     public void enqueueSmsPickResult(String callingPackage, String callingAttributionTag,
11132             IIntegerConsumer pendingSubIdResult) {
11133         if (callingPackage == null) {
11134             callingPackage = getCurrentPackageName();
11135         }
11136         SmsPermissions permissions = new SmsPermissions(getDefaultPhone(), mApp,
11137                 (AppOpsManager) mApp.getSystemService(Context.APP_OPS_SERVICE));
11138         if (!permissions.checkCallingCanSendSms(callingPackage, callingAttributionTag,
11139                 "Sending message")) {
11140             throw new SecurityException("Requires SEND_SMS permission to perform this operation");
11141         }
11142         PickSmsSubscriptionActivity.addPendingResult(pendingSubIdResult);
11143         Intent intent = new Intent();
11144         intent.setClass(mApp, PickSmsSubscriptionActivity.class);
11145         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11146         // Bring up choose default SMS subscription dialog right now
11147         intent.putExtra(PickSmsSubscriptionActivity.DIALOG_TYPE_KEY,
11148                 PickSmsSubscriptionActivity.SMS_PICK_FOR_MESSAGE);
11149         mApp.startActivityAsUser(intent, UserHandle.CURRENT);
11150     }
11151 
11152     @Override
showSwitchToManagedProfileDialog()11153     public void showSwitchToManagedProfileDialog() {
11154         enforceModifyPermission();
11155         try {
11156             // Note: This intent is constructed to ensure that the IntentForwarderActivity is
11157             // shown in accordance with the intent filters in DefaultCrossProfileIntentFilterUtils
11158             // for work telephony.
11159             Intent intent = new Intent(Intent.ACTION_SENDTO);
11160             intent.setData(Uri.parse("smsto:"));
11161             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11162             mApp.startActivityAsUser(intent, UserHandle.CURRENT);
11163         } catch (ActivityNotFoundException e) {
11164             Log.w(LOG_TAG, "Unable to show intent forwarder, try showing error dialog instead");
11165             Intent intent = new Intent();
11166             intent.setClass(mApp, ErrorDialogActivity.class);
11167             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11168             mApp.startActivityAsUser(intent, UserHandle.CURRENT);
11169         }
11170     }
11171 
11172     @Override
getMmsUAProfUrl(int subId)11173     public String getMmsUAProfUrl(int subId) {
11174         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11175                 PackageManager.FEATURE_TELEPHONY_MESSAGING, "getMmsUAProfUrl");
11176 
11177         //TODO investigate if this API should require proper permission check in R b/133791609
11178         final long identity = Binder.clearCallingIdentity();
11179         try {
11180             String carrierUAProfUrl = mApp.getCarrierConfigForSubId(subId).getString(
11181                     CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING);
11182             if (!TextUtils.isEmpty(carrierUAProfUrl)) {
11183                 return carrierUAProfUrl;
11184             }
11185             return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
11186                     .getString(com.android.internal.R.string.config_mms_user_agent_profile_url);
11187         } finally {
11188             Binder.restoreCallingIdentity(identity);
11189         }
11190     }
11191 
11192     @Override
getMmsUserAgent(int subId)11193     public String getMmsUserAgent(int subId) {
11194         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11195                 PackageManager.FEATURE_TELEPHONY_MESSAGING, "getMmsUserAgent");
11196 
11197         //TODO investigate if this API should require proper permission check in R b/133791609
11198         final long identity = Binder.clearCallingIdentity();
11199         try {
11200             String carrierUserAgent = mApp.getCarrierConfigForSubId(subId).getString(
11201                     CarrierConfigManager.KEY_MMS_USER_AGENT_STRING);
11202             if (!TextUtils.isEmpty(carrierUserAgent)) {
11203                 return carrierUserAgent;
11204             }
11205             return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
11206                     .getString(com.android.internal.R.string.config_mms_user_agent);
11207         } finally {
11208             Binder.restoreCallingIdentity(identity);
11209         }
11210     }
11211 
11212     @Override
isMobileDataPolicyEnabled(int subscriptionId, int policy)11213     public boolean isMobileDataPolicyEnabled(int subscriptionId, int policy) {
11214         enforceReadPrivilegedPermission("isMobileDataPolicyEnabled");
11215 
11216         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11217                 PackageManager.FEATURE_TELEPHONY_DATA, "isMobileDataPolicyEnabled");
11218 
11219         final long identity = Binder.clearCallingIdentity();
11220         try {
11221             Phone phone = getPhone(subscriptionId);
11222             if (phone == null || phone.getDataSettingsManager() == null) return false;
11223 
11224             return phone.getDataSettingsManager().isMobileDataPolicyEnabled(policy);
11225         } finally {
11226             Binder.restoreCallingIdentity(identity);
11227         }
11228     }
11229 
11230     @Override
setMobileDataPolicyEnabled(int subscriptionId, int policy, boolean enabled)11231     public void setMobileDataPolicyEnabled(int subscriptionId, int policy,
11232             boolean enabled) {
11233         enforceModifyPermission();
11234 
11235         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11236                 PackageManager.FEATURE_TELEPHONY_DATA, "setMobileDataPolicyEnabled");
11237 
11238         final long identity = Binder.clearCallingIdentity();
11239         try {
11240             Phone phone = getPhone(subscriptionId);
11241             if (phone == null || phone.getDataSettingsManager() == null) return;
11242 
11243             phone.getDataSettingsManager().setMobileDataPolicy(policy, enabled);
11244         } finally {
11245             Binder.restoreCallingIdentity(identity);
11246         }
11247     }
11248 
11249     /**
11250      * Updates whether conference event package handling is enabled.
11251      * @param isCepEnabled {@code true} if CEP handling is enabled (default), or {@code false}
11252      *                                 otherwise.
11253      */
11254     @Override
setCepEnabled(boolean isCepEnabled)11255     public void setCepEnabled(boolean isCepEnabled) {
11256         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCepEnabled");
11257 
11258         final long identity = Binder.clearCallingIdentity();
11259         try {
11260             Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled);
11261             for (Phone phone : PhoneFactory.getPhones()) {
11262                 Phone defaultPhone = phone.getImsPhone();
11263                 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
11264                     ImsPhone imsPhone = (ImsPhone) defaultPhone;
11265                     ImsPhoneCallTracker imsPhoneCallTracker =
11266                             (ImsPhoneCallTracker) imsPhone.getCallTracker();
11267                     imsPhoneCallTracker.setConferenceEventPackageEnabled(isCepEnabled);
11268                     Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled + ", for imsPhone "
11269                             + imsPhone.getMsisdn());
11270                 }
11271             }
11272         } finally {
11273             Binder.restoreCallingIdentity(identity);
11274         }
11275     }
11276 
11277     /**
11278      * Notify that an RCS autoconfiguration XML file has been received for provisioning.
11279      *
11280      * @param config       The XML file to be read. ASCII/UTF8 encoded text if not compressed.
11281      * @param isCompressed The XML file is compressed in gzip format and must be decompressed
11282      *                     before being read.
11283      */
11284     @Override
notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean isCompressed)11285     public void notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean
11286             isCompressed) {
11287         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
11288                 mApp, subId, "notifyRcsAutoConfigurationReceived");
11289         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11290             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11291         }
11292 
11293         if (!CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, getCurrentPackageName(),
11294                 Binder.getCallingUserHandle())) {
11295             if (!isImsAvailableOnDevice()) {
11296                 // ProvisioningManager can not handle ServiceSpecificException.
11297                 // Throw the IllegalStateException and annotate ProvisioningManager.
11298                 throw new IllegalStateException("IMS not available on device.");
11299             }
11300         } else {
11301             enforceTelephonyFeatureWithException(getCurrentPackageName(),
11302                     FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION,
11303                     "notifyRcsAutoConfigurationReceived");
11304         }
11305 
11306         final long identity = Binder.clearCallingIdentity();
11307         try {
11308             RcsProvisioningMonitor.getInstance().updateConfig(subId, config, isCompressed);
11309         } finally {
11310             Binder.restoreCallingIdentity(identity);
11311         }
11312     }
11313 
11314     @Override
isIccLockEnabled(int subId)11315     public boolean isIccLockEnabled(int subId) {
11316         enforceReadPrivilegedPermission("isIccLockEnabled");
11317 
11318         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11319                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "isIccLockEnabled");
11320 
11321         // Now that all security checks passes, perform the operation as ourselves.
11322         final long identity = Binder.clearCallingIdentity();
11323         try {
11324             Phone phone = getPhone(subId);
11325             if (phone != null && phone.getIccCard() != null) {
11326                 return phone.getIccCard().getIccLockEnabled();
11327             } else {
11328                 return false;
11329             }
11330         } finally {
11331             Binder.restoreCallingIdentity(identity);
11332         }
11333     }
11334 
11335     /**
11336      * Set the ICC pin lock enabled or disabled.
11337      *
11338      * @return an integer representing the status of IccLock enabled or disabled in the following
11339      * three cases:
11340      *   - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if enabled or disabled IccLock
11341      *   successfully.
11342      *   - Positive number and zero for remaining password attempts.
11343      *   - Negative number for other failure cases (such like enabling/disabling PIN failed).
11344      *
11345      */
11346     @Override
setIccLockEnabled(int subId, boolean enabled, String password)11347     public int setIccLockEnabled(int subId, boolean enabled, String password) {
11348         enforceModifyPermission();
11349 
11350         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11351                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "setIccLockEnabled");
11352 
11353         Phone phone = getPhone(subId);
11354         if (phone == null) {
11355             return 0;
11356         }
11357         // Now that all security checks passes, perform the operation as ourselves.
11358         final long identity = Binder.clearCallingIdentity();
11359         try {
11360             int attemptsRemaining = (int) sendRequest(CMD_SET_ICC_LOCK_ENABLED,
11361                     new Pair<Boolean, String>(enabled, password), phone, null);
11362             return attemptsRemaining;
11363 
11364         } catch (Exception e) {
11365             Log.e(LOG_TAG, "setIccLockEnabled. Exception e =" + e);
11366         } finally {
11367             Binder.restoreCallingIdentity(identity);
11368         }
11369         return 0;
11370     }
11371 
11372     /**
11373      * Change the ICC password used in ICC pin lock.
11374      *
11375      * @return an integer representing the status of IccLock changed in the following three cases:
11376      *   - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if changed IccLock successfully.
11377      *   - Positive number and zero for remaining password attempts.
11378      *   - Negative number for other failure cases (such like enabling/disabling PIN failed).
11379      *
11380      */
11381     @Override
changeIccLockPassword(int subId, String oldPassword, String newPassword)11382     public int changeIccLockPassword(int subId, String oldPassword, String newPassword) {
11383         enforceModifyPermission();
11384 
11385         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11386                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "changeIccLockPassword");
11387 
11388         Phone phone = getPhone(subId);
11389         if (phone == null) {
11390             return 0;
11391         }
11392         // Now that all security checks passes, perform the operation as ourselves.
11393         final long identity = Binder.clearCallingIdentity();
11394         try {
11395             int attemptsRemaining = (int) sendRequest(CMD_CHANGE_ICC_LOCK_PASSWORD,
11396                     new Pair<String, String>(oldPassword, newPassword), phone, null);
11397             return attemptsRemaining;
11398 
11399         } catch (Exception e) {
11400             Log.e(LOG_TAG, "changeIccLockPassword. Exception e =" + e);
11401         } finally {
11402             Binder.restoreCallingIdentity(identity);
11403         }
11404         return 0;
11405     }
11406 
11407     /**
11408      * Request for receiving user activity notification
11409      */
11410     @Override
requestUserActivityNotification()11411     public void requestUserActivityNotification() {
11412         if (!mNotifyUserActivity.get()
11413                 && !mMainThreadHandler.hasMessages(MSG_NOTIFY_USER_ACTIVITY)) {
11414             mNotifyUserActivity.set(true);
11415         }
11416     }
11417 
11418     /**
11419      * Called when userActivity is signalled in the power manager.
11420      * This is safe to call from any thread, with any window manager locks held or not.
11421      */
11422     @Override
userActivity()11423     public void userActivity() {
11424         // ***************************************
11425         // *  Inherited from PhoneWindowManager  *
11426         // ***************************************
11427         // THIS IS CALLED FROM DEEP IN THE POWER MANAGER
11428         // WITH ITS LOCKS HELD.
11429         //
11430         // This code must be VERY careful about the locks
11431         // it acquires.
11432         // In fact, the current code acquires way too many,
11433         // and probably has lurking deadlocks.
11434 
11435         if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
11436             throw new SecurityException("Only the OS may call notifyUserActivity()");
11437         }
11438 
11439         if (mNotifyUserActivity.getAndSet(false)) {
11440             mMainThreadHandler.sendEmptyMessageDelayed(MSG_NOTIFY_USER_ACTIVITY,
11441                     USER_ACTIVITY_NOTIFICATION_DELAY);
11442         }
11443     }
11444 
11445     @Override
canConnectTo5GInDsdsMode()11446     public boolean canConnectTo5GInDsdsMode() {
11447         return mApp.getResources().getBoolean(R.bool.config_5g_connection_in_dsds_mode);
11448     }
11449 
11450     @Override
getEquivalentHomePlmns(int subId, String callingPackage, String callingFeatureId)11451     public @NonNull List<String> getEquivalentHomePlmns(int subId, String callingPackage,
11452             String callingFeatureId) {
11453         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
11454                 mApp, subId, callingPackage, callingFeatureId, "getEquivalentHomePlmns")) {
11455             throw new SecurityException("Requires READ_PHONE_STATE permission.");
11456         }
11457 
11458         enforceTelephonyFeatureWithException(callingPackage,
11459                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getEquivalentHomePlmns");
11460 
11461         Phone phone = getPhone(subId);
11462         if (phone == null) {
11463             throw new RuntimeException("phone is not available");
11464         }
11465         // Now that all security checks passes, perform the operation as ourselves.
11466         final long identity = Binder.clearCallingIdentity();
11467         try {
11468             return phone.getEquivalentHomePlmns();
11469         } finally {
11470             Binder.restoreCallingIdentity(identity);
11471         }
11472     }
11473 
11474     @Override
isRadioInterfaceCapabilitySupported( final @NonNull @TelephonyManager.RadioInterfaceCapability String capability)11475     public boolean isRadioInterfaceCapabilitySupported(
11476             final @NonNull @TelephonyManager.RadioInterfaceCapability String capability) {
11477         if (!mApp.getResources().getBoolean(
11478                 com.android.internal.R.bool.config_force_phone_globals_creation)) {
11479             enforceTelephonyFeatureWithException(getCurrentPackageName(),
11480                     PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS,
11481                     "isRadioInterfaceCapabilitySupported");
11482         }
11483 
11484         Set<String> radioInterfaceCapabilities =
11485                 mRadioInterfaceCapabilities.getCapabilities();
11486         if (radioInterfaceCapabilities == null) {
11487             throw new RuntimeException("radio interface capabilities are not available");
11488         }
11489         return radioInterfaceCapabilities.contains(capability);
11490     }
11491 
11492     @Override
bootstrapAuthenticationRequest(int subId, int appType, Uri nafUrl, UaSecurityProtocolIdentifier securityProtocol, boolean forceBootStrapping, IBootstrapAuthenticationCallback callback)11493     public void bootstrapAuthenticationRequest(int subId, int appType, Uri nafUrl,
11494             UaSecurityProtocolIdentifier securityProtocol,
11495             boolean forceBootStrapping, IBootstrapAuthenticationCallback callback) {
11496         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
11497                 Binder.getCallingUid(), "bootstrapAuthenticationRequest",
11498                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
11499                 Manifest.permission.MODIFY_PHONE_STATE);
11500 
11501         enforceTelephonyFeatureWithException(getCurrentPackageName(),
11502                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "bootstrapAuthenticationRequest");
11503 
11504         if (DBG) {
11505             log("bootstrapAuthenticationRequest, subId:" + subId + ", appType:"
11506                     + appType + ", NAF:" + nafUrl + ", sp:" + securityProtocol
11507                     + ", forceBootStrapping:" + forceBootStrapping + ", callback:" + callback);
11508         }
11509 
11510         if (!SubscriptionManager.isValidSubscriptionId(subId)
11511                 || appType < TelephonyManager.APPTYPE_UNKNOWN
11512                 || appType > TelephonyManager.APPTYPE_ISIM
11513                 || nafUrl == null || securityProtocol == null || callback == null) {
11514             Log.d(LOG_TAG, "bootstrapAuthenticationRequest failed due to invalid parameters");
11515             if (callback != null) {
11516                 try {
11517                     callback.onAuthenticationFailure(
11518                             0, TelephonyManager.GBA_FAILURE_REASON_FEATURE_NOT_SUPPORTED);
11519                 } catch (RemoteException exception) {
11520                     log("Fail to notify onAuthenticationFailure due to " + exception);
11521                 }
11522                 return;
11523             }
11524         }
11525 
11526         final long token = Binder.clearCallingIdentity();
11527         try {
11528             getGbaManager(subId).bootstrapAuthenticationRequest(
11529                     new GbaAuthRequest(subId, appType, nafUrl, securityProtocol.toByteArray(),
11530                             forceBootStrapping, callback));
11531         } finally {
11532             Binder.restoreCallingIdentity(token);
11533         }
11534     }
11535 
11536     /**
11537      * Attempts to set the radio power state for all phones for thermal reason.
11538      * This does not guarantee that the
11539      * requested radio power state will actually be set. See {@link
11540      * PhoneInternalInterface#setRadioPowerForReason} for more details.
11541      *
11542      * @param enable {@code true} if trying to turn radio on.
11543      * @return {@code true} if phone setRadioPowerForReason was called. Otherwise, returns {@code
11544      * false}.
11545      */
setRadioPowerForThermal(boolean enable)11546     private boolean setRadioPowerForThermal(boolean enable) {
11547         boolean isPhoneAvailable = false;
11548         for (int i = 0; i < TelephonyManager.getDefault().getActiveModemCount(); i++) {
11549             Phone phone = PhoneFactory.getPhone(i);
11550             if (phone != null) {
11551                 phone.setRadioPowerForReason(enable, TelephonyManager.RADIO_POWER_REASON_THERMAL);
11552                 isPhoneAvailable = true;
11553             }
11554         }
11555 
11556         // return true if successfully informed the phone object about the thermal radio power
11557         // request.
11558         return isPhoneAvailable;
11559     }
11560 
handleDataThrottlingRequest(int subId, DataThrottlingRequest dataThrottlingRequest, String callingPackage)11561     private int handleDataThrottlingRequest(int subId,
11562             DataThrottlingRequest dataThrottlingRequest, String callingPackage) {
11563         boolean isDataThrottlingSupported = isRadioInterfaceCapabilitySupported(
11564                 TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING);
11565         if (!isDataThrottlingSupported && dataThrottlingRequest.getDataThrottlingAction()
11566                 != DataThrottlingRequest.DATA_THROTTLING_ACTION_NO_DATA_THROTTLING) {
11567             throw new IllegalArgumentException("modem does not support data throttling");
11568         }
11569 
11570         // Ensure that radio is on. If not able to power on due to phone being unavailable, return
11571         // THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
11572         if (!setRadioPowerForThermal(true)) {
11573             return TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
11574         }
11575 
11576         setDataEnabledForReason(
11577                 subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL, true, callingPackage);
11578 
11579         if (isDataThrottlingSupported) {
11580             int thermalMitigationResult =
11581                     (int) sendRequest(CMD_SET_DATA_THROTTLING, dataThrottlingRequest, subId);
11582             if (thermalMitigationResult == SET_DATA_THROTTLING_MODEM_THREW_INVALID_PARAMS) {
11583                 throw new IllegalArgumentException("modem returned INVALID_ARGUMENTS");
11584             } else if (thermalMitigationResult
11585                     == MODEM_DOES_NOT_SUPPORT_DATA_THROTTLING_ERROR_CODE) {
11586                 log("Modem likely does not support data throttling on secondary carrier. Data " +
11587                         "throttling action = " + dataThrottlingRequest.getDataThrottlingAction());
11588                 return TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
11589             }
11590             return thermalMitigationResult;
11591         }
11592 
11593         return TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
11594     }
11595 
getThermalMitigationAllowlist(Context context)11596     private static List<String> getThermalMitigationAllowlist(Context context) {
11597         if (sThermalMitigationAllowlistedPackages.isEmpty()) {
11598             for (String pckg : context.getResources()
11599                     .getStringArray(R.array.thermal_mitigation_allowlisted_packages)) {
11600                 sThermalMitigationAllowlistedPackages.add(pckg);
11601             }
11602         }
11603 
11604         return sThermalMitigationAllowlistedPackages;
11605     }
11606 
isAnyPhoneInEmergencyState()11607     private boolean isAnyPhoneInEmergencyState() {
11608         TelecomManager tm = mApp.getSystemService(TelecomManager.class);
11609         if (tm.isInEmergencyCall()) {
11610             Log.e(LOG_TAG , "Phone state is not valid. One of the phones is in an emergency call");
11611             return true;
11612         }
11613         for (Phone phone : PhoneFactory.getPhones()) {
11614             if (phone.isInEmergencySmsMode() || phone.isInEcm()) {
11615                 Log.e(LOG_TAG, "Phone state is not valid. isInEmergencySmsMode = "
11616                         + phone.isInEmergencySmsMode() + " isInEmergencyCallbackMode = "
11617                         + phone.isInEcm());
11618                 return true;
11619             }
11620         }
11621 
11622         return false;
11623     }
11624 
11625     /**
11626      * Used by shell commands to add an authorized package name for thermal mitigation.
11627      * @param packageName name of package to be allowlisted
11628      * @param context
11629      */
addPackageToThermalMitigationAllowlist(String packageName, Context context)11630     static void addPackageToThermalMitigationAllowlist(String packageName, Context context) {
11631         sThermalMitigationAllowlistedPackages = getThermalMitigationAllowlist(context);
11632         sThermalMitigationAllowlistedPackages.add(packageName);
11633     }
11634 
11635     /**
11636      * Used by shell commands to remove an authorized package name for thermal mitigation.
11637      * @param packageName name of package to remove from allowlist
11638      * @param context
11639      */
removePackageFromThermalMitigationAllowlist(String packageName, Context context)11640     static void removePackageFromThermalMitigationAllowlist(String packageName, Context context) {
11641         sThermalMitigationAllowlistedPackages = getThermalMitigationAllowlist(context);
11642         sThermalMitigationAllowlistedPackages.remove(packageName);
11643     }
11644 
11645     /**
11646      * Thermal mitigation request to control functionalities at modem.
11647      *
11648      * @param subId the id of the subscription.
11649      * @param thermalMitigationRequest holds all necessary information to be passed down to modem.
11650      * @param callingPackage the package name of the calling package.
11651      *
11652      * @return thermalMitigationResult enum as defined in android.telephony.Annotation.
11653      */
11654     @Override
11655     @ThermalMitigationResult
sendThermalMitigationRequest( int subId, ThermalMitigationRequest thermalMitigationRequest, String callingPackage)11656     public int sendThermalMitigationRequest(
11657             int subId,
11658             ThermalMitigationRequest thermalMitigationRequest,
11659             String callingPackage) throws IllegalArgumentException {
11660         enforceModifyPermission();
11661 
11662         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
11663 
11664         enforceTelephonyFeatureWithException(callingPackage,
11665                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "sendThermalMitigationRequest");
11666 
11667         if (!getThermalMitigationAllowlist(getDefaultPhone().getContext())
11668                 .contains(callingPackage)) {
11669             throw new SecurityException("Calling package must be configured in the device config. "
11670                     + "calling package: " + callingPackage);
11671         }
11672 
11673         WorkSource workSource = getWorkSource(Binder.getCallingUid());
11674         final long identity = Binder.clearCallingIdentity();
11675 
11676         int thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR;
11677         try {
11678             int thermalMitigationAction = thermalMitigationRequest.getThermalMitigationAction();
11679             switch (thermalMitigationAction) {
11680                 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_DATA_THROTTLING:
11681                     thermalMitigationResult =
11682                             handleDataThrottlingRequest(subId,
11683                                     thermalMitigationRequest.getDataThrottlingRequest(),
11684                                     callingPackage);
11685                     break;
11686                 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY:
11687                     if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
11688                         throw new IllegalArgumentException("dataThrottlingRequest must be null for "
11689                                 + "ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_VOICE_ONLY");
11690                     }
11691 
11692                     // Ensure that radio is on. If not able to power on due to phone being
11693                     // unavailable, return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
11694                     if (!setRadioPowerForThermal(true)) {
11695                         thermalMitigationResult =
11696                                 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
11697                         break;
11698                     }
11699 
11700                     setDataEnabledForReason(subId, TelephonyManager.DATA_ENABLED_REASON_THERMAL,
11701                             false, callingPackage);
11702                     thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
11703                     break;
11704                 case ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF:
11705                     if (thermalMitigationRequest.getDataThrottlingRequest() != null) {
11706                         throw new IllegalArgumentException("dataThrottlingRequest  must be null for"
11707                                 + " ThermalMitigationRequest.THERMAL_MITIGATION_ACTION_RADIO_OFF");
11708                     }
11709 
11710                     TelecomAccountRegistry registry = TelecomAccountRegistry.getInstance(null);
11711                     if (registry != null) {
11712                         Phone phone = getPhone(subId);
11713                         if (phone == null) {
11714                             thermalMitigationResult =
11715                                     TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
11716                             break;
11717                         }
11718 
11719                         TelephonyConnectionService service =
11720                                 registry.getTelephonyConnectionService();
11721                         if (service != null && service.isEmergencyCallPending()) {
11722                             Log.e(LOG_TAG, "An emergency call is pending");
11723                             thermalMitigationResult =
11724                                     TelephonyManager.THERMAL_MITIGATION_RESULT_INVALID_STATE;
11725                             break;
11726                         } else if (isAnyPhoneInEmergencyState()) {
11727                             thermalMitigationResult =
11728                                     TelephonyManager.THERMAL_MITIGATION_RESULT_INVALID_STATE;
11729                             break;
11730                         }
11731                     } else {
11732                         thermalMitigationResult =
11733                                 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
11734                         break;
11735                     }
11736 
11737                     // Turn radio off. If not able to power off due to phone being unavailable,
11738                     // return THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE.
11739                     if (!setRadioPowerForThermal(false)) {
11740                         thermalMitigationResult =
11741                                 TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_NOT_AVAILABLE;
11742                         break;
11743                     }
11744                     thermalMitigationResult =
11745                             TelephonyManager.THERMAL_MITIGATION_RESULT_SUCCESS;
11746                     break;
11747                 default:
11748                     throw new IllegalArgumentException("the requested thermalMitigationAction does "
11749                             + "not exist. Requested action: " + thermalMitigationAction);
11750             }
11751         } catch (IllegalArgumentException e) {
11752             throw e;
11753         } catch (Exception e) {
11754             Log.e(LOG_TAG, "thermalMitigationRequest. Exception e =" + e);
11755             thermalMitigationResult = TelephonyManager.THERMAL_MITIGATION_RESULT_MODEM_ERROR;
11756         } finally {
11757             Binder.restoreCallingIdentity(identity);
11758         }
11759 
11760         if (DBG) {
11761             log("thermalMitigationRequest returning with thermalMitigationResult: "
11762                     + thermalMitigationResult);
11763         }
11764 
11765         return thermalMitigationResult;
11766     }
11767 
11768     /**
11769      * Set the GbaService Package Name that Telephony will bind to.
11770      *
11771      * @param subId The sim that the GbaService is associated with.
11772      * @param packageName The name of the package to be replaced with.
11773      * @return true if setting the GbaService to bind to succeeded, false if it did not.
11774      */
11775     @Override
setBoundGbaServiceOverride(int subId, String packageName)11776     public boolean setBoundGbaServiceOverride(int subId, String packageName) {
11777         enforceModifyPermission();
11778         int userId = ActivityManager.getCurrentUser();
11779         final long identity = Binder.clearCallingIdentity();
11780         try {
11781             return getGbaManager(subId).overrideServicePackage(packageName, userId);
11782         } finally {
11783             Binder.restoreCallingIdentity(identity);
11784         }
11785     }
11786 
11787     /**
11788      * Return the package name of the currently bound GbaService.
11789      *
11790      * @param subId The sim that the GbaService is associated with.
11791      * @return the package name of the GbaService configuration, null if GBA is not supported.
11792      */
11793     @Override
getBoundGbaService(int subId)11794     public String getBoundGbaService(int subId) {
11795         enforceReadPrivilegedPermission("getBoundGbaServicePackage");
11796 
11797         final long identity = Binder.clearCallingIdentity();
11798         try {
11799             return getGbaManager(subId).getServicePackage();
11800         } finally {
11801             Binder.restoreCallingIdentity(identity);
11802         }
11803     }
11804 
11805     /**
11806      * Set the release time for telephony to unbind GbaService.
11807      *
11808      * @param subId The sim that the GbaService is associated with.
11809      * @param interval The release time to unbind GbaService by millisecond.
11810      * @return true if setting the GbaService to bind to succeeded, false if it did not.
11811      */
11812     @Override
setGbaReleaseTimeOverride(int subId, int interval)11813     public boolean setGbaReleaseTimeOverride(int subId, int interval) {
11814         enforceModifyPermission();
11815 
11816         final long identity = Binder.clearCallingIdentity();
11817         try {
11818             return getGbaManager(subId).overrideReleaseTime(interval);
11819         } finally {
11820             Binder.restoreCallingIdentity(identity);
11821         }
11822     }
11823 
11824     /**
11825      * Return the release time for telephony to unbind GbaService.
11826      *
11827      * @param subId The sim that the GbaService is associated with.
11828      * @return The release time to unbind GbaService by millisecond.
11829      */
11830     @Override
getGbaReleaseTime(int subId)11831     public int getGbaReleaseTime(int subId) {
11832         enforceReadPrivilegedPermission("getGbaReleaseTime");
11833 
11834         final long identity = Binder.clearCallingIdentity();
11835         try {
11836             return getGbaManager(subId).getReleaseTime();
11837         } finally {
11838             Binder.restoreCallingIdentity(identity);
11839         }
11840     }
11841 
getGbaManager(int subId)11842     private GbaManager getGbaManager(int subId) {
11843         GbaManager instance = GbaManager.getInstance(subId);
11844         if (instance == null) {
11845             String packageName = mApp.getResources().getString(R.string.config_gba_package);
11846             int releaseTime = mApp.getResources().getInteger(R.integer.config_gba_release_time);
11847             instance = GbaManager.make(mApp, subId, packageName, releaseTime, mFeatureFlags);
11848         }
11849         return instance;
11850     }
11851 
11852     /**
11853      * indicate whether the device and the carrier can support
11854      * RCS VoLTE single registration.
11855      */
11856     @Override
isRcsVolteSingleRegistrationCapable(int subId)11857     public boolean isRcsVolteSingleRegistrationCapable(int subId) {
11858         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
11859                 Binder.getCallingUid(), "isRcsVolteSingleRegistrationCapable",
11860                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
11861                 permission.READ_PRIVILEGED_PHONE_STATE);
11862 
11863         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11864             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11865         }
11866 
11867         final long identity = Binder.clearCallingIdentity();
11868         try {
11869             RcsProvisioningMonitor rpm = RcsProvisioningMonitor.getInstance();
11870             if (rpm != null) {
11871                 Boolean isCapable = rpm.isRcsVolteSingleRegistrationEnabled(subId);
11872                 if (isCapable != null) {
11873                     return isCapable;
11874                 }
11875             }
11876             throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
11877                     "service is temporarily unavailable.");
11878         } finally {
11879             Binder.restoreCallingIdentity(identity);
11880         }
11881     }
11882 
11883     /**
11884      * Register RCS provisioning callback.
11885      */
11886     @Override
registerRcsProvisioningCallback(int subId, IRcsConfigCallback callback)11887     public void registerRcsProvisioningCallback(int subId,
11888             IRcsConfigCallback callback) {
11889         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
11890                 Binder.getCallingUid(), "registerRcsProvisioningCallback",
11891                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
11892                 permission.READ_PRIVILEGED_PHONE_STATE);
11893 
11894         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11895             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11896         }
11897         if (!CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, getCurrentPackageName(),
11898                 Binder.getCallingUserHandle())) {
11899             if (!isImsAvailableOnDevice()) {
11900                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
11901                         "IMS not available on device.");
11902             }
11903         } else {
11904             enforceTelephonyFeatureWithException(getCurrentPackageName(),
11905                     FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION, "registerRcsProvisioningCallback");
11906         }
11907 
11908         final long identity = Binder.clearCallingIdentity();
11909         try {
11910             if (!RcsProvisioningMonitor.getInstance()
11911                     .registerRcsProvisioningCallback(subId, callback)) {
11912                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
11913                         "Active subscription not found.");
11914             }
11915         } finally {
11916             Binder.restoreCallingIdentity(identity);
11917         }
11918     }
11919 
11920     /**
11921      * Unregister RCS provisioning callback.
11922      */
11923     @Override
unregisterRcsProvisioningCallback(int subId, IRcsConfigCallback callback)11924     public void unregisterRcsProvisioningCallback(int subId,
11925             IRcsConfigCallback callback) {
11926         TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
11927                 Binder.getCallingUid(), "unregisterRcsProvisioningCallback",
11928                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION,
11929                 permission.READ_PRIVILEGED_PHONE_STATE);
11930 
11931         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11932             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11933         }
11934 
11935         if (!CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, getCurrentPackageName(),
11936                 Binder.getCallingUserHandle())) {
11937             if (!isImsAvailableOnDevice()) {
11938                 // operation failed silently
11939                 Rlog.w(LOG_TAG, "IMS not available on device.");
11940                 return;
11941             }
11942         } else {
11943             enforceTelephonyFeatureWithException(getCurrentPackageName(),
11944                     FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION,
11945                     "unregisterRcsProvisioningCallback");
11946         }
11947 
11948         final long identity = Binder.clearCallingIdentity();
11949         try {
11950             RcsProvisioningMonitor.getInstance()
11951                     .unregisterRcsProvisioningCallback(subId, callback);
11952         } finally {
11953             Binder.restoreCallingIdentity(identity);
11954         }
11955     }
11956 
11957     /**
11958      * trigger RCS reconfiguration.
11959      */
triggerRcsReconfiguration(int subId)11960     public void triggerRcsReconfiguration(int subId) {
11961         TelephonyPermissions.enforceAnyPermissionGranted(mApp, Binder.getCallingUid(),
11962                 "triggerRcsReconfiguration",
11963                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
11964 
11965         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11966             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11967         }
11968         if (!CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, getCurrentPackageName(),
11969                 Binder.getCallingUserHandle())) {
11970             if (!isImsAvailableOnDevice()) {
11971                 // ProvisioningManager can not handle ServiceSpecificException.
11972                 // Throw the IllegalStateException and annotate ProvisioningManager.
11973                 throw new IllegalStateException("IMS not available on device.");
11974             }
11975         } else {
11976             enforceTelephonyFeatureWithException(getCurrentPackageName(),
11977                     FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION, "triggerRcsReconfiguration");
11978         }
11979 
11980         final long identity = Binder.clearCallingIdentity();
11981         try {
11982             RcsProvisioningMonitor.getInstance().requestReconfig(subId);
11983         } finally {
11984             Binder.restoreCallingIdentity(identity);
11985         }
11986     }
11987 
11988     /**
11989      * Provide the client configuration parameters of the RCS application.
11990      */
setRcsClientConfiguration(int subId, RcsClientConfiguration rcc)11991     public void setRcsClientConfiguration(int subId, RcsClientConfiguration rcc) {
11992         TelephonyPermissions.enforceAnyPermissionGranted(mApp, Binder.getCallingUid(),
11993                 "setRcsClientConfiguration",
11994                 Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
11995 
11996         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
11997             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
11998         }
11999         if (!CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, getCurrentPackageName(),
12000                 Binder.getCallingUserHandle())) {
12001             if (!isImsAvailableOnDevice()) {
12002                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
12003                         "IMS not available on device.");
12004             }
12005         } else {
12006             enforceTelephonyFeatureWithException(getCurrentPackageName(),
12007                     FEATURE_TELEPHONY_IMS_SINGLE_REGISTRATION, "setRcsClientConfiguration");
12008         }
12009 
12010         final long identity = Binder.clearCallingIdentity();
12011 
12012         try {
12013             IImsConfig configBinder = getImsConfig(getSlotIndex(subId), ImsFeature.FEATURE_RCS);
12014             if (configBinder == null) {
12015                 Rlog.e(LOG_TAG, "null result for setRcsClientConfiguration");
12016                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION,
12017                         "could not find the requested subscription");
12018             } else {
12019                 configBinder.setRcsClientConfiguration(rcc);
12020             }
12021 
12022             RcsStats.getInstance().onRcsClientProvisioningStats(subId,
12023                     RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT);
12024         } catch (RemoteException e) {
12025             Rlog.e(LOG_TAG, "fail to setRcsClientConfiguration " + e.getMessage());
12026             throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
12027                     "service is temporarily unavailable.");
12028         } finally {
12029             Binder.restoreCallingIdentity(identity);
12030         }
12031     }
12032 
12033     /**
12034      * Enables or disables the test mode for RCS VoLTE single registration.
12035      */
12036     @Override
setRcsSingleRegistrationTestModeEnabled(boolean enabled)12037     public void setRcsSingleRegistrationTestModeEnabled(boolean enabled) {
12038         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12039                 "setRcsSingleRegistrationTestModeEnabled");
12040 
12041         RcsProvisioningMonitor.getInstance().setTestModeEnabled(enabled);
12042     }
12043 
12044     /**
12045      * Gets the test mode for RCS VoLTE single registration.
12046      */
12047     @Override
getRcsSingleRegistrationTestModeEnabled()12048     public boolean getRcsSingleRegistrationTestModeEnabled() {
12049         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12050                 "getRcsSingleRegistrationTestModeEnabled");
12051 
12052         return RcsProvisioningMonitor.getInstance().getTestModeEnabled();
12053     }
12054 
12055     /**
12056      * Overrides the config of RCS VoLTE single registration enabled for the device.
12057      */
12058     @Override
setDeviceSingleRegistrationEnabledOverride(String enabledStr)12059     public void setDeviceSingleRegistrationEnabledOverride(String enabledStr) {
12060         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12061                 "setDeviceSingleRegistrationEnabledOverride");
12062         enforceModifyPermission();
12063 
12064         Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
12065                 : Boolean.parseBoolean(enabledStr);
12066         RcsProvisioningMonitor.getInstance().overrideDeviceSingleRegistrationEnabled(enabled);
12067         mApp.imsRcsController.setDeviceSingleRegistrationSupportOverride(enabled);
12068     }
12069 
12070     /**
12071      * Sends a device to device communication message.  Only usable via shell.
12072      * @param message message to send.
12073      * @param value message value.
12074      */
12075     @Override
sendDeviceToDeviceMessage(int message, int value)12076     public void sendDeviceToDeviceMessage(int message, int value) {
12077         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12078                 "sendDeviceToDeviceMessage");
12079         enforceModifyPermission();
12080 
12081         final long identity = Binder.clearCallingIdentity();
12082         try {
12083             TelephonyConnectionService service =
12084                     TelecomAccountRegistry.getInstance(null).getTelephonyConnectionService();
12085             if (service == null) {
12086                 Rlog.e(LOG_TAG, "sendDeviceToDeviceMessage: not in a call.");
12087                 return;
12088             }
12089             service.sendTestDeviceToDeviceMessage(message, value);
12090         } finally {
12091             Binder.restoreCallingIdentity(identity);
12092         }
12093     }
12094 
12095     /**
12096      * Sets the specified device to device transport active.
12097      * @param transport The transport to set active.
12098      */
12099     @Override
setActiveDeviceToDeviceTransport(@onNull String transport)12100     public void setActiveDeviceToDeviceTransport(@NonNull String transport) {
12101         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12102                 "setActiveDeviceToDeviceTransport");
12103         enforceModifyPermission();
12104 
12105         final long identity = Binder.clearCallingIdentity();
12106         try {
12107             TelephonyConnectionService service =
12108                     TelecomAccountRegistry.getInstance(null).getTelephonyConnectionService();
12109             if (service == null) {
12110                 Rlog.e(LOG_TAG, "setActiveDeviceToDeviceTransport: not in a call.");
12111                 return;
12112             }
12113             service.setActiveDeviceToDeviceTransport(transport);
12114         } finally {
12115             Binder.restoreCallingIdentity(identity);
12116         }
12117     }
12118 
12119     @Override
setDeviceToDeviceForceEnabled(boolean isForceEnabled)12120     public void setDeviceToDeviceForceEnabled(boolean isForceEnabled) {
12121         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12122                 "setDeviceToDeviceForceEnabled");
12123 
12124         final long identity = Binder.clearCallingIdentity();
12125         try {
12126             Arrays.stream(PhoneFactory.getPhones()).forEach(
12127                     p -> {
12128                         Phone thePhone = p.getImsPhone();
12129                         if (thePhone != null && thePhone instanceof ImsPhone) {
12130                             ImsPhone imsPhone = (ImsPhone) thePhone;
12131                             CallTracker tracker = imsPhone.getCallTracker();
12132                             if (tracker != null && tracker instanceof ImsPhoneCallTracker) {
12133                                 ImsPhoneCallTracker imsPhoneCallTracker =
12134                                         (ImsPhoneCallTracker) tracker;
12135                                 imsPhoneCallTracker.setDeviceToDeviceForceEnabled(isForceEnabled);
12136                             }
12137                         }
12138                     }
12139             );
12140         } finally {
12141             Binder.restoreCallingIdentity(identity);
12142         }
12143     }
12144 
12145     /**
12146      * Gets the config of RCS VoLTE single registration enabled for the device.
12147      */
12148     @Override
getDeviceSingleRegistrationEnabled()12149     public boolean getDeviceSingleRegistrationEnabled() {
12150         enforceReadPrivilegedPermission("getDeviceSingleRegistrationEnabled");
12151         return RcsProvisioningMonitor.getInstance().getDeviceSingleRegistrationEnabled();
12152     }
12153 
12154     /**
12155      * Overrides the config of RCS VoLTE single registration enabled for the carrier/subscription.
12156      */
12157     @Override
setCarrierSingleRegistrationEnabledOverride(int subId, String enabledStr)12158     public boolean setCarrierSingleRegistrationEnabledOverride(int subId, String enabledStr) {
12159         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12160                 "setCarrierSingleRegistrationEnabledOverride");
12161         enforceModifyPermission();
12162 
12163         Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
12164                 : Boolean.parseBoolean(enabledStr);
12165         return RcsProvisioningMonitor.getInstance().overrideCarrierSingleRegistrationEnabled(
12166                 subId, enabled);
12167     }
12168 
12169     /**
12170      * Gets the config of RCS VoLTE single registration enabled for the carrier/subscription.
12171      */
12172     @Override
getCarrierSingleRegistrationEnabled(int subId)12173     public boolean getCarrierSingleRegistrationEnabled(int subId) {
12174         enforceReadPrivilegedPermission("getCarrierSingleRegistrationEnabled");
12175         return RcsProvisioningMonitor.getInstance().getCarrierSingleRegistrationEnabled(subId);
12176     }
12177 
12178     /**
12179      * Overrides the ims feature validation result
12180      */
12181     @Override
setImsFeatureValidationOverride(int subId, String enabledStr)12182     public boolean setImsFeatureValidationOverride(int subId, String enabledStr) {
12183         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12184                 "setImsFeatureValidationOverride");
12185 
12186         Boolean enabled = "NULL".equalsIgnoreCase(enabledStr) ? null
12187                 : Boolean.parseBoolean(enabledStr);
12188         return RcsProvisioningMonitor.getInstance().overrideImsFeatureValidation(
12189                 subId, enabled);
12190     }
12191 
12192     /**
12193      * Gets the ims feature validation override value
12194      */
12195     @Override
getImsFeatureValidationOverride(int subId)12196     public boolean getImsFeatureValidationOverride(int subId) {
12197         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12198                 "getImsFeatureValidationOverride");
12199         return RcsProvisioningMonitor.getInstance().getImsFeatureValidationOverride(subId);
12200     }
12201 
12202     /**
12203      * Get the mobile provisioning url that is used to launch a browser to allow users to manage
12204      * their mobile plan.
12205      */
12206     @Override
getMobileProvisioningUrl()12207     public String getMobileProvisioningUrl() {
12208         enforceReadPrivilegedPermission("getMobileProvisioningUrl");
12209         final long identity = Binder.clearCallingIdentity();
12210         try {
12211             return getDefaultPhone().getMobileProvisioningUrl();
12212         } finally {
12213             Binder.restoreCallingIdentity(identity);
12214         }
12215     }
12216 
12217     /**
12218      * Get the EAB contact from the EAB database.
12219      */
12220     @Override
getContactFromEab(String contact)12221     public String getContactFromEab(String contact) {
12222         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getContactFromEab");
12223         enforceModifyPermission();
12224         final long identity = Binder.clearCallingIdentity();
12225         try {
12226             return EabUtil.getContactFromEab(getDefaultPhone().getContext(), contact);
12227         } finally {
12228             Binder.restoreCallingIdentity(identity);
12229         }
12230     }
12231 
12232     /**
12233      * Get the EAB capability from the EAB database.
12234      */
12235     @Override
getCapabilityFromEab(String contact)12236     public String getCapabilityFromEab(String contact) {
12237         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getCapabilityFromEab");
12238         enforceModifyPermission();
12239         final long identity = Binder.clearCallingIdentity();
12240         try {
12241             return EabUtil.getCapabilityFromEab(getDefaultPhone().getContext(), contact);
12242         } finally {
12243             Binder.restoreCallingIdentity(identity);
12244         }
12245     }
12246 
12247     /**
12248      * Remove the EAB contacts from the EAB database.
12249      */
12250     @Override
removeContactFromEab(int subId, String contacts)12251     public int removeContactFromEab(int subId, String contacts) {
12252         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "removeCapabilitiesFromEab");
12253         enforceModifyPermission();
12254         final long identity = Binder.clearCallingIdentity();
12255         try {
12256             return EabUtil.removeContactFromEab(subId, contacts, getDefaultPhone().getContext());
12257         } finally {
12258             Binder.restoreCallingIdentity(identity);
12259         }
12260     }
12261 
12262     @Override
getDeviceUceEnabled()12263     public boolean getDeviceUceEnabled() {
12264         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getDeviceUceEnabled");
12265         final long identity = Binder.clearCallingIdentity();
12266         try {
12267             return mApp.getDeviceUceEnabled();
12268         } finally {
12269             Binder.restoreCallingIdentity(identity);
12270         }
12271     }
12272 
12273     @Override
setDeviceUceEnabled(boolean isEnabled)12274     public void setDeviceUceEnabled(boolean isEnabled) {
12275         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setDeviceUceEnabled");
12276         final long identity = Binder.clearCallingIdentity();
12277         try {
12278             mApp.setDeviceUceEnabled(isEnabled);
12279         } finally {
12280             Binder.restoreCallingIdentity(identity);
12281         }
12282     }
12283 
12284     /**
12285      * Add new feature tags to the Set used to calculate the capabilities in PUBLISH.
12286      * @return current RcsContactUceCapability instance that will be used for PUBLISH.
12287      */
12288     // Used for SHELL command only right now.
12289     @Override
addUceRegistrationOverrideShell(int subId, List<String> featureTags)12290     public RcsContactUceCapability addUceRegistrationOverrideShell(int subId,
12291             List<String> featureTags) {
12292         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12293                 "addUceRegistrationOverrideShell");
12294         final long identity = Binder.clearCallingIdentity();
12295         try {
12296             return mApp.imsRcsController.addUceRegistrationOverrideShell(subId,
12297                     new ArraySet<>(featureTags));
12298         } catch (ImsException e) {
12299             throw new ServiceSpecificException(e.getCode(), e.getMessage());
12300         } finally {
12301             Binder.restoreCallingIdentity(identity);
12302         }
12303     }
12304 
12305     /**
12306      * Remove existing feature tags to the Set used to calculate the capabilities in PUBLISH.
12307      * @return current RcsContactUceCapability instance that will be used for PUBLISH.
12308      */
12309     // Used for SHELL command only right now.
12310     @Override
removeUceRegistrationOverrideShell(int subId, List<String> featureTags)12311     public RcsContactUceCapability removeUceRegistrationOverrideShell(int subId,
12312             List<String> featureTags) {
12313         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12314                 "removeUceRegistrationOverrideShell");
12315         final long identity = Binder.clearCallingIdentity();
12316         try {
12317             return mApp.imsRcsController.removeUceRegistrationOverrideShell(subId,
12318                     new ArraySet<>(featureTags));
12319         } catch (ImsException e) {
12320             throw new ServiceSpecificException(e.getCode(), e.getMessage());
12321         } finally {
12322             Binder.restoreCallingIdentity(identity);
12323         }
12324     }
12325 
12326     /**
12327      * Clear all overrides in the Set used to calculate the capabilities in PUBLISH.
12328      * @return current RcsContactUceCapability instance that will be used for PUBLISH.
12329      */
12330     // Used for SHELL command only right now.
12331     @Override
clearUceRegistrationOverrideShell(int subId)12332     public RcsContactUceCapability clearUceRegistrationOverrideShell(int subId) {
12333         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12334                 "clearUceRegistrationOverrideShell");
12335         final long identity = Binder.clearCallingIdentity();
12336         try {
12337             return mApp.imsRcsController.clearUceRegistrationOverrideShell(subId);
12338         } catch (ImsException e) {
12339             throw new ServiceSpecificException(e.getCode(), e.getMessage());
12340         } finally {
12341             Binder.restoreCallingIdentity(identity);
12342         }
12343     }
12344 
12345     /**
12346      * @return current RcsContactUceCapability instance that will be used for PUBLISH.
12347      */
12348     // Used for SHELL command only right now.
12349     @Override
getLatestRcsContactUceCapabilityShell(int subId)12350     public RcsContactUceCapability getLatestRcsContactUceCapabilityShell(int subId) {
12351         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
12352                 "getLatestRcsContactUceCapabilityShell");
12353         final long identity = Binder.clearCallingIdentity();
12354         try {
12355             return mApp.imsRcsController.getLatestRcsContactUceCapabilityShell(subId);
12356         } catch (ImsException e) {
12357             throw new ServiceSpecificException(e.getCode(), e.getMessage());
12358         } finally {
12359             Binder.restoreCallingIdentity(identity);
12360         }
12361     }
12362 
12363     /**
12364      * Returns the last PIDF XML sent to the network during the last PUBLISH or "none" if the
12365      * device does not have an active PUBLISH.
12366      */
12367     // Used for SHELL command only right now.
12368     @Override
getLastUcePidfXmlShell(int subId)12369     public String getLastUcePidfXmlShell(int subId) {
12370         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "uceGetLastPidfXml");
12371         final long identity = Binder.clearCallingIdentity();
12372         try {
12373             return mApp.imsRcsController.getLastUcePidfXmlShell(subId);
12374         } catch (ImsException e) {
12375             throw new ServiceSpecificException(e.getCode(), e.getMessage());
12376         } finally {
12377             Binder.restoreCallingIdentity(identity);
12378         }
12379     }
12380 
12381     /**
12382      * Remove UCE requests cannot be sent to the network status.
12383      */
12384     // Used for SHELL command only right now.
12385     @Override
removeUceRequestDisallowedStatus(int subId)12386     public boolean removeUceRequestDisallowedStatus(int subId) {
12387         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "uceRemoveDisallowedStatus");
12388         final long identity = Binder.clearCallingIdentity();
12389         try {
12390             return mApp.imsRcsController.removeUceRequestDisallowedStatus(subId);
12391         } catch (ImsException e) {
12392             throw new ServiceSpecificException(e.getCode(), e.getMessage());
12393         } finally {
12394             Binder.restoreCallingIdentity(identity);
12395         }
12396     }
12397 
12398     /**
12399      * Remove UCE requests cannot be sent to the network status.
12400      */
12401     // Used for SHELL command only.
12402     @Override
setCapabilitiesRequestTimeout(int subId, long timeoutAfterMs)12403     public boolean setCapabilitiesRequestTimeout(int subId, long timeoutAfterMs) {
12404         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCapRequestTimeout");
12405         final long identity = Binder.clearCallingIdentity();
12406         try {
12407             return mApp.imsRcsController.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
12408         } catch (ImsException e) {
12409             throw new ServiceSpecificException(e.getCode(), e.getMessage());
12410         } finally {
12411             Binder.restoreCallingIdentity(identity);
12412         }
12413     }
12414 
12415     @Override
setSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request, String callingPackage)12416     public void setSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request,
12417             String callingPackage) {
12418         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
12419                 mApp, subId, "setSignalStrengthUpdateRequest");
12420 
12421         enforceTelephonyFeatureWithException(callingPackage,
12422                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "setSignalStrengthUpdateRequest");
12423 
12424         final int callingUid = Binder.getCallingUid();
12425         // Verify that tha callingPackage belongs to the calling UID
12426         mApp.getSystemService(AppOpsManager.class)
12427                 .checkPackage(callingUid, callingPackage);
12428 
12429         validateSignalStrengthUpdateRequest(mApp, request, callingUid);
12430 
12431         final long identity = Binder.clearCallingIdentity();
12432         try {
12433             Object result = sendRequest(CMD_SET_SIGNAL_STRENGTH_UPDATE_REQUEST,
12434                     new Pair<Integer, SignalStrengthUpdateRequest>(callingUid, request), subId);
12435 
12436             if (result instanceof IllegalStateException) {
12437                 throw (IllegalStateException) result;
12438             }
12439         } finally {
12440             Binder.restoreCallingIdentity(identity);
12441         }
12442     }
12443 
12444     @Override
clearSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request, String callingPackage)12445     public void clearSignalStrengthUpdateRequest(int subId, SignalStrengthUpdateRequest request,
12446             String callingPackage) {
12447         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
12448                 mApp, subId, "clearSignalStrengthUpdateRequest");
12449 
12450         enforceTelephonyFeatureWithException(callingPackage,
12451                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS, "clearSignalStrengthUpdateRequest");
12452 
12453         final int callingUid = Binder.getCallingUid();
12454         // Verify that tha callingPackage belongs to the calling UID
12455         mApp.getSystemService(AppOpsManager.class)
12456                 .checkPackage(callingUid, callingPackage);
12457 
12458         final long identity = Binder.clearCallingIdentity();
12459         try {
12460             Object result = sendRequest(CMD_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST,
12461                     new Pair<Integer, SignalStrengthUpdateRequest>(callingUid, request), subId);
12462 
12463             if (result instanceof IllegalStateException) {
12464                 throw (IllegalStateException) result;
12465             }
12466         } finally {
12467             Binder.restoreCallingIdentity(identity);
12468         }
12469     }
12470 
validateSignalStrengthUpdateRequest(Context context, SignalStrengthUpdateRequest request, int callingUid)12471     private static void validateSignalStrengthUpdateRequest(Context context,
12472             SignalStrengthUpdateRequest request, int callingUid) {
12473         if (TelephonyPermissions.isSystemOrPhone(callingUid)) {
12474             // phone/system process do not have further restriction on request
12475             return;
12476         }
12477 
12478         // Applications has restrictions on how to use the request:
12479         // Non-system callers need permission to set mIsSystemThresholdReportingRequestedWhileIdle
12480         if (request.isSystemThresholdReportingRequestedWhileIdle()) {
12481             context.enforceCallingOrSelfPermission(
12482                     android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH,
12483                     "validateSignalStrengthUpdateRequest");
12484         }
12485 
12486         for (SignalThresholdInfo info : request.getSignalThresholdInfos()) {
12487             // Only system caller can set mHysteresisMs/mIsEnabled.
12488             if (info.getHysteresisMs() != SignalThresholdInfo.HYSTERESIS_MS_DISABLED
12489                     || info.isEnabled()) {
12490                 throw new IllegalArgumentException(
12491                         "Only system can set hide fields in SignalThresholdInfo");
12492             }
12493 
12494             // Thresholds length for each RAN need in range. This has been validated in
12495             // SignalThresholdInfo#Builder#setThreshold. Here we prevent apps calling hide method
12496             // setThresholdUnlimited (e.g. through reflection) with too short or too long thresholds
12497             final int[] thresholds = info.getThresholds();
12498             Objects.requireNonNull(thresholds);
12499             if (thresholds.length < SignalThresholdInfo.getMinimumNumberOfThresholdsAllowed()
12500                     || thresholds.length
12501                     > SignalThresholdInfo.getMaximumNumberOfThresholdsAllowed()) {
12502                 throw new IllegalArgumentException(
12503                         "thresholds length is out of range: " + thresholds.length);
12504             }
12505         }
12506     }
12507 
12508     /**
12509      * Gets the current phone capability.
12510      *
12511      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
12512      * @return the PhoneCapability which describes the data connection capability of modem.
12513      * It's used to evaluate possible phone config change, for example from single
12514      * SIM device to multi-SIM device.
12515      */
12516     @Override
getPhoneCapability()12517     public PhoneCapability getPhoneCapability() {
12518         enforceReadPrivilegedPermission("getPhoneCapability");
12519 
12520         enforceTelephonyFeatureWithException(getCurrentPackageName(),
12521                 PackageManager.FEATURE_TELEPHONY, "getPhoneCapability");
12522 
12523         final long identity = Binder.clearCallingIdentity();
12524         try {
12525             return mPhoneConfigurationManager.getCurrentPhoneCapability();
12526         } finally {
12527             Binder.restoreCallingIdentity(identity);
12528         }
12529     }
12530 
12531     /**
12532      * Prepare TelephonyManager for an unattended reboot. The reboot is
12533      * required to be done shortly after the API is invoked.
12534      */
12535     @Override
12536     @TelephonyManager.PrepareUnattendedRebootResult
prepareForUnattendedReboot()12537     public int prepareForUnattendedReboot() {
12538         WorkSource workSource = getWorkSource(Binder.getCallingUid());
12539         enforceRebootPermission();
12540 
12541         enforceTelephonyFeatureWithException(getCurrentPackageName(),
12542                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "prepareForUnattendedReboot");
12543 
12544         final long identity = Binder.clearCallingIdentity();
12545         try {
12546             return (int) sendRequest(CMD_PREPARE_UNATTENDED_REBOOT, null, workSource);
12547         } finally {
12548             Binder.restoreCallingIdentity(identity);
12549         }
12550     }
12551 
12552     /**
12553      * Request to get the current slicing configuration including URSP rules and
12554      * NSSAIs (configured, allowed and rejected).
12555      *
12556      * Requires carrier privileges or READ_PRIVILEGED_PHONE_STATE permission.
12557      */
12558     @Override
getSlicingConfig(ResultReceiver callback)12559     public void getSlicingConfig(ResultReceiver callback) {
12560         TelephonyPermissions
12561                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
12562                         mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, "getSlicingConfig");
12563 
12564         enforceTelephonyFeatureWithException(getCurrentPackageName(),
12565                 PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS,
12566                 "getSlicingConfig");
12567 
12568         final long identity = Binder.clearCallingIdentity();
12569         try {
12570             Phone phone = getDefaultPhone();
12571             sendRequestAsync(CMD_GET_SLICING_CONFIG, callback, phone, null);
12572         } finally {
12573             Binder.restoreCallingIdentity(identity);
12574         }
12575     }
12576 
12577     /**
12578      * Check whether the given premium capability is available for purchase from the carrier.
12579      *
12580      * @param capability The premium capability to check.
12581      * @param subId The subId to check the premium capability for.
12582      *
12583      * @return Whether the given premium capability is available to purchase.
12584      */
12585     @Override
isPremiumCapabilityAvailableForPurchase(int capability, int subId)12586     public boolean isPremiumCapabilityAvailableForPurchase(int capability, int subId) {
12587         if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
12588                 mApp, "isPremiumCapabilityAvailableForPurchase")) {
12589             log("Premium capability "
12590                     + TelephonyManager.convertPremiumCapabilityToString(capability)
12591                     + " is not available for purchase due to missing permissions.");
12592             throw new SecurityException("isPremiumCapabilityAvailableForPurchase requires "
12593                     + "permission READ_BASIC_PHONE_STATE.");
12594         }
12595 
12596         enforceTelephonyFeatureWithException(getCurrentPackageName(),
12597                 PackageManager.FEATURE_TELEPHONY_DATA, "isPremiumCapabilityAvailableForPurchase");
12598 
12599         Phone phone = getPhone(subId);
12600         if (phone == null) {
12601             loge("isPremiumCapabilityAvailableForPurchase: phone is null, subId=" + subId);
12602             return false;
12603         }
12604         final long identity = Binder.clearCallingIdentity();
12605         try {
12606             return SlicePurchaseController.getInstance(phone, mFeatureFlags)
12607                     .isPremiumCapabilityAvailableForPurchase(capability);
12608         } finally {
12609             Binder.restoreCallingIdentity(identity);
12610         }
12611     }
12612 
12613     /**
12614      * Purchase the given premium capability from the carrier.
12615      *
12616      * @param capability The premium capability to purchase.
12617      * @param callback The result of the purchase request.
12618      * @param subId The subId to purchase the premium capability for.
12619      */
12620     @Override
purchasePremiumCapability(int capability, IIntegerConsumer callback, int subId)12621     public void purchasePremiumCapability(int capability, IIntegerConsumer callback, int subId) {
12622         log("purchasePremiumCapability: capability="
12623                 + TelephonyManager.convertPremiumCapabilityToString(capability) + ", caller="
12624                 + getCurrentPackageName());
12625 
12626         if (!TelephonyPermissions.checkCallingOrSelfReadNonDangerousPhoneStateNoThrow(
12627                 mApp, "purchasePremiumCapability")) {
12628             log("purchasePremiumCapability "
12629                     + TelephonyManager.convertPremiumCapabilityToString(capability)
12630                     + " failed due to missing permissions.");
12631             throw new SecurityException("purchasePremiumCapability requires permission "
12632                     + "READ_BASIC_PHONE_STATE.");
12633         } else if (!TelephonyPermissions.checkInternetPermissionNoThrow(
12634                 mApp, "purchasePremiumCapability")) {
12635             log("purchasePremiumCapability "
12636                     + TelephonyManager.convertPremiumCapabilityToString(capability)
12637                     + " failed due to missing permissions.");
12638             throw new SecurityException("purchasePremiumCapability requires permission INTERNET.");
12639         }
12640 
12641         enforceTelephonyFeatureWithException(getCurrentPackageName(),
12642                 PackageManager.FEATURE_TELEPHONY_DATA, "purchasePremiumCapability");
12643 
12644         Phone phone = getPhone(subId);
12645         if (phone == null) {
12646             try {
12647                 int result = TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_REQUEST_FAILED;
12648                 callback.accept(result);
12649                 loge("purchasePremiumCapability: phone is null, subId=" + subId);
12650             } catch (RemoteException e) {
12651                 String logStr = "Purchase premium capability "
12652                         + TelephonyManager.convertPremiumCapabilityToString(capability)
12653                         + " failed due to RemoteException handling null phone: " + e;
12654                 if (DBG) log(logStr);
12655                 AnomalyReporter.reportAnomaly(
12656                         UUID.fromString(PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID), logStr);
12657             }
12658             return;
12659         }
12660 
12661         String callingProcess;
12662         try {
12663             if (mFeatureFlags.hsumPackageManager()) {
12664                 callingProcess = mApp.getPackageManager().getApplicationInfoAsUser(
12665                         getCurrentPackageName(), 0, Binder.getCallingUserHandle()).processName;
12666             } else {
12667                 callingProcess = mApp.getPackageManager().getApplicationInfo(
12668                         getCurrentPackageName(), 0).processName;
12669             }
12670         } catch (PackageManager.NameNotFoundException e) {
12671             callingProcess = getCurrentPackageName();
12672         }
12673 
12674         boolean isVisible = false;
12675         ActivityManager am = mApp.getSystemService(ActivityManager.class);
12676         if (am != null) {
12677             List<ActivityManager.RunningAppProcessInfo> processes = am.getRunningAppProcesses();
12678             if (processes != null) {
12679                 for (ActivityManager.RunningAppProcessInfo process : processes) {
12680                     log("purchasePremiumCapability: process " + process.processName
12681                             + " has importance " + process.importance);
12682                     if (process.processName.equals(callingProcess) && process.importance
12683                             <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE) {
12684                         isVisible = true;
12685                         break;
12686                     }
12687                 }
12688             }
12689         }
12690 
12691         if (!isVisible) {
12692             try {
12693                 int result = TelephonyManager.PURCHASE_PREMIUM_CAPABILITY_RESULT_NOT_FOREGROUND;
12694                 callback.accept(result);
12695                 loge("purchasePremiumCapability: " + callingProcess + " is not in the foreground.");
12696             } catch (RemoteException e) {
12697                 String logStr = "Purchase premium capability "
12698                         + TelephonyManager.convertPremiumCapabilityToString(capability)
12699                         + " failed due to RemoteException handling background application: " + e;
12700                 if (DBG) log(logStr);
12701                 AnomalyReporter.reportAnomaly(
12702                         UUID.fromString(PURCHASE_PREMIUM_CAPABILITY_ERROR_UUID), logStr);
12703             }
12704             return;
12705         }
12706 
12707         sendRequestAsync(CMD_PURCHASE_PREMIUM_CAPABILITY,
12708                 new PurchasePremiumCapabilityArgument(capability, callback), phone, null);
12709     }
12710 
12711     /**
12712      * Register an IMS connection state callback
12713      */
12714     @Override
registerImsStateCallback(int subId, int feature, IImsStateCallback cb, String callingPackage)12715     public void registerImsStateCallback(int subId, int feature, IImsStateCallback cb,
12716             String callingPackage) {
12717         if (feature == ImsFeature.FEATURE_MMTEL) {
12718             // ImsMmTelManager
12719             // The following also checks READ_PRIVILEGED_PHONE_STATE.
12720             TelephonyPermissions
12721                     .enforceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
12722                             mApp, subId, "registerImsStateCallback");
12723         } else if (feature == ImsFeature.FEATURE_RCS) {
12724             // ImsRcsManager or SipDelegateManager
12725             TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(mApp, subId,
12726                     Binder.getCallingUid(), "registerImsStateCallback",
12727                     Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
12728                     Manifest.permission.READ_PRECISE_PHONE_STATE,
12729                     Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE,
12730                     Manifest.permission.PERFORM_IMS_SINGLE_REGISTRATION);
12731         }
12732 
12733         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
12734             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
12735                     "IMS not available on device.");
12736         }
12737 
12738         if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
12739             throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
12740         }
12741 
12742         ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
12743         if (controller == null) {
12744             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
12745                     "IMS not available on device.");
12746         }
12747 
12748         if (callingPackage == null) {
12749             callingPackage = getCurrentPackageName();
12750         }
12751 
12752         final long token = Binder.clearCallingIdentity();
12753         try {
12754             int slotId = getSlotIndexOrException(subId);
12755             controller.registerImsStateCallback(subId, feature, cb, callingPackage);
12756         } catch (ImsException e) {
12757             throw new ServiceSpecificException(e.getCode());
12758         } finally {
12759             Binder.restoreCallingIdentity(token);
12760         }
12761     }
12762 
12763     /**
12764      * Unregister an IMS connection state callback
12765      */
12766     @Override
unregisterImsStateCallback(IImsStateCallback cb)12767     public void unregisterImsStateCallback(IImsStateCallback cb) {
12768         final long token = Binder.clearCallingIdentity();
12769         ImsStateCallbackController controller = ImsStateCallbackController.getInstance();
12770         if (controller == null) {
12771             return;
12772         }
12773         try {
12774             controller.unregisterImsStateCallback(cb);
12775         } finally {
12776             Binder.restoreCallingIdentity(token);
12777         }
12778     }
12779 
12780     /**
12781      * @return {@CellIdentity} last known cell identity {@CellIdentity}.
12782      *
12783      * Require {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
12784      * {@link android.Manifest.permission#ACCESS_LAST_KNOWN_CELL_ID}, otherwise throws
12785      * SecurityException.
12786      *
12787      * If there is current registered network this value will be same as the registered cell
12788      * identity. If the device goes out of service the previous cell identity is cached and
12789      * will be returned. If the cache age of the Cell identity is more than 24 hours
12790      * it will be cleared and null will be returned.
12791      *
12792      */
12793     @Override
getLastKnownCellIdentity(int subId, String callingPackage, String callingFeatureId)12794     public @Nullable CellIdentity getLastKnownCellIdentity(int subId, String callingPackage,
12795             String callingFeatureId) {
12796         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
12797         LocationAccessPolicy.LocationPermissionResult fineLocationResult =
12798                 LocationAccessPolicy.checkLocationPermission(mApp,
12799                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
12800                                 .setCallingPackage(callingPackage)
12801                                 .setCallingFeatureId(callingFeatureId)
12802                                 .setCallingPid(Binder.getCallingPid())
12803                                 .setCallingUid(Binder.getCallingUid())
12804                                 .setMethod("getLastKnownCellIdentity")
12805                                 .setLogAsInfo(true)
12806                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
12807                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
12808                                 .setMinSdkVersionForEnforcement(Build.VERSION_CODES.Q)
12809                                 .build());
12810 
12811         boolean hasFinePermission =
12812                 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
12813         if (!hasFinePermission
12814                 || !TelephonyPermissions.checkLastKnownCellIdAccessPermission(mApp)) {
12815             throw new SecurityException("getLastKnownCellIdentity need ACCESS_FINE_LOCATION "
12816                     + "and ACCESS_LAST_KNOWN_CELL_ID permission.");
12817         }
12818 
12819         final long identity = Binder.clearCallingIdentity();
12820         try {
12821             ServiceStateTracker sst = getPhoneFromSubIdOrDefault(subId).getServiceStateTracker();
12822             if (sst == null) return null;
12823             return sst.getLastKnownCellIdentity();
12824         } finally {
12825             Binder.restoreCallingIdentity(identity);
12826         }
12827     }
12828 
12829     /**
12830      * Sets the modem service class Name that Telephony will bind to.
12831      *
12832      * @param serviceName The class name of the modem service.
12833      * @return true if the operation is succeed, otherwise false.
12834      */
setModemService(String serviceName)12835     public boolean setModemService(String serviceName) {
12836         Log.d(LOG_TAG, "setModemService - " + serviceName);
12837         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setModemService");
12838         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
12839                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
12840                 "setModemService");
12841         return mPhoneConfigurationManager.setModemService(serviceName);
12842     }
12843 
12844     /**
12845      * Return the class name of the currently bounded modem service.
12846      *
12847      * @return the class name of the modem service.
12848      */
getModemService()12849     public String getModemService() {
12850         String result;
12851         Log.d(LOG_TAG, "getModemService");
12852         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "getModemService");
12853         TelephonyPermissions
12854                 .enforceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
12855                         mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID,
12856                         "getModemService");
12857         result = mPhoneConfigurationManager.getModemService();
12858         Log.d(LOG_TAG, "result = " + result);
12859         return result;
12860     }
12861 
12862     /**
12863      * Get the aggregated satellite plmn list. This API collects plmn data from multiple sources,
12864      * including carrier config, entitlement server, and config update.
12865      *
12866      * @param subId subId The subscription ID of the carrier.
12867      *
12868      * @return List of plmns for carrier satellite service. If no plmn is available, empty list will
12869      * be returned.
12870      *
12871      * @throws SecurityException if the caller doesn't have the required permission.
12872      */
getSatellitePlmnsForCarrier(int subId)12873     @NonNull public List<String> getSatellitePlmnsForCarrier(int subId) {
12874         enforceSatelliteCommunicationPermission("getSatellitePlmnsForCarrier");
12875         final long identity = Binder.clearCallingIdentity();
12876         try {
12877             return mSatelliteController.getSatellitePlmnsForCarrier(subId);
12878         } finally {
12879             Binder.restoreCallingIdentity(identity);
12880         }
12881     }
12882 
12883     @Override
setVoiceServiceStateOverride(int subId, boolean hasService, String callingPackage)12884     public void setVoiceServiceStateOverride(int subId, boolean hasService, String callingPackage) {
12885         // Only telecom (and shell, for CTS purposes) is allowed to call this method.
12886         mApp.enforceCallingOrSelfPermission(
12887                 permission.BIND_TELECOM_CONNECTION_SERVICE, "setVoiceServiceStateOverride");
12888         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
12889 
12890         final long identity = Binder.clearCallingIdentity();
12891         try {
12892             Phone phone = getPhone(subId);
12893             if (phone == null) return;
12894             Log.i(LOG_TAG, "setVoiceServiceStateOverride: subId=" + subId + ", phone=" + phone
12895                     + ", hasService=" + hasService + ", callingPackage=" + callingPackage);
12896             phone.setVoiceServiceStateOverride(hasService);
12897         } finally {
12898             Binder.restoreCallingIdentity(identity);
12899         }
12900     }
12901 
12902     /**
12903      * set removable eSIM as default eUICC.
12904      *
12905      * @hide
12906      */
12907     @Override
setRemovableEsimAsDefaultEuicc(boolean isDefault, String callingPackage)12908     public void setRemovableEsimAsDefaultEuicc(boolean isDefault, String callingPackage) {
12909         enforceModifyPermission();
12910         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
12911 
12912         final long identity = Binder.clearCallingIdentity();
12913         try {
12914             UiccController.getInstance().setRemovableEsimAsDefaultEuicc(isDefault);
12915         }  finally {
12916             Binder.restoreCallingIdentity(identity);
12917         }
12918     }
12919 
12920     /**
12921      * Returns whether the removable eSIM is default eUICC or not.
12922      *
12923      * @hide
12924      */
12925     @Override
isRemovableEsimDefaultEuicc(String callingPackage)12926     public boolean isRemovableEsimDefaultEuicc(String callingPackage) {
12927         enforceReadPrivilegedPermission("isRemovableEsimDefaultEuicc");
12928         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
12929 
12930         final long identity = Binder.clearCallingIdentity();
12931         try {
12932             return UiccController.getInstance().isRemovableEsimDefaultEuicc();
12933         }  finally {
12934             Binder.restoreCallingIdentity(identity);
12935         }
12936     }
12937 
12938     /**
12939      * Get the component name of the default app to direct respond-via-message intent for the
12940      * user associated with this subscription, update the cache if there is no respond-via-message
12941      * application currently configured for this user.
12942      * @return component name of the app and class to direct Respond Via Message intent to, or
12943      * {@code null} if the functionality is not supported.
12944      * @hide
12945      */
12946     @Override
getDefaultRespondViaMessageApplication(int subId, boolean updateIfNeeded)12947     public @Nullable ComponentName getDefaultRespondViaMessageApplication(int subId,
12948             boolean updateIfNeeded) {
12949         enforceInteractAcrossUsersPermission("getDefaultRespondViaMessageApplication");
12950 
12951         enforceTelephonyFeatureWithException(getCurrentPackageName(),
12952                 PackageManager.FEATURE_TELEPHONY_MESSAGING,
12953                 "getDefaultRespondViaMessageApplication");
12954 
12955         Context context = getPhoneFromSubIdOrDefault(subId).getContext();
12956 
12957         if (mTelecomFeatureFlags.telecomMainUserInGetRespondMessageApp()){
12958             UserHandle mainUser = null;
12959             Context userContext = context;
12960             final long identity = Binder.clearCallingIdentity();
12961             try {
12962                 mainUser = mUserManager.getMainUser();
12963                 if (mainUser != null) {
12964                     userContext = context.createContextAsUser(mainUser, 0);
12965                 } else {
12966                     // If getting the main user is null, then fall back to legacy behavior:
12967                     mainUser = TelephonyUtils.getSubscriptionUserHandle(context, subId);
12968                 }
12969                 Log.d(LOG_TAG, "getDefaultRespondViaMessageApplication: mainUser = "
12970                         + mainUser);
12971             } finally {
12972                 Binder.restoreCallingIdentity(identity);
12973             }
12974             return SmsApplication.getDefaultRespondViaMessageApplicationAsUser(userContext,
12975                     updateIfNeeded, mainUser);
12976         } else {
12977             UserHandle userHandle = null;
12978             final long identity = Binder.clearCallingIdentity();
12979             try {
12980                 userHandle = TelephonyUtils.getSubscriptionUserHandle(context, subId);
12981             } finally {
12982                 Binder.restoreCallingIdentity(identity);
12983             }
12984             return SmsApplication.getDefaultRespondViaMessageApplicationAsUser(context,
12985                     updateIfNeeded, userHandle);
12986         }
12987 
12988     }
12989 
12990     /**
12991      * Set whether the device is able to connect with null ciphering or integrity
12992      * algorithms. This is a global setting and will apply to all active subscriptions
12993      * and all new subscriptions after this.
12994      *
12995      * @param enabled when true, null  cipher and integrity algorithms are allowed.
12996      * @hide
12997      */
12998     @Override
12999     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
setNullCipherAndIntegrityEnabled(boolean enabled)13000     public void setNullCipherAndIntegrityEnabled(boolean enabled) {
13001         enforceModifyPermission();
13002         checkForNullCipherAndIntegritySupport();
13003 
13004         // Persist the state of our preference. Each GsmCdmaPhone instance is responsible
13005         // for listening to these preference changes and applying them immediately.
13006         SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
13007         editor.putBoolean(Phone.PREF_NULL_CIPHER_AND_INTEGRITY_ENABLED, enabled);
13008         editor.apply();
13009 
13010         for (Phone phone: PhoneFactory.getPhones()) {
13011             phone.handleNullCipherEnabledChange();
13012         }
13013     }
13014 
13015 
13016     /**
13017      * Get whether the device is able to connect with null ciphering or integrity
13018      * algorithms. Note that this retrieves the phone-global preference and not
13019      * the state of the radio.
13020      *
13021      * @throws SecurityException if {@link permission#MODIFY_PHONE_STATE} is not satisfied
13022      * @throws UnsupportedOperationException if the device does not support the minimum HAL
13023      * version for this feature.
13024      * @hide
13025      */
13026     @Override
13027     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
isNullCipherAndIntegrityPreferenceEnabled()13028     public boolean isNullCipherAndIntegrityPreferenceEnabled() {
13029         enforceReadPermission();
13030         checkForNullCipherAndIntegritySupport();
13031         return getDefaultPhone().getNullCipherAndIntegrityEnabledPreference();
13032     }
13033 
checkForNullCipherAndIntegritySupport()13034     private void checkForNullCipherAndIntegritySupport() {
13035         if (getHalVersion(HAL_SERVICE_NETWORK) < MIN_NULL_CIPHER_AND_INTEGRITY_VERSION) {
13036             throw new UnsupportedOperationException(
13037                     "Null cipher and integrity operations require HAL 2.1 or above");
13038         }
13039         if (!getDefaultPhone().isNullCipherAndIntegritySupported()) {
13040             throw new UnsupportedOperationException(
13041                     "Null cipher and integrity operations unsupported by modem");
13042         }
13043     }
13044 
checkForIdentifierDisclosureNotificationSupport()13045     private void checkForIdentifierDisclosureNotificationSupport() {
13046         if (getHalVersion(HAL_SERVICE_NETWORK) < MIN_IDENTIFIER_DISCLOSURE_VERSION) {
13047             throw new UnsupportedOperationException(
13048                     "Cellular identifier disclosure transparency operations require HAL 2.2 or "
13049                             + "above");
13050         }
13051         if (!getDefaultPhone().isIdentifierDisclosureTransparencySupported()) {
13052             throw new UnsupportedOperationException(
13053                     "Cellular identifier disclosure transparency operations unsupported by modem");
13054         }
13055     }
13056 
checkForNullCipherNotificationSupport()13057     private void checkForNullCipherNotificationSupport() {
13058         if (getHalVersion(HAL_SERVICE_NETWORK) < MIN_NULL_CIPHER_NOTIFICATION_VERSION) {
13059             throw new UnsupportedOperationException(
13060                     "Null cipher notification operations require HAL 2.2 or above");
13061         }
13062         if (!getDefaultPhone().isNullCipherNotificationSupported()) {
13063             throw new UnsupportedOperationException(
13064                     "Null cipher notification operations unsupported by modem");
13065         }
13066     }
13067 
13068     /**
13069      * Get the SIM state for the slot index.
13070      * For Remote-SIMs, this method returns {@link IccCardConstants.State#UNKNOWN}
13071      *
13072      * @return SIM state as the ordinal of {@link IccCardConstants.State}
13073      */
13074     @Override
13075     @SimState
getSimStateForSlotIndex(int slotIndex)13076     public int getSimStateForSlotIndex(int slotIndex) {
13077         if (!mApp.getResources().getBoolean(
13078                 com.android.internal.R.bool.config_force_phone_globals_creation)) {
13079             enforceTelephonyFeatureWithException(getCurrentPackageName(),
13080                     PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSimStateForSlotIndex");
13081         }
13082 
13083         IccCardConstants.State simState;
13084         if (slotIndex < 0) {
13085             simState = IccCardConstants.State.UNKNOWN;
13086         } else {
13087             Phone phone = null;
13088             try {
13089                 phone = PhoneFactory.getPhone(slotIndex);
13090             } catch (IllegalStateException e) {
13091                 // ignore
13092             }
13093             if (phone == null) {
13094                 simState = IccCardConstants.State.UNKNOWN;
13095             } else {
13096                 IccCard icc = phone.getIccCard();
13097                 if (icc == null) {
13098                     simState = IccCardConstants.State.UNKNOWN;
13099                 } else {
13100                     simState = icc.getState();
13101                 }
13102             }
13103         }
13104         return simState.ordinal();
13105     }
13106 
persistEmergencyCallDiagnosticDataInternal(@onNull String dropboxTag, boolean enableLogcat, long logcatStartTimestampMillis, boolean enableTelecomDump, boolean enableTelephonyDump)13107     private void persistEmergencyCallDiagnosticDataInternal(@NonNull String dropboxTag,
13108             boolean enableLogcat,
13109             long logcatStartTimestampMillis, boolean enableTelecomDump,
13110             boolean enableTelephonyDump) {
13111         DropBoxManager db = mApp.getSystemService(DropBoxManager.class);
13112         TelephonyManager.EmergencyCallDiagnosticData.Builder ecdDataBuilder =
13113                 new TelephonyManager.EmergencyCallDiagnosticData.Builder();
13114         ecdDataBuilder
13115                 .setTelecomDumpsysCollectionEnabled(enableTelecomDump)
13116                 .setTelephonyDumpsysCollectionEnabled(enableTelephonyDump);
13117         if (enableLogcat) {
13118             ecdDataBuilder.setLogcatCollectionStartTimeMillis(logcatStartTimestampMillis);
13119         }
13120         TelephonyManager.EmergencyCallDiagnosticData ecdData = ecdDataBuilder.build();
13121         Log.d(LOG_TAG, "persisting with Params " + ecdData.toString());
13122         DiagnosticDataCollector ddc = new DiagnosticDataCollector(Runtime.getRuntime(),
13123                 Executors.newCachedThreadPool(), db,
13124                 mApp.getSystemService(ActivityManager.class).isLowRamDevice());
13125         ddc.persistEmergencyDianosticData(new DataCollectorConfig.Adapter(), ecdData, dropboxTag);
13126     }
13127 
13128     /**
13129      * Request telephony to persist state for debugging emergency call failures.
13130      *
13131      * @param dropboxTag                 Tag to use when persisting data to dropbox service.
13132      * @param enableLogcat               whether to collect logcat output
13133      * @param logcatStartTimestampMillis timestamp from when logcat buffers would be persisted
13134      * @param enableTelecomDump          whether to collect telecom dumpsys
13135      * @param enableTelephonyDump        whether to collect telephony dumpsys
13136      */
13137     @Override
13138     @RequiresPermission(android.Manifest.permission.DUMP)
persistEmergencyCallDiagnosticData(@onNull String dropboxTag, boolean enableLogcat, long logcatStartTimestampMillis, boolean enableTelecomDump, boolean enableTelephonyDump)13139     public void persistEmergencyCallDiagnosticData(@NonNull String dropboxTag, boolean enableLogcat,
13140             long logcatStartTimestampMillis, boolean enableTelecomDump,
13141             boolean enableTelephonyDump) {
13142         // Verify that the caller has READ_DROPBOX_DATA permission.
13143         if (mTelecomFeatureFlags.telecomResolveHiddenDependencies()
13144                 && Flags.enableReadDropboxPermission()) {
13145             mApp.enforceCallingPermission(permission.READ_DROPBOX_DATA,
13146                     "persistEmergencyCallDiagnosticData");
13147         } else {
13148             // Otherwise, enforce legacy permission.
13149             mApp.enforceCallingPermission(android.Manifest.permission.DUMP,
13150                     "persistEmergencyCallDiagnosticData");
13151         }
13152         final long identity = Binder.clearCallingIdentity();
13153         try {
13154             persistEmergencyCallDiagnosticDataInternal(dropboxTag, enableLogcat,
13155                     logcatStartTimestampMillis, enableTelecomDump, enableTelephonyDump);
13156 
13157         } finally {
13158             Binder.restoreCallingIdentity(identity);
13159         }
13160     }
13161 
13162     /**
13163      * Get current cell broadcast ranges.
13164      */
13165     @Override
13166     @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
getCellBroadcastIdRanges(int subId)13167     public List<CellBroadcastIdRange> getCellBroadcastIdRanges(int subId) {
13168         mApp.enforceCallingPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS,
13169                 "getCellBroadcastIdRanges");
13170 
13171         enforceTelephonyFeatureWithException(getCurrentPackageName(),
13172                 PackageManager.FEATURE_TELEPHONY_MESSAGING, "getCellBroadcastIdRanges");
13173 
13174         final long identity = Binder.clearCallingIdentity();
13175         try {
13176             return getPhone(subId).getCellBroadcastIdRanges();
13177         } finally {
13178             Binder.restoreCallingIdentity(identity);
13179         }
13180     }
13181 
13182     /**
13183      * Set reception of cell broadcast messages with the list of the given ranges
13184      *
13185      * @param ranges the list of {@link CellBroadcastIdRange} to be enabled
13186      */
13187     @Override
13188     @RequiresPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS)
setCellBroadcastIdRanges(int subId, @NonNull List<CellBroadcastIdRange> ranges, @Nullable IIntegerConsumer callback)13189     public void setCellBroadcastIdRanges(int subId, @NonNull List<CellBroadcastIdRange> ranges,
13190             @Nullable IIntegerConsumer callback) {
13191         mApp.enforceCallingPermission(android.Manifest.permission.MODIFY_CELL_BROADCASTS,
13192                 "setCellBroadcastIdRanges");
13193 
13194         enforceTelephonyFeatureWithException(getCurrentPackageName(),
13195                 PackageManager.FEATURE_TELEPHONY_MESSAGING, "setCellBroadcastIdRanges");
13196 
13197         final long identity = Binder.clearCallingIdentity();
13198         try {
13199             Phone phone = getPhoneFromSubId(subId);
13200             if (DBG) {
13201                 log("setCellBroadcastIdRanges for subId :" + subId + ", phone:" + phone);
13202             }
13203             phone.setCellBroadcastIdRanges(ranges, result -> {
13204                 if (callback != null) {
13205                     try {
13206                         callback.accept(result);
13207                     } catch (RemoteException e) {
13208                         Log.w(LOG_TAG, "setCellBroadcastIdRanges: callback not available.");
13209                     }
13210                 }
13211             });
13212         } finally {
13213             Binder.restoreCallingIdentity(identity);
13214         }
13215     }
13216 
13217     /**
13218      * Returns whether the device supports the domain selection service.
13219      *
13220      * @return {@code true} if the device supports the domain selection service.
13221      */
13222     @Override
isDomainSelectionSupported()13223     public boolean isDomainSelectionSupported() {
13224         mApp.enforceCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
13225                 "isDomainSelectionSupported");
13226 
13227         final long identity = Binder.clearCallingIdentity();
13228         try {
13229             return DomainSelectionResolver.getInstance().isDomainSelectionSupported();
13230         }  finally {
13231             Binder.restoreCallingIdentity(identity);
13232         }
13233     }
13234 
13235     /**
13236      * Returns whether the AOSP domain selection service is supported.
13237      *
13238      * @return {@code true} if the AOSP domain selection service is supported,
13239      *         {@code false} otherwise.
13240      */
13241     @Override
isAospDomainSelectionService()13242     public boolean isAospDomainSelectionService() {
13243         mApp.enforceCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
13244                 "isAospDomainSelectionService");
13245 
13246         final long identity = Binder.clearCallingIdentity();
13247         try {
13248             if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
13249                 String dssComponentName = mApp.getResources().getString(
13250                         R.string.config_domain_selection_service_component_name);
13251                 ComponentName componentName = ComponentName.createRelative(mApp.getPackageName(),
13252                         TelephonyDomainSelectionService.class.getName());
13253                 Log.i(LOG_TAG, "isAospDomainSelectionService dss=" + dssComponentName
13254                         + ", aosp=" + componentName.flattenToString());
13255                 return TextUtils.equals(componentName.flattenToString(), dssComponentName);
13256             }
13257         } finally {
13258             Binder.restoreCallingIdentity(identity);
13259         }
13260         return false;
13261     }
13262 
13263     /**
13264      * Request to enable or disable the satellite modem and demo mode. If the satellite modem is
13265      * enabled, this may also disable the cellular modem, and if the satellite modem is disabled,
13266      * this may also re-enable the cellular modem.
13267      *
13268      * @param enableSatellite {@code true} to enable the satellite modem and
13269      *                        {@code false} to disable.
13270      * @param enableDemoMode {@code true} to enable demo mode and {@code false} to disable.
13271      * @param isEmergency {@code true} to enable emergency mode, {@code false} otherwise.
13272      * @param callback The callback to get the result of the request.
13273      *
13274      * @throws SecurityException if the caller doesn't have the required permission.
13275      */
13276     @Override
requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode, boolean isEmergency, @NonNull IIntegerConsumer callback)13277     public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode,
13278             boolean isEmergency, @NonNull IIntegerConsumer callback) {
13279         enforceSatelliteCommunicationPermission("requestSatelliteEnabled");
13280         final long identity = Binder.clearCallingIdentity();
13281         try {
13282             if (enableSatellite) {
13283                 String caller = "PIM:requestSatelliteEnabled";
13284                 ResultReceiver resultReceiver = new ResultReceiver(mMainThreadHandler) {
13285                     @Override
13286                     protected void onReceiveResult(int resultCode, Bundle resultData) {
13287                         Log.d(LOG_TAG, "Satellite access restriction resultCode=" + resultCode
13288                                 + ", resultData=" + resultData);
13289                         mSatelliteController.decrementResultReceiverCount(caller);
13290 
13291                         boolean isAllowed = false;
13292                         Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(
13293                                 callback::accept);
13294                         if (resultCode == SATELLITE_RESULT_SUCCESS) {
13295                             if (resultData != null
13296                                     && resultData.containsKey(
13297                                     KEY_SATELLITE_COMMUNICATION_ALLOWED)) {
13298                                 isAllowed = resultData.getBoolean(
13299                                         KEY_SATELLITE_COMMUNICATION_ALLOWED);
13300                             } else {
13301                                 loge("KEY_SATELLITE_COMMUNICATION_ALLOWED does not exist.");
13302                             }
13303                         } else {
13304                             result.accept(resultCode);
13305                             return;
13306                         }
13307                         List<Integer> disallowedReasons =
13308                                 mSatelliteAccessController.getSatelliteDisallowedReasons();
13309                         if (disallowedReasons.stream().anyMatch(r ->
13310                                 (r == SATELLITE_DISALLOWED_REASON_UNSUPPORTED_DEFAULT_MSG_APP
13311                                         || r == SATELLITE_DISALLOWED_REASON_NOT_PROVISIONED
13312                                         || r == SATELLITE_DISALLOWED_REASON_NOT_SUPPORTED))) {
13313                             Log.d(LOG_TAG, "Satellite access is disallowed for current location.");
13314                             result.accept(SATELLITE_RESULT_ACCESS_BARRED);
13315                             return;
13316                         }
13317                         if (isAllowed) {
13318                             ResultReceiver resultReceiver = new ResultReceiver(mMainThreadHandler) {
13319                                 @Override
13320                                 protected void onReceiveResult(int resultCode, Bundle resultData) {
13321                                     Log.d(LOG_TAG, "updateSystemSelectionChannels resultCode="
13322                                             + resultCode);
13323                                     mSatelliteController.requestSatelliteEnabled(
13324                                         enableSatellite, enableDemoMode, isEmergency, callback);
13325                                 }
13326                             };
13327                             mSatelliteAccessController.updateSystemSelectionChannels(
13328                                     resultReceiver);
13329                         } else {
13330                             result.accept(SATELLITE_RESULT_ACCESS_BARRED);
13331                         }
13332                     }
13333                 };
13334                 mSatelliteAccessController.requestIsCommunicationAllowedForCurrentLocation(
13335                         resultReceiver, true);
13336                 mSatelliteController.incrementResultReceiverCount(caller);
13337             } else {
13338                 // No need to check if satellite is allowed at current location when disabling
13339                 // satellite
13340                 mSatelliteController.requestSatelliteEnabled(
13341                         enableSatellite, enableDemoMode, isEmergency, callback);
13342             }
13343         } finally {
13344             Binder.restoreCallingIdentity(identity);
13345         }
13346     }
13347 
13348     /**
13349      * Request to get whether the satellite modem is enabled.
13350      *
13351      * @param result The result receiver that returns whether the satellite modem is enabled
13352      *               if the request is successful or an error code if the request failed.
13353      *
13354      * @throws SecurityException if the caller doesn't have the required permission.
13355      */
13356     @Override
requestIsSatelliteEnabled(@onNull ResultReceiver result)13357     public void requestIsSatelliteEnabled(@NonNull ResultReceiver result) {
13358         enforceSatelliteCommunicationPermission("requestIsSatelliteEnabled");
13359         final long identity = Binder.clearCallingIdentity();
13360         try {
13361             mSatelliteController.requestIsSatelliteEnabled(result);
13362         } finally {
13363             Binder.restoreCallingIdentity(identity);
13364         }
13365     }
13366 
13367     /**
13368      * Request to get whether the satellite service demo mode is enabled.
13369      *
13370      * @param result The result receiver that returns whether the satellite demo mode is enabled
13371      *               if the request is successful or an error code if the request failed.
13372      *
13373      * @throws SecurityException if the caller doesn't have the required permission.
13374      */
13375     @Override
requestIsDemoModeEnabled(@onNull ResultReceiver result)13376     public void requestIsDemoModeEnabled(@NonNull ResultReceiver result) {
13377         enforceSatelliteCommunicationPermission("requestIsDemoModeEnabled");
13378         final long identity = Binder.clearCallingIdentity();
13379         try {
13380             mSatelliteController.requestIsDemoModeEnabled(result);
13381         } finally {
13382             Binder.restoreCallingIdentity(identity);
13383         }
13384     }
13385 
13386     /**
13387      * Request to get whether the satellite service is enabled with emergency mode.
13388      *
13389      * @param result The result receiver that returns whether the satellite emergency mode is
13390      *               enabled if the request is successful or an error code if the request failed.
13391      *
13392      * @throws SecurityException if the caller doesn't have the required permission.
13393      */
13394     @Override
requestIsEmergencyModeEnabled(@onNull ResultReceiver result)13395     public void requestIsEmergencyModeEnabled(@NonNull ResultReceiver result) {
13396         enforceSatelliteCommunicationPermission("requestIsEmergencyModeEnabled");
13397         final long identity = Binder.clearCallingIdentity();
13398         try {
13399             mSatelliteController.requestIsEmergencyModeEnabled(result);
13400         } finally {
13401             Binder.restoreCallingIdentity(identity);
13402         }
13403     }
13404 
13405     /**
13406      * Request to get whether the satellite service is supported on the device.
13407      *
13408      * @param result The result receiver that returns whether the satellite service is supported on
13409      *               the device if the request is successful or an error code if the request failed.
13410      */
13411     @Override
requestIsSatelliteSupported(@onNull ResultReceiver result)13412     public void requestIsSatelliteSupported(@NonNull ResultReceiver result) {
13413         final long identity = Binder.clearCallingIdentity();
13414         try {
13415             mSatelliteController.requestIsSatelliteSupported(result);
13416         } finally {
13417             Binder.restoreCallingIdentity(identity);
13418         }
13419     }
13420 
13421     /**
13422      * Request to get the {@link SatelliteCapabilities} of the satellite service.
13423      *
13424      * @param result The result receiver that returns the {@link SatelliteCapabilities}
13425      *               if the request is successful or an error code if the request failed.
13426      *
13427      * @throws SecurityException if the caller doesn't have required permission.
13428      */
13429     @Override
requestSatelliteCapabilities(@onNull ResultReceiver result)13430     public void requestSatelliteCapabilities(@NonNull ResultReceiver result) {
13431         enforceSatelliteCommunicationPermission("requestSatelliteCapabilities");
13432         final long identity = Binder.clearCallingIdentity();
13433         try {
13434             mSatelliteController.requestSatelliteCapabilities(result);
13435         } finally {
13436             Binder.restoreCallingIdentity(identity);
13437         }
13438     }
13439 
13440     /**
13441      * Start receiving satellite transmission updates.
13442      * This can be called by the pointing UI when the user starts pointing to the satellite.
13443      * Modem should continue to report the pointing input as the device or satellite moves.
13444      *
13445      * @param resultCallback The callback to get the result of the request.
13446      * @param callback The callback to notify of satellite transmission updates.
13447      *
13448      * @throws SecurityException if the caller doesn't have the required permission.
13449      */
13450     @Override
startSatelliteTransmissionUpdates( @onNull IIntegerConsumer resultCallback, @NonNull ISatelliteTransmissionUpdateCallback callback)13451     public void startSatelliteTransmissionUpdates(
13452             @NonNull IIntegerConsumer resultCallback,
13453             @NonNull ISatelliteTransmissionUpdateCallback callback) {
13454         enforceSatelliteCommunicationPermission("startSatelliteTransmissionUpdates");
13455         final long identity = Binder.clearCallingIdentity();
13456         try {
13457             mSatelliteController.startSatelliteTransmissionUpdates(resultCallback, callback);
13458         } finally {
13459             Binder.restoreCallingIdentity(identity);
13460         }
13461     }
13462 
13463     /**
13464      * Stop receiving satellite transmission updates.
13465      * This can be called by the pointing UI when the user stops pointing to the satellite.
13466      *
13467      * @param resultCallback The callback to get the result of the request.
13468      * @param callback The callback that was passed to {@link #startSatelliteTransmissionUpdates(
13469      *                 IIntegerConsumer, ISatelliteTransmissionUpdateCallback)}.
13470      *
13471      * @throws SecurityException if the caller doesn't have the required permission.
13472      */
13473     @Override
stopSatelliteTransmissionUpdates( @onNull IIntegerConsumer resultCallback, @NonNull ISatelliteTransmissionUpdateCallback callback)13474     public void stopSatelliteTransmissionUpdates(
13475             @NonNull IIntegerConsumer resultCallback,
13476             @NonNull ISatelliteTransmissionUpdateCallback callback) {
13477         enforceSatelliteCommunicationPermission("stopSatelliteTransmissionUpdates");
13478         final long identity = Binder.clearCallingIdentity();
13479         try {
13480             mSatelliteController.stopSatelliteTransmissionUpdates(resultCallback, callback);
13481         } finally {
13482             Binder.restoreCallingIdentity(identity);
13483         }
13484     }
13485 
13486     /**
13487      * Register the subscription with a satellite provider.
13488      * This is needed to register the subscription if the provider allows dynamic registration.
13489      *
13490      * @param token The token to be used as a unique identifier for provisioning with satellite
13491      *              gateway.
13492      * @param provisionData Data from the provisioning app that can be used by provisioning server
13493      * @param callback The callback to get the result of the request.
13494      *
13495      * @return The signal transport used by the caller to cancel the provision request,
13496      *         or {@code null} if the request failed.
13497      *
13498      * @throws SecurityException if the caller doesn't have the required permission.
13499      */
13500     @Override
provisionSatelliteService( @onNull String token, @NonNull byte[] provisionData, @NonNull IIntegerConsumer callback)13501     @Nullable public ICancellationSignal provisionSatelliteService(
13502             @NonNull String token, @NonNull byte[] provisionData,
13503             @NonNull IIntegerConsumer callback) {
13504         enforceSatelliteCommunicationPermission("provisionSatelliteService");
13505         final long identity = Binder.clearCallingIdentity();
13506         try {
13507             return mSatelliteController.provisionSatelliteService(token, provisionData,
13508                 callback);
13509         } finally {
13510             Binder.restoreCallingIdentity(identity);
13511         }
13512     }
13513 
13514     /**
13515      * Unregister the device/subscription with the satellite provider.
13516      * This is needed if the provider allows dynamic registration. Once deprovisioned,
13517      * {@link SatelliteProvisionStateCallback#onSatelliteProvisionStateChanged(boolean)}
13518      * should report as deprovisioned.
13519      *
13520      * @param token The token of the device/subscription to be deprovisioned.
13521      * @param callback The callback to get the result of the request.
13522      *
13523      * @throws SecurityException if the caller doesn't have the required permission.
13524      */
13525     @Override
deprovisionSatelliteService( @onNull String token, @NonNull IIntegerConsumer callback)13526     public void deprovisionSatelliteService(
13527             @NonNull String token, @NonNull IIntegerConsumer callback) {
13528         enforceSatelliteCommunicationPermission("deprovisionSatelliteService");
13529         final long identity = Binder.clearCallingIdentity();
13530         try {
13531             mSatelliteController.deprovisionSatelliteService(token, callback);
13532         } finally {
13533             Binder.restoreCallingIdentity(identity);
13534         }
13535     }
13536 
13537     /**
13538      * Registers for the satellite provision state changed.
13539      *
13540      * @param callback The callback to handle the satellite provision state changed event.
13541      *
13542      * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
13543      *
13544      * @throws SecurityException if the caller doesn't have the required permission.
13545      */
13546     @Override
registerForSatelliteProvisionStateChanged( @onNull ISatelliteProvisionStateCallback callback)13547     @SatelliteManager.SatelliteResult public int registerForSatelliteProvisionStateChanged(
13548             @NonNull ISatelliteProvisionStateCallback callback) {
13549         enforceSatelliteCommunicationPermission("registerForSatelliteProvisionStateChanged");
13550         final long identity = Binder.clearCallingIdentity();
13551         try {
13552             return mSatelliteController.registerForSatelliteProvisionStateChanged(callback);
13553         } finally {
13554             Binder.restoreCallingIdentity(identity);
13555         }
13556     }
13557 
13558     /**
13559      * Unregisters for the satellite provision state changed.
13560      * If callback was not registered before, the request will be ignored.
13561      *
13562      * @param callback The callback that was passed to
13563      * {@link #registerForSatelliteProvisionStateChanged(ISatelliteProvisionStateCallback)}.
13564      *
13565      * @throws SecurityException if the caller doesn't have the required permission.
13566      */
13567     @Override
unregisterForSatelliteProvisionStateChanged( @onNull ISatelliteProvisionStateCallback callback)13568     public void unregisterForSatelliteProvisionStateChanged(
13569             @NonNull ISatelliteProvisionStateCallback callback) {
13570         enforceSatelliteCommunicationPermission("unregisterForSatelliteProvisionStateChanged");
13571         final long identity = Binder.clearCallingIdentity();
13572         try {
13573             mSatelliteController.unregisterForSatelliteProvisionStateChanged(callback);
13574         } finally {
13575             Binder.restoreCallingIdentity(identity);
13576         }
13577     }
13578 
13579     /**
13580      * Request to get whether the device is provisioned with a satellite provider.
13581      *
13582      * @param result The result receiver that returns whether the device is provisioned with a
13583      *               satellite provider if the request is successful or an error code if the
13584      *               request failed.
13585      *
13586      * @throws SecurityException if the caller doesn't have the required permission.
13587      */
13588     @Override
requestIsSatelliteProvisioned(@onNull ResultReceiver result)13589     public void requestIsSatelliteProvisioned(@NonNull ResultReceiver result) {
13590         enforceSatelliteCommunicationPermission("requestIsSatelliteProvisioned");
13591         final long identity = Binder.clearCallingIdentity();
13592         try {
13593             mSatelliteController.requestIsSatelliteProvisioned(result);
13594         } finally {
13595             Binder.restoreCallingIdentity(identity);
13596         }
13597     }
13598 
13599     /**
13600      * Registers for modem state changed from satellite modem.
13601      *
13602      * @param callback The callback to handle the satellite modem state changed event.
13603      *
13604      * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
13605      *
13606      * @throws SecurityException if the caller doesn't have the required permission.
13607      */
13608     @Override
registerForSatelliteModemStateChanged( @onNull ISatelliteModemStateCallback callback)13609     @SatelliteManager.SatelliteResult public int registerForSatelliteModemStateChanged(
13610             @NonNull ISatelliteModemStateCallback callback) {
13611         enforceSatelliteCommunicationPermission("registerForSatelliteModemStateChanged");
13612         final long identity = Binder.clearCallingIdentity();
13613         try {
13614             return mSatelliteController.registerForSatelliteModemStateChanged(callback);
13615         } finally {
13616             Binder.restoreCallingIdentity(identity);
13617         }
13618     }
13619 
13620     /**
13621      * Unregisters for modem state changed from satellite modem.
13622      * If callback was not registered before, the request will be ignored.
13623      *
13624      * @param callback The callback that was passed to
13625      * {@link #registerForModemStateChanged(int, ISatelliteModemStateCallback)}.
13626      *
13627      * @throws SecurityException if the caller doesn't have the required permission.
13628      */
13629     @Override
unregisterForModemStateChanged(@onNull ISatelliteModemStateCallback callback)13630     public void unregisterForModemStateChanged(@NonNull ISatelliteModemStateCallback callback) {
13631         enforceSatelliteCommunicationPermission("unregisterForModemStateChanged");
13632         final long identity = Binder.clearCallingIdentity();
13633         try {
13634             mSatelliteController.unregisterForModemStateChanged(callback);
13635         } finally {
13636             Binder.restoreCallingIdentity(identity);
13637         }
13638     }
13639 
13640     /**
13641      * Register to receive incoming datagrams over satellite.
13642      *
13643      * @param callback The callback to handle incoming datagrams over satellite.
13644      *
13645      * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
13646      *
13647      * @throws SecurityException if the caller doesn't have the required permission.
13648      */
13649     @Override
registerForIncomingDatagram( @onNull ISatelliteDatagramCallback callback)13650     @SatelliteManager.SatelliteResult public int registerForIncomingDatagram(
13651             @NonNull ISatelliteDatagramCallback callback) {
13652         enforceSatelliteCommunicationPermission("registerForIncomingDatagram");
13653         final long identity = Binder.clearCallingIdentity();
13654         try {
13655             return mSatelliteController.registerForIncomingDatagram(callback);
13656         } finally {
13657             Binder.restoreCallingIdentity(identity);
13658         }
13659     }
13660 
13661     /**
13662      * Unregister to stop receiving incoming datagrams over satellite.
13663      * If callback was not registered before, the request will be ignored.
13664      *
13665      * @param callback The callback that was passed to
13666      *                 {@link #registerForIncomingDatagram(ISatelliteDatagramCallback)}.
13667      *
13668      * @throws SecurityException if the caller doesn't have the required permission.
13669      */
13670     @Override
unregisterForIncomingDatagram(@onNull ISatelliteDatagramCallback callback)13671     public void unregisterForIncomingDatagram(@NonNull ISatelliteDatagramCallback callback) {
13672         enforceSatelliteCommunicationPermission("unregisterForIncomingDatagram");
13673         final long identity = Binder.clearCallingIdentity();
13674         try {
13675             mSatelliteController.unregisterForIncomingDatagram(callback);
13676         } finally {
13677             Binder.restoreCallingIdentity(identity);
13678         }
13679     }
13680 
13681     /**
13682      * Poll pending satellite datagrams over satellite.
13683      *
13684      * This method requests modem to check if there are any pending datagrams to be received over
13685      * satellite. If there are any incoming datagrams, they will be received via
13686      * {@link SatelliteDatagramCallback#onSatelliteDatagramReceived(long, SatelliteDatagram, int, Consumer)})}
13687      *
13688      * @param callback The callback to get {@link SatelliteManager.SatelliteResult} of the request.
13689      *
13690      * @throws SecurityException if the caller doesn't have required permission.
13691      */
pollPendingDatagrams(IIntegerConsumer callback)13692     public void pollPendingDatagrams(IIntegerConsumer callback) {
13693         enforceSatelliteCommunicationPermission("pollPendingDatagrams");
13694         final long identity = Binder.clearCallingIdentity();
13695         try {
13696             mSatelliteController.pollPendingDatagrams(callback);
13697         } finally {
13698             Binder.restoreCallingIdentity(identity);
13699         }
13700     }
13701 
13702     /**
13703      * Send datagram over satellite.
13704      *
13705      * Gateway encodes SOS message or location sharing message into a datagram and passes it as
13706      * input to this method. Datagram received here will be passed down to modem without any
13707      * encoding or encryption.
13708      *
13709      * @param datagramType datagram type indicating whether the datagram is of type
13710      *                     SOS_SMS or LOCATION_SHARING.
13711      * @param datagram encoded gateway datagram which is encrypted by the caller.
13712      *                 Datagram will be passed down to modem without any encoding or encryption.
13713      * @param needFullScreenPointingUI this is used to indicate pointingUI app to open in
13714      *                                 full screen mode.
13715      * @param callback The callback to get {@link SatelliteManager.SatelliteResult} of the request.
13716      *
13717      * @throws SecurityException if the caller doesn't have required permission.
13718      */
13719     @Override
sendDatagram(@atelliteManager.DatagramType int datagramType, @NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI, @NonNull IIntegerConsumer callback)13720     public void sendDatagram(@SatelliteManager.DatagramType int datagramType,
13721             @NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI,
13722             @NonNull IIntegerConsumer callback) {
13723         enforceSatelliteCommunicationPermission("sendDatagram");
13724         final long identity = Binder.clearCallingIdentity();
13725         try {
13726             mSatelliteController.sendDatagram(datagramType, datagram, needFullScreenPointingUI,
13727                     callback);
13728         } finally {
13729             Binder.restoreCallingIdentity(identity);
13730         }
13731     }
13732 
13733     /**
13734      * Returns integer array of disallowed reasons of satellite.
13735      *
13736      * @return Integer array of disallowed reasons of satellite.
13737      *
13738      * @throws SecurityException if the caller doesn't have the required permission.
13739      */
getSatelliteDisallowedReasons()13740     @NonNull public int[] getSatelliteDisallowedReasons() {
13741         enforceSatelliteCommunicationPermission("getSatelliteDisallowedReasons");
13742         final long identity = Binder.clearCallingIdentity();
13743         try {
13744             return mSatelliteAccessController.getSatelliteDisallowedReasons()
13745                     .stream().mapToInt(Integer::intValue).toArray();
13746         } finally {
13747             Binder.restoreCallingIdentity(identity);
13748         }
13749     }
13750 
13751     /**
13752      * Registers for disallowed reasons change event from satellite service.
13753      *
13754      * @param callback The callback to handle disallowed reasons changed event.
13755      *
13756      * @throws SecurityException if the caller doesn't have the required permission.
13757      */
13758     @Override
registerForSatelliteDisallowedReasonsChanged( @onNull ISatelliteDisallowedReasonsCallback callback)13759     public void registerForSatelliteDisallowedReasonsChanged(
13760             @NonNull ISatelliteDisallowedReasonsCallback callback) {
13761         enforceSatelliteCommunicationPermission("registerForSatelliteDisallowedReasonsChanged");
13762         final long identity = Binder.clearCallingIdentity();
13763         try {
13764             mSatelliteAccessController.registerForSatelliteDisallowedReasonsChanged(callback);
13765         } finally {
13766             Binder.restoreCallingIdentity(identity);
13767         }
13768     }
13769 
13770     /**
13771      * Unregisters for disallowed reasons change event from satellite service.
13772      * If callback was not registered before, the request will be ignored.
13773      *
13774      * @param callback The callback to handle disallowed reasons changed event.
13775      *                 {@link #registerForSatelliteDisallowedReasonsChanged(
13776      *                 ISatelliteDisallowedReasonsCallback)}.
13777      * @throws SecurityException if the caller doesn't have the required permission.
13778      */
13779     @Override
unregisterForSatelliteDisallowedReasonsChanged( @onNull ISatelliteDisallowedReasonsCallback callback)13780     public void unregisterForSatelliteDisallowedReasonsChanged(
13781             @NonNull ISatelliteDisallowedReasonsCallback callback) {
13782         enforceSatelliteCommunicationPermission("unregisterForSatelliteDisallowedReasonsChanged");
13783         final long identity = Binder.clearCallingIdentity();
13784         try {
13785             mSatelliteAccessController.unregisterForSatelliteDisallowedReasonsChanged(callback);
13786         } finally {
13787             Binder.restoreCallingIdentity(identity);
13788         }
13789     }
13790 
13791     /**
13792      * Request to get whether satellite communication is allowed for the current location.
13793      *
13794      * @param subId The subId of the subscription to check whether satellite communication is
13795      *              allowed for the current location for.
13796      * @param result The result receiver that returns whether satellite communication is allowed
13797      *               for the current location if the request is successful or an error code
13798      *               if the request failed.
13799      *
13800      * @throws SecurityException if the caller doesn't have the required permission.
13801      */
13802     @Override
requestIsCommunicationAllowedForCurrentLocation(int subId, @NonNull ResultReceiver result)13803     public void requestIsCommunicationAllowedForCurrentLocation(int subId,
13804             @NonNull ResultReceiver result) {
13805         enforceSatelliteCommunicationPermission("requestIsCommunicationAllowedForCurrentLocation");
13806         final long identity = Binder.clearCallingIdentity();
13807         try {
13808             mSatelliteAccessController.requestIsCommunicationAllowedForCurrentLocation(result,
13809                     false);
13810         } finally {
13811             Binder.restoreCallingIdentity(identity);
13812         }
13813     }
13814 
13815     /**
13816      * Request to get satellite access configuration for the current location.
13817      *
13818      * @param result The result receiver that returns the satellite access configuration
13819      *               for the current location if the request is successful or an error code
13820      *               if the request failed.
13821      *
13822      * @throws SecurityException if the caller doesn't have the required permission.
13823      */
13824     @Override
requestSatelliteAccessConfigurationForCurrentLocation( @onNull ResultReceiver result)13825     public void requestSatelliteAccessConfigurationForCurrentLocation(
13826             @NonNull ResultReceiver result) {
13827         enforceSatelliteCommunicationPermission(
13828                 "requestSatelliteAccessConfigurationForCurrentLocation");
13829         final long identity = Binder.clearCallingIdentity();
13830         try {
13831             mSatelliteAccessController
13832                     .requestSatelliteAccessConfigurationForCurrentLocation(result);
13833         } finally {
13834             Binder.restoreCallingIdentity(identity);
13835         }
13836     }
13837 
13838     /**
13839      * Request to get the time after which the satellite will be visible.
13840      *
13841      * @param result The result receiver that returns the time after which the satellite will
13842      *               be visible if the request is successful or an error code if the request failed.
13843      *
13844      * @throws SecurityException if the caller doesn't have the required permission.
13845      */
13846     @Override
requestTimeForNextSatelliteVisibility(@onNull ResultReceiver result)13847     public void requestTimeForNextSatelliteVisibility(@NonNull ResultReceiver result) {
13848         enforceSatelliteCommunicationPermission("requestTimeForNextSatelliteVisibility");
13849         final long identity = Binder.clearCallingIdentity();
13850         try {
13851             mSatelliteController.requestTimeForNextSatelliteVisibility(result);
13852         } finally {
13853             Binder.restoreCallingIdentity(identity);
13854         }
13855     }
13856 
13857     /**
13858      * Request to get the name to display for Satellite subscription.
13859      *
13860      * @param result The result receiver that returns the display name to use for satellite feature
13861      *               in the UI for current satellite subscription if the request is successful,
13862      *               or an error code if the request failed.
13863      *
13864      * @throws SecurityException if the caller doesn't have the required permission.
13865      */
13866     @Override
requestSatelliteDisplayName(@onNull ResultReceiver result)13867     public void requestSatelliteDisplayName(@NonNull ResultReceiver result) {
13868         enforceSatelliteCommunicationPermission("requestSatelliteDisplayName");
13869         final long identity = Binder.clearCallingIdentity();
13870         try {
13871             mSatelliteController.requestSatelliteDisplayName(result);
13872         } finally {
13873             Binder.restoreCallingIdentity(identity);
13874         }
13875     }
13876 
13877     /**
13878      * Request to get the currently selected satellite subscription id.
13879      *
13880      * @param result The result receiver that returns the currently selected satellite subscription
13881      *               id if the request is successful or an error code if the request failed.
13882      *
13883      * @throws SecurityException if the caller doesn't have the required permission.
13884      */
13885     @Override
requestSelectedNbIotSatelliteSubscriptionId(@onNull ResultReceiver result)13886     public void requestSelectedNbIotSatelliteSubscriptionId(@NonNull ResultReceiver result) {
13887         enforceSatelliteCommunicationPermission("requestSelectedNbIotSatelliteSubscriptionId");
13888         final long identity = Binder.clearCallingIdentity();
13889         try {
13890             mSatelliteController.requestSelectedNbIotSatelliteSubscriptionId(result);
13891         } finally {
13892             Binder.restoreCallingIdentity(identity);
13893         }
13894     }
13895 
13896     /**
13897      * Registers for selected satellite subscription changed event from the satellite service.
13898      *
13899      * @param callback The callback to handle the satellite subscription changed event.
13900      *
13901      * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
13902      *
13903      * @throws SecurityException if the caller doesn't have required permission.
13904      */
13905     @Override
13906     @SatelliteManager.SatelliteResult
registerForSelectedNbIotSatelliteSubscriptionChanged( @onNull ISelectedNbIotSatelliteSubscriptionCallback callback)13907     public int registerForSelectedNbIotSatelliteSubscriptionChanged(
13908             @NonNull ISelectedNbIotSatelliteSubscriptionCallback callback) {
13909         enforceSatelliteCommunicationPermission(
13910                 "registerForSelectedNbIotSatelliteSubscriptionChanged");
13911         final long identity = Binder.clearCallingIdentity();
13912         try {
13913             return mSatelliteController.registerForSelectedNbIotSatelliteSubscriptionChanged(
13914                     callback);
13915         } finally {
13916             Binder.restoreCallingIdentity(identity);
13917         }
13918     }
13919 
13920     /**
13921      * Unregisters for selected satellite subscription changed event from the satellite service.
13922      * If callback was not registered before, the request will be ignored.
13923      *
13924      * @param callback The callback that was passed to {@link
13925      *     #registerForSelectedNbIotSatelliteSubscriptionChanged(
13926      *     ISelectedNbIotSatelliteSubscriptionCallback)}.
13927      *
13928      * @throws SecurityException if the caller doesn't have required permission.
13929      */
13930     @Override
unregisterForSelectedNbIotSatelliteSubscriptionChanged( @onNull ISelectedNbIotSatelliteSubscriptionCallback callback)13931     public void unregisterForSelectedNbIotSatelliteSubscriptionChanged(
13932             @NonNull ISelectedNbIotSatelliteSubscriptionCallback callback) {
13933         enforceSatelliteCommunicationPermission(
13934                 "unregisterForSelectedNbIotSatelliteSubscriptionChanged");
13935         final long identity = Binder.clearCallingIdentity();
13936         try {
13937             mSatelliteController.unregisterForSelectedNbIotSatelliteSubscriptionChanged(
13938                     callback);
13939         } finally {
13940             Binder.restoreCallingIdentity(identity);
13941         }
13942     }
13943 
13944     /**
13945      * Inform whether the device is aligned with the satellite in both real and demo mode.
13946      *
13947      * @param isAligned {@code true} Device is aligned with the satellite.
13948      *                  {@code false} Device fails to align with the satellite.
13949      *
13950      * @throws SecurityException if the caller doesn't have required permission.
13951      */
13952     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
13953 
setDeviceAlignedWithSatellite(@onNull boolean isAligned)13954     public void setDeviceAlignedWithSatellite(@NonNull boolean isAligned) {
13955         enforceSatelliteCommunicationPermission("setDeviceAlignedWithSatellite");
13956         final long identity = Binder.clearCallingIdentity();
13957         try {
13958             mSatelliteController.setDeviceAlignedWithSatellite(isAligned);
13959         } finally {
13960             Binder.restoreCallingIdentity(identity);
13961         }
13962     }
13963 
13964     /**
13965      * Add a restriction reason for disallowing carrier supported satellite plmn scan and attach
13966      * by modem.
13967      *
13968      * @param subId The subId of the subscription to request for.
13969      * @param reason Reason for disallowing satellite communication for carrier.
13970      * @param callback Listener for the {@link SatelliteManager.SatelliteResult} result of the
13971      * operation.
13972      *
13973      * @throws SecurityException if the caller doesn't have required permission.
13974      */
addAttachRestrictionForCarrier(int subId, @SatelliteManager.SatelliteCommunicationRestrictionReason int reason, @NonNull IIntegerConsumer callback)13975     public void addAttachRestrictionForCarrier(int subId,
13976             @SatelliteManager.SatelliteCommunicationRestrictionReason int reason,
13977             @NonNull IIntegerConsumer callback) {
13978         enforceSatelliteCommunicationPermission("addAttachRestrictionForCarrier");
13979         final long identity = Binder.clearCallingIdentity();
13980         try {
13981             mSatelliteController.addAttachRestrictionForCarrier(subId, reason, callback);
13982         } finally {
13983             Binder.restoreCallingIdentity(identity);
13984         }
13985     }
13986 
13987     /**
13988      * Remove a restriction reason for disallowing carrier supported satellite plmn scan and attach
13989      * by modem.
13990      *
13991      * @param subId The subId of the subscription to request for.
13992      * @param reason Reason for disallowing satellite communication.
13993      * @param callback Listener for the {@link SatelliteManager.SatelliteResult} result of the
13994      * operation.
13995      *
13996      * @throws SecurityException if the caller doesn't have required permission.
13997      */
removeAttachRestrictionForCarrier(int subId, @SatelliteManager.SatelliteCommunicationRestrictionReason int reason, @NonNull IIntegerConsumer callback)13998     public void removeAttachRestrictionForCarrier(int subId,
13999             @SatelliteManager.SatelliteCommunicationRestrictionReason int reason,
14000             @NonNull IIntegerConsumer callback) {
14001         enforceSatelliteCommunicationPermission("removeAttachRestrictionForCarrier");
14002         final long identity = Binder.clearCallingIdentity();
14003         try {
14004             mSatelliteController.removeAttachRestrictionForCarrier(subId, reason, callback);
14005         } finally {
14006             Binder.restoreCallingIdentity(identity);
14007         }
14008     }
14009 
14010     /**
14011      * Get reasons for disallowing satellite communication, as requested by
14012      * {@link #addAttachRestrictionForCarrier(int, int, IIntegerConsumer)}.
14013      *
14014      * @param subId The subId of the subscription to request for.
14015      *
14016      * @return Integer array of reasons for disallowing satellite communication.
14017      *
14018      * @throws SecurityException if the caller doesn't have the required permission.
14019      */
getAttachRestrictionReasonsForCarrier( int subId)14020     public @NonNull int[] getAttachRestrictionReasonsForCarrier(
14021             int subId) {
14022         enforceSatelliteCommunicationPermission("getAttachRestrictionReasonsForCarrier");
14023         final long identity = Binder.clearCallingIdentity();
14024         try {
14025             Set<Integer> reasonSet =
14026                     mSatelliteController.getAttachRestrictionReasonsForCarrier(subId);
14027             return reasonSet.stream().mapToInt(i->i).toArray();
14028         } finally {
14029             Binder.restoreCallingIdentity(identity);
14030         }
14031     }
14032 
14033     /**
14034      * Request to get the signal strength of the satellite connection.
14035      *
14036      * @param result Result receiver to get the error code of the request and the current signal
14037      * strength of the satellite connection.
14038      *
14039      * @throws SecurityException if the caller doesn't have required permission.
14040      */
14041     @Override
requestNtnSignalStrength(@onNull ResultReceiver result)14042     public void requestNtnSignalStrength(@NonNull ResultReceiver result) {
14043         enforceSatelliteCommunicationPermission("requestNtnSignalStrength");
14044         final long identity = Binder.clearCallingIdentity();
14045         try {
14046             mSatelliteController.requestNtnSignalStrength(result);
14047         } finally {
14048             Binder.restoreCallingIdentity(identity);
14049         }
14050     }
14051 
14052     /**
14053      * Registers for NTN signal strength changed from satellite modem. If the registration operation
14054      * is not successful, a {@link ServiceSpecificException} that contains
14055      * {@link SatelliteManager.SatelliteResult} will be thrown.
14056      *
14057      * @param callback The callback to handle the NTN signal strength changed event. If the
14058      * operation is successful, {@link NtnSignalStrengthCallback#onNtnSignalStrengthChanged(
14059      * NtnSignalStrength)} will return an instance of {@link NtnSignalStrength} with a value of
14060      * {@link NtnSignalStrength.NtnSignalStrengthLevel} when the signal strength of non-terrestrial
14061      * network has changed.
14062      *
14063      * @throws SecurityException If the caller doesn't have the required permission.
14064      * @throws ServiceSpecificException If the callback registration operation fails.
14065      */
14066     @Override
registerForNtnSignalStrengthChanged( @onNull INtnSignalStrengthCallback callback)14067     public void registerForNtnSignalStrengthChanged(
14068             @NonNull INtnSignalStrengthCallback callback) throws RemoteException {
14069         enforceSatelliteCommunicationPermission("registerForNtnSignalStrengthChanged");
14070         final long identity = Binder.clearCallingIdentity();
14071         try {
14072             mSatelliteController.registerForNtnSignalStrengthChanged(callback);
14073         } finally {
14074             Binder.restoreCallingIdentity(identity);
14075         }
14076     }
14077 
14078     /**
14079      * Unregisters for NTN signal strength changed from satellite modem.
14080      * If callback was not registered before, the request will be ignored.
14081      *
14082      * changed event.
14083      * @param callback The callback that was passed to
14084      * {@link #registerForNtnSignalStrengthChanged(INtnSignalStrengthCallback)}
14085      *
14086      * @throws SecurityException if the caller doesn't have the required permission.
14087      */
14088     @Override
unregisterForNtnSignalStrengthChanged( @onNull INtnSignalStrengthCallback callback)14089     public void unregisterForNtnSignalStrengthChanged(
14090             @NonNull INtnSignalStrengthCallback callback) {
14091         enforceSatelliteCommunicationPermission("unregisterForNtnSignalStrengthChanged");
14092         final long identity = Binder.clearCallingIdentity();
14093         try {
14094             mSatelliteController.unregisterForNtnSignalStrengthChanged(callback);
14095         } finally {
14096             Binder.restoreCallingIdentity(identity);
14097         }
14098     }
14099 
14100     /**
14101      * Registers for satellite capabilities change event from the satellite service.
14102      *
14103      * @param callback The callback to handle the satellite capabilities changed event.
14104      *
14105      * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
14106      *
14107      * @throws SecurityException if the caller doesn't have required permission.
14108      */
14109     @Override
registerForCapabilitiesChanged( @onNull ISatelliteCapabilitiesCallback callback)14110     @SatelliteManager.SatelliteResult public int registerForCapabilitiesChanged(
14111             @NonNull ISatelliteCapabilitiesCallback callback) {
14112         enforceSatelliteCommunicationPermission("registerForCapabilitiesChanged");
14113         final long identity = Binder.clearCallingIdentity();
14114         try {
14115             return mSatelliteController.registerForCapabilitiesChanged(callback);
14116         } finally {
14117             Binder.restoreCallingIdentity(identity);
14118         }
14119     }
14120 
14121     /**
14122      * Unregisters for satellite capabilities change event from the satellite service.
14123      * If callback was not registered before, the request will be ignored.
14124      *
14125      * @param callback The callback that was passed to.
14126      * {@link #registerForCapabilitiesChanged(ISatelliteCapabilitiesCallback)}.
14127      *
14128      * @throws SecurityException if the caller doesn't have required permission.
14129      */
14130     @Override
unregisterForCapabilitiesChanged( @onNull ISatelliteCapabilitiesCallback callback)14131     public void unregisterForCapabilitiesChanged(
14132             @NonNull ISatelliteCapabilitiesCallback callback) {
14133         enforceSatelliteCommunicationPermission("unregisterForCapabilitiesChanged");
14134         final long identity = Binder.clearCallingIdentity();
14135         try {
14136             mSatelliteController.unregisterForCapabilitiesChanged(callback);
14137         } finally {
14138             Binder.restoreCallingIdentity(identity);
14139         }
14140     }
14141 
14142     /**
14143      * Registers for the satellite supported state changed.
14144      *
14145      * @param callback The callback to handle the satellite supported state changed event.
14146      *
14147      * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
14148      *
14149      * @throws SecurityException if the caller doesn't have the required permission.
14150      */
14151     @Override
registerForSatelliteSupportedStateChanged( @onNull IBooleanConsumer callback)14152     @SatelliteManager.SatelliteResult public int registerForSatelliteSupportedStateChanged(
14153             @NonNull IBooleanConsumer callback) {
14154         enforceSatelliteCommunicationPermission("registerForSatelliteSupportedStateChanged");
14155         final long identity = Binder.clearCallingIdentity();
14156         try {
14157             return mSatelliteController.registerForSatelliteSupportedStateChanged(callback);
14158         } finally {
14159             Binder.restoreCallingIdentity(identity);
14160         }
14161     }
14162 
14163     /**
14164      * Unregisters for the satellite supported state changed.
14165      * If callback was not registered before, the request will be ignored.
14166      *
14167      * @param callback The callback that was passed to
14168      *                 {@link #registerForSatelliteSupportedStateChanged(IBooleanConsumer)}
14169      *
14170      * @throws SecurityException if the caller doesn't have the required permission.
14171      */
14172     @Override
unregisterForSatelliteSupportedStateChanged( @onNull IBooleanConsumer callback)14173     public void unregisterForSatelliteSupportedStateChanged(
14174             @NonNull IBooleanConsumer callback) {
14175         enforceSatelliteCommunicationPermission("unregisterForSatelliteSupportedStateChanged");
14176         final long identity = Binder.clearCallingIdentity();
14177         try {
14178             mSatelliteController.unregisterForSatelliteSupportedStateChanged(callback);
14179         } finally {
14180             Binder.restoreCallingIdentity(identity);
14181         }
14182     }
14183 
14184     /**
14185      * This API can be used by only CTS to update satellite vendor service package name.
14186      *
14187      * @param servicePackageName The package name of the satellite vendor service.
14188      * @param provisioned Whether satellite should be provisioned or not.
14189      *
14190      * @return {@code true} if the satellite vendor service is set successfully,
14191      * {@code false} otherwise.
14192      */
setSatelliteServicePackageName(String servicePackageName, String provisioned)14193     public boolean setSatelliteServicePackageName(String servicePackageName,
14194             String provisioned) {
14195         Log.d(LOG_TAG, "setSatelliteServicePackageName - " + servicePackageName
14196                 + ", provisioned=" + provisioned);
14197         TelephonyPermissions.enforceShellOnly(
14198                 Binder.getCallingUid(), "setSatelliteServicePackageName");
14199         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14200                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14201                 "setSatelliteServicePackageName");
14202         final long identity = Binder.clearCallingIdentity();
14203         try {
14204             return mSatelliteController.setSatelliteServicePackageName(servicePackageName,
14205                     provisioned);
14206         } finally {
14207             Binder.restoreCallingIdentity(identity);
14208         }
14209     }
14210 
14211     /**
14212      * This API can be used by only CTS to override the satellite access allowed state for
14213      * a list of subscription IDs.
14214      *
14215      * @param subIdListStr The string representation of the list of subscription IDs,
14216      *                     which are numbers separated by comma.
14217      * @return {@code true} if the satellite access allowed state is set successfully,
14218      * {@code false} otherwise.
14219      */
setSatelliteAccessAllowedForSubscriptions(@ullable String subIdListStr)14220     public boolean setSatelliteAccessAllowedForSubscriptions(@Nullable String subIdListStr) {
14221         Log.d(LOG_TAG, "setSatelliteAccessAllowedForSubscriptions - " + subIdListStr);
14222         TelephonyPermissions.enforceShellOnly(
14223                 Binder.getCallingUid(), "setSatelliteAccessAllowedForSubscriptions");
14224         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14225                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14226                 "setSatelliteAccessAllowedForSubscriptions");
14227         final long identity = Binder.clearCallingIdentity();
14228         try {
14229             return mSatelliteController.setSatelliteAccessAllowedForSubscriptions(subIdListStr);
14230         } finally {
14231             Binder.restoreCallingIdentity(identity);
14232         }
14233     }
14234 
14235     /**
14236      * This API can be used by only CTS to update satellite gateway service package name.
14237      *
14238      * @param servicePackageName The package name of the satellite gateway service.
14239      * @return {@code true} if the satellite gateway service is set successfully,
14240      * {@code false} otherwise.
14241      */
setSatelliteGatewayServicePackageName(@ullable String servicePackageName)14242     public boolean setSatelliteGatewayServicePackageName(@Nullable String servicePackageName) {
14243         Log.d(LOG_TAG, "setSatelliteGatewayServicePackageName - " + servicePackageName);
14244         TelephonyPermissions.enforceShellOnly(
14245                 Binder.getCallingUid(), "setSatelliteGatewayServicePackageName");
14246         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14247                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14248                 "setSatelliteGatewayServicePackageName");
14249         final long identity = Binder.clearCallingIdentity();
14250         try {
14251             return mSatelliteController.setSatelliteGatewayServicePackageName(servicePackageName);
14252         } finally {
14253             Binder.restoreCallingIdentity(identity);
14254         }
14255     }
14256 
14257     /**
14258      * This API can be used by only CTS to update satellite pointing UI app package and class names.
14259      *
14260      * @param packageName The package name of the satellite pointing UI app.
14261      * @param className The class name of the satellite pointing UI app.
14262      * @return {@code true} if the satellite pointing UI app package and class is set successfully,
14263      * {@code false} otherwise.
14264      */
setSatellitePointingUiClassName( @ullable String packageName, @Nullable String className)14265     public boolean setSatellitePointingUiClassName(
14266             @Nullable String packageName, @Nullable String className) {
14267         Log.d(LOG_TAG, "setSatellitePointingUiClassName: packageName=" + packageName
14268                 + ", className=" + className);
14269         TelephonyPermissions.enforceShellOnly(
14270                 Binder.getCallingUid(), "setSatellitePointingUiClassName");
14271         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14272                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14273                 "setSatellitePointingUiClassName");
14274         final long identity = Binder.clearCallingIdentity();
14275         try {
14276             return mSatelliteController.setSatellitePointingUiClassName(packageName, className);
14277         } finally {
14278             Binder.restoreCallingIdentity(identity);
14279         }
14280     }
14281 
14282     /**
14283      * This API can be used by only CTS to update the timeout duration in milliseconds that
14284      * satellite should stay at listening mode to wait for the next incoming page before disabling
14285      * listening mode.
14286      *
14287      * @param timeoutMillis The timeout duration in millisecond.
14288      * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
14289      */
setSatelliteListeningTimeoutDuration(long timeoutMillis)14290     public boolean setSatelliteListeningTimeoutDuration(long timeoutMillis) {
14291         Log.d(LOG_TAG, "setSatelliteListeningTimeoutDuration - " + timeoutMillis);
14292         TelephonyPermissions.enforceShellOnly(
14293                 Binder.getCallingUid(), "setSatelliteListeningTimeoutDuration");
14294         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14295                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14296                 "setSatelliteListeningTimeoutDuration");
14297         final long identity = Binder.clearCallingIdentity();
14298         try {
14299             return mSatelliteController.setSatelliteListeningTimeoutDuration(timeoutMillis);
14300         } finally {
14301             Binder.restoreCallingIdentity(identity);
14302         }
14303     }
14304 
14305     /**
14306      * This API can be used by only CTS to override TN scanning support.
14307      *
14308      * @param reset {@code true} mean the overridden configs should not be used, {@code false}
14309      *              otherwise.
14310      * @param concurrentTnScanningSupported Whether concurrent TN scanning is supported.
14311      * @param tnScanningDuringSatelliteSessionAllowed Whether TN scanning is allowed during
14312      * a satellite session.
14313      * @return {@code true} if the TN scanning support is set successfully,
14314      * {@code false} otherwise.
14315      */
setTnScanningSupport(boolean reset, boolean concurrentTnScanningSupported, boolean tnScanningDuringSatelliteSessionAllowed)14316     public boolean setTnScanningSupport(boolean reset, boolean concurrentTnScanningSupported,
14317         boolean tnScanningDuringSatelliteSessionAllowed) {
14318         Log.d(LOG_TAG, "setTnScanningSupport: reset= " + reset
14319             + ", concurrentTnScanningSupported=" + concurrentTnScanningSupported
14320             + ", tnScanningDuringSatelliteSessionAllowed="
14321             + tnScanningDuringSatelliteSessionAllowed);
14322         TelephonyPermissions.enforceShellOnly(
14323                 Binder.getCallingUid(), "setTnScanningSupport");
14324         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14325                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14326                 "setTnScanningSupport");
14327         final long identity = Binder.clearCallingIdentity();
14328         try {
14329             return mSatelliteController.setTnScanningSupport(reset,
14330                 concurrentTnScanningSupported, tnScanningDuringSatelliteSessionAllowed);
14331         } finally {
14332             Binder.restoreCallingIdentity(identity);
14333         }
14334     }
14335 
14336     /**
14337      * This API can be used by only CTS to control ingoring cellular service state event.
14338      *
14339      * @param enabled Whether to enable boolean config.
14340      * @return {@code true} if the value is set successfully, {@code false} otherwise.
14341      */
setSatelliteIgnoreCellularServiceState(boolean enabled)14342     public boolean setSatelliteIgnoreCellularServiceState(boolean enabled) {
14343         Log.d(LOG_TAG, "setSatelliteIgnoreCellularServiceState - " + enabled);
14344         TelephonyPermissions.enforceShellOnly(
14345                 Binder.getCallingUid(), "setSatelliteIgnoreCellularServiceState");
14346         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14347                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14348                 "setSatelliteIgnoreCellularServiceState");
14349         final long identity = Binder.clearCallingIdentity();
14350         try {
14351             return mSatelliteController.setSatelliteIgnoreCellularServiceState(enabled);
14352         } finally {
14353             Binder.restoreCallingIdentity(identity);
14354         }
14355     }
14356 
14357     /**
14358      * This API can be used by only CTS to control the feature
14359      * {@code config_support_disable_satellite_while_enable_in_progress}.
14360      *
14361      * @param reset Whether to reset the override.
14362      * @param supported Whether to support the feature.
14363      * @return {@code true} if the value is set successfully, {@code false} otherwise.
14364      */
setSupportDisableSatelliteWhileEnableInProgress( boolean reset, boolean supported)14365     public boolean setSupportDisableSatelliteWhileEnableInProgress(
14366         boolean reset, boolean supported) {
14367         Log.d(LOG_TAG, "setSupportDisableSatelliteWhileEnableInProgress - reset=" + reset
14368                   + ", supported=" + supported);
14369         TelephonyPermissions.enforceShellOnly(
14370                 Binder.getCallingUid(), "setSupportDisableSatelliteWhileEnableInProgress");
14371         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14372                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14373                 "setSupportDisableSatelliteWhileEnableInProgress");
14374         final long identity = Binder.clearCallingIdentity();
14375         try {
14376             return mSatelliteController.setSupportDisableSatelliteWhileEnableInProgress(
14377                 reset, supported);
14378         } finally {
14379             Binder.restoreCallingIdentity(identity);
14380         }
14381     }
14382 
14383     /**
14384      * This API can be used by only CTS to override the timeout durations used by the
14385      * DatagramController module.
14386      *
14387      * @param timeoutMillis The timeout duration in millisecond.
14388      * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
14389      */
setDatagramControllerTimeoutDuration( boolean reset, int timeoutType, long timeoutMillis)14390     public boolean setDatagramControllerTimeoutDuration(
14391             boolean reset, int timeoutType, long timeoutMillis) {
14392         Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration - " + timeoutMillis + ", reset="
14393                 + reset + ", timeoutMillis=" + timeoutMillis);
14394         TelephonyPermissions.enforceShellOnly(
14395                 Binder.getCallingUid(), "setDatagramControllerTimeoutDuration");
14396         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14397                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14398                 "setDatagramControllerTimeoutDuration");
14399         final long identity = Binder.clearCallingIdentity();
14400         try {
14401             return mSatelliteController.setDatagramControllerTimeoutDuration(
14402                     reset, timeoutType, timeoutMillis);
14403         } finally {
14404             Binder.restoreCallingIdentity(identity);
14405         }
14406     }
14407 
14408     /**
14409      * This API can be used by only CTS to override the boolean configs used by the
14410      * DatagramController module.
14411      *
14412      * @param enable Whether to enable or disable boolean config.
14413      * @return {@code true} if the boolean config is set successfully, {@code false} otherwise.
14414      */
setDatagramControllerBooleanConfig( boolean reset, int booleanType, boolean enable)14415     public boolean setDatagramControllerBooleanConfig(
14416             boolean reset, int booleanType, boolean enable) {
14417         Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: booleanType=" + booleanType
14418                 + ", reset=" + reset + ", enable=" + enable);
14419         TelephonyPermissions.enforceShellOnly(
14420                 Binder.getCallingUid(), "setDatagramControllerBooleanConfig");
14421         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14422                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14423                 "ssetDatagramControllerBooleanConfig");
14424         final long identity = Binder.clearCallingIdentity();
14425         try {
14426             return mSatelliteController.setDatagramControllerBooleanConfig(reset, booleanType,
14427                     enable);
14428         } finally {
14429             Binder.restoreCallingIdentity(identity);
14430         }
14431     }
14432 
14433 
14434     /**
14435      * This API can be used by only CTS to override the timeout durations used by the
14436      * SatelliteController module.
14437      *
14438      * @param timeoutMillis The timeout duration in millisecond.
14439      * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
14440      */
setSatelliteControllerTimeoutDuration( boolean reset, int timeoutType, long timeoutMillis)14441     public boolean setSatelliteControllerTimeoutDuration(
14442             boolean reset, int timeoutType, long timeoutMillis) {
14443         Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration - " + timeoutMillis + ", reset="
14444                 + reset + ", timeoutMillis=" + timeoutMillis);
14445         TelephonyPermissions.enforceShellOnly(
14446                 Binder.getCallingUid(), "setSatelliteControllerTimeoutDuration");
14447         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14448                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14449                 "setSatelliteControllerTimeoutDuration");
14450         final long identity = Binder.clearCallingIdentity();
14451         try {
14452             return mSatelliteController.setSatelliteControllerTimeoutDuration(
14453                     reset, timeoutType, timeoutMillis);
14454         } finally {
14455             Binder.restoreCallingIdentity(identity);
14456         }
14457     }
14458 
14459     /**
14460      * This API can be used in only testing to override connectivity status in monitoring emergency
14461      * calls and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.
14462      *
14463      * @param handoverType The type of handover from emergency call to satellite messaging. Use one
14464      *                     of the following values to enable the override:
14465      *                     0 - EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_SOS
14466      *                     1 - EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE_T911
14467      *                     To disable the override, use -1 for handoverType.
14468      * @param delaySeconds The event EVENT_DISPLAY_EMERGENCY_MESSAGE will be sent to Dialer
14469      *                     delaySeconds after the emergency call starts.
14470      * @return {@code true} if the handover type is set successfully, {@code false} otherwise.
14471      */
setEmergencyCallToSatelliteHandoverType(int handoverType, int delaySeconds)14472     public boolean setEmergencyCallToSatelliteHandoverType(int handoverType, int delaySeconds) {
14473         Log.d(LOG_TAG, "setEmergencyCallToSatelliteHandoverType - " + handoverType);
14474         TelephonyPermissions.enforceShellOnly(
14475                 Binder.getCallingUid(), "setEmergencyCallToSatelliteHandoverType");
14476         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14477                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14478                 "setEmergencyCallToSatelliteHandoverType");
14479         final long identity = Binder.clearCallingIdentity();
14480         try {
14481             return mSatelliteController.setEmergencyCallToSatelliteHandoverType(
14482                     handoverType, delaySeconds);
14483         } finally {
14484             Binder.restoreCallingIdentity(identity);
14485         }
14486     }
14487 
14488     /**
14489      * This API can be used in only testing to override oem-enabled satellite provision status.
14490      *
14491      * @param reset {@code true} mean the overriding status should not be used, {@code false}
14492      *              otherwise.
14493      * @param isProvisioned The overriding provision status.
14494      * @return {@code true} if the provision status is set successfully, {@code false} otherwise.
14495      */
setOemEnabledSatelliteProvisionStatus(boolean reset, boolean isProvisioned)14496     public boolean setOemEnabledSatelliteProvisionStatus(boolean reset, boolean isProvisioned) {
14497         Log.d(LOG_TAG, "setOemEnabledSatelliteProvisionStatus - reset=" + reset
14498                 + ", isProvisioned=" + isProvisioned);
14499         TelephonyPermissions.enforceShellOnly(
14500                 Binder.getCallingUid(), "setOemEnabledSatelliteProvisionStatus");
14501         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14502                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14503                 "setOemEnabledSatelliteProvisionStatus");
14504         final long identity = Binder.clearCallingIdentity();
14505         try {
14506             return mSatelliteController.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
14507         } finally {
14508             Binder.restoreCallingIdentity(identity);
14509         }
14510     }
14511 
14512     /**
14513      * This API should be used by only CTS tests to forcefully set telephony country codes.
14514      *
14515      * @return {@code true} if the country code is set successfully, {@code false} otherwise.
14516      */
setCountryCodes(boolean reset, List<String> currentNetworkCountryCodes, Map cachedNetworkCountryCodes, String locationCountryCode, long locationCountryCodeTimestampNanos)14517     public boolean setCountryCodes(boolean reset, List<String> currentNetworkCountryCodes,
14518             Map cachedNetworkCountryCodes, String locationCountryCode,
14519             long locationCountryCodeTimestampNanos) {
14520         Log.d(LOG_TAG, "setCountryCodes: currentNetworkCountryCodes="
14521                 + String.join(", ", currentNetworkCountryCodes)
14522                 + ", locationCountryCode=" + locationCountryCode
14523                 + ", locationCountryCodeTimestampNanos" + locationCountryCodeTimestampNanos
14524                 + ", reset=" + reset + ", cachedNetworkCountryCodes="
14525                 + String.join(", ", cachedNetworkCountryCodes.keySet()));
14526         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCountryCodes");
14527         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14528                 SubscriptionManager.INVALID_SUBSCRIPTION_ID, "setCountryCodes");
14529         final long identity = Binder.clearCallingIdentity();
14530         try {
14531             return TelephonyCountryDetector.getInstance(getDefaultPhone().getContext(),
14532                     mFeatureFlags).setCountryCodes(reset, currentNetworkCountryCodes,
14533                     cachedNetworkCountryCodes, locationCountryCode,
14534                     locationCountryCodeTimestampNanos);
14535         } finally {
14536             Binder.restoreCallingIdentity(identity);
14537         }
14538     }
14539 
14540     /**
14541      * This API is used by CTS to override the version of the config data
14542      *
14543      * @param reset Whether to restore the original version
14544      * @param version The overriding version
14545      * @return {@code true} if successful, {@code false} otherwise
14546      */
overrideConfigDataVersion(boolean reset, int version)14547     public boolean overrideConfigDataVersion(boolean reset, int version) {
14548         Log.d(LOG_TAG, "overrideVersion - reset=" + reset + ", version=" + version);
14549         TelephonyPermissions.enforceShellOnly(
14550                 Binder.getCallingUid(), "overrideConfigDataVersion");
14551         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14552                 SubscriptionManager.INVALID_SUBSCRIPTION_ID, "overrideVersion");
14553         return TelephonyConfigUpdateInstallReceiver.getInstance().overrideVersion(reset, version);
14554     }
14555 
14556     /**
14557      * This API should be used by only CTS tests to override the overlay configs of satellite
14558      * access controller.
14559      *
14560      * @param reset {@code true} mean the overridden configs should not be used, {@code false}
14561      *              otherwise.
14562      * @return {@code true} if the overlay configs are set successfully, {@code false} otherwise.
14563      */
setSatelliteAccessControlOverlayConfigs(boolean reset, boolean isAllowed, String s2CellFile, long locationFreshDurationNanos, List<String> satelliteCountryCodes, String satelliteAccessConfigurationFile)14564     public boolean setSatelliteAccessControlOverlayConfigs(boolean reset, boolean isAllowed,
14565             String s2CellFile, long locationFreshDurationNanos,
14566             List<String> satelliteCountryCodes, String satelliteAccessConfigurationFile) {
14567         Log.d(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: reset=" + reset
14568                 + ", isAllowed" + isAllowed + ", s2CellFile=" + s2CellFile
14569                 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
14570                 + ", satelliteCountryCodes=" + ((satelliteCountryCodes != null)
14571                 ? String.join(", ", satelliteCountryCodes) : null)
14572                 + ", satelliteAccessConfigurationFile=" + satelliteAccessConfigurationFile);
14573         TelephonyPermissions.enforceShellOnly(
14574                 Binder.getCallingUid(), "setSatelliteAccessControlOverlayConfigs");
14575         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14576                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14577                 "setSatelliteAccessControlOverlayConfigs");
14578         final long identity = Binder.clearCallingIdentity();
14579         try {
14580             return mSatelliteAccessController.setSatelliteAccessControlOverlayConfigs(reset,
14581                     isAllowed, s2CellFile, locationFreshDurationNanos, satelliteCountryCodes,
14582                     satelliteAccessConfigurationFile);
14583         } finally {
14584             Binder.restoreCallingIdentity(identity);
14585         }
14586     }
14587 
14588     /**
14589      * This API can be used by only CTS to override the cached value for the device overlay config
14590      * value : config_send_satellite_datagram_to_modem_in_demo_mode, which determines whether
14591      * outgoing satellite datagrams should be sent to modem in demo mode.
14592      *
14593      * @param shouldSendToModemInDemoMode Whether send datagram in demo mode should be sent to
14594      * satellite modem or not.
14595      *
14596      * @return {@code true} if the operation is successful, {@code false} otherwise.
14597      */
setShouldSendDatagramToModemInDemoMode(boolean shouldSendToModemInDemoMode)14598     public boolean setShouldSendDatagramToModemInDemoMode(boolean shouldSendToModemInDemoMode) {
14599         Log.d(LOG_TAG, "setShouldSendDatagramToModemInDemoMode");
14600         TelephonyPermissions.enforceShellOnly(
14601                 Binder.getCallingUid(), "setShouldSendDatagramToModemInDemoMode");
14602         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14603                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14604                 "setShouldSendDatagramToModemInDemoMode");
14605         final long identity = Binder.clearCallingIdentity();
14606         try {
14607             return mSatelliteController.setShouldSendDatagramToModemInDemoMode(
14608                     shouldSendToModemInDemoMode);
14609         } finally {
14610             Binder.restoreCallingIdentity(identity);
14611         }
14612     }
14613 
14614     /**
14615      * This API can be used by only CTS to set the cache whether satellite communication is allowed.
14616      *
14617      * @param state a state indicates whether satellite access allowed state should be cached and
14618      * the allowed state.
14619      * @return {@code true} if the setting is successful, {@code false} otherwise.
14620      */
setIsSatelliteCommunicationAllowedForCurrentLocationCache(String state)14621     public boolean setIsSatelliteCommunicationAllowedForCurrentLocationCache(String state) {
14622         Log.d(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache: "
14623                 + "state=" + state);
14624         TelephonyPermissions.enforceShellOnly(
14625                 Binder.getCallingUid(),
14626                 "setIsSatelliteCommunicationAllowedForCurrentLocationCache");
14627         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14628                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
14629                 "setIsSatelliteCommunicationAllowedForCurrentLocationCache");
14630         final long identity = Binder.clearCallingIdentity();
14631         try {
14632             return mSatelliteAccessController
14633                     .setIsSatelliteCommunicationAllowedForCurrentLocationCache(state);
14634         } finally {
14635             Binder.restoreCallingIdentity(identity);
14636         }
14637     }
14638 
14639     /**
14640      * Sets the service defined in ComponentName to be bound.
14641      *
14642      * This should only be used for testing.
14643      * @return {@code true} if the DomainSelectionService to bind to was set,
14644      *         {@code false} otherwise.
14645      */
14646     @Override
setDomainSelectionServiceOverride(ComponentName componentName)14647     public boolean setDomainSelectionServiceOverride(ComponentName componentName) {
14648         Log.i(LOG_TAG, "setDomainSelectionServiceOverride component=" + componentName);
14649 
14650         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
14651                 "setDomainSelectionServiceOverride");
14652         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14653                 getDefaultSubscription(), "setDomainSelectionServiceOverride");
14654 
14655         final long identity = Binder.clearCallingIdentity();
14656         try {
14657             if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
14658                 return DomainSelectionResolver.getInstance()
14659                         .setDomainSelectionServiceOverride(componentName);
14660             }
14661         } finally {
14662             Binder.restoreCallingIdentity(identity);
14663         }
14664         return false;
14665     }
14666 
14667     /**
14668      * Clears the DomainSelectionService override.
14669      *
14670      * This should only be used for testing.
14671      * @return {@code true} if the DomainSelectionService override was cleared,
14672      *         {@code false} otherwise.
14673      */
14674     @Override
clearDomainSelectionServiceOverride()14675     public boolean clearDomainSelectionServiceOverride() {
14676         Log.i(LOG_TAG, "clearDomainSelectionServiceOverride");
14677 
14678         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
14679                 "clearDomainSelectionServiceOverride");
14680         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
14681                 getDefaultSubscription(), "clearDomainSelectionServiceOverride");
14682 
14683         final long identity = Binder.clearCallingIdentity();
14684         try {
14685             if (DomainSelectionResolver.getInstance().isDomainSelectionSupported()) {
14686                 return DomainSelectionResolver.getInstance()
14687                         .clearDomainSelectionServiceOverride();
14688             }
14689         } finally {
14690             Binder.restoreCallingIdentity(identity);
14691         }
14692         return false;
14693     }
14694 
14695     /**
14696      * Enable or disable notifications sent for cellular identifier disclosure events.
14697      *
14698      * Disclosure events are defined as instances where a device has sent a cellular identifier
14699      * on the Non-access stratum (NAS) before a security context is established. As a result the
14700      * identifier is sent in the clear, which has privacy implications for the user.
14701      *
14702      * @param enable if notifications about disclosure events should be enabled
14703      * @throws SecurityException             if the caller does not have the required privileges
14704      * @throws UnsupportedOperationException if the modem does not support this feature.
14705      */
14706     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setEnableCellularIdentifierDisclosureNotifications(boolean enable)14707     public void setEnableCellularIdentifierDisclosureNotifications(boolean enable) {
14708         enforceModifyPermission();
14709         checkForIdentifierDisclosureNotificationSupport();
14710 
14711         SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
14712         editor.putBoolean(Phone.PREF_IDENTIFIER_DISCLOSURE_NOTIFICATIONS_ENABLED, enable);
14713         editor.apply();
14714 
14715         // Each phone instance is responsible for updating its respective modem immediately
14716         // after we've made a preference change.
14717         for (Phone phone : PhoneFactory.getPhones()) {
14718             phone.handleIdentifierDisclosureNotificationPreferenceChange();
14719         }
14720     }
14721 
14722     /**
14723      * Get whether or not cellular identifier disclosure notifications are enabled.
14724      *
14725      * @throws SecurityException             if the caller does not have the required privileges
14726      * @throws UnsupportedOperationException if the modem does not support this feature.
14727      */
14728     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
isCellularIdentifierDisclosureNotificationsEnabled()14729     public boolean isCellularIdentifierDisclosureNotificationsEnabled() {
14730         enforceReadPrivilegedPermission("isCellularIdentifierDisclosureNotificationEnabled");
14731         checkForIdentifierDisclosureNotificationSupport();
14732         return getDefaultPhone().getIdentifierDisclosureNotificationsPreferenceEnabled();
14733     }
14734 
14735     /**
14736      * Enables or disables notifications sent when cellular null cipher or integrity algorithms
14737      * are in use by the cellular modem.
14738      *
14739      * @throws IllegalStateException if the Telephony process is not currently available
14740      * @throws SecurityException if the caller does not have the required privileges
14741      * @throws UnsupportedOperationException if the modem does not support reporting on ciphering
14742      * and integrity algorithms in use
14743      * @hide
14744      */
14745     @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
setNullCipherNotificationsEnabled(boolean enable)14746     public void setNullCipherNotificationsEnabled(boolean enable) {
14747         enforceModifyPermission();
14748         checkForNullCipherNotificationSupport();
14749 
14750         SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
14751         editor.putBoolean(Phone.PREF_NULL_CIPHER_NOTIFICATIONS_ENABLED, enable);
14752         editor.apply();
14753 
14754         // Each phone instance is responsible for updating its respective modem immediately
14755         // after a preference change.
14756         for (Phone phone : PhoneFactory.getPhones()) {
14757             phone.handleNullCipherNotificationPreferenceChanged();
14758         }
14759     }
14760 
14761     /**
14762      * Get whether notifications are enabled for null cipher or integrity algorithms in use by the
14763      * cellular modem.
14764      *
14765      * @throws IllegalStateException if the Telephony process is not currently available
14766      * @throws SecurityException if the caller does not have the required privileges
14767      * @throws UnsupportedOperationException if the modem does not support reporting on ciphering
14768      * and integrity algorithms in use
14769      * @hide
14770      */
14771     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
isNullCipherNotificationsEnabled()14772     public boolean isNullCipherNotificationsEnabled() {
14773         enforceReadPrivilegedPermission("isNullCipherNotificationsEnabled");
14774         checkForNullCipherNotificationSupport();
14775         return getDefaultPhone().getNullCipherNotificationsPreferenceEnabled();
14776     }
14777 
14778     /**
14779      * Check whether the caller (or self, if not processing an IPC) can read device identifiers.
14780      *
14781      * <p>This method behaves in one of the following ways:
14782      * <ul>
14783      *     <li>return true : if the calling package has the appop permission {@link
14784      *     Manifest.permission#USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER} in the manifest </>
14785      *     <li>return true : if any one subscription has the READ_PRIVILEGED_PHONE_STATE
14786      *     permission, the calling package passes a DevicePolicyManager Device Owner / Profile
14787      *     Owner device identifier access check, or the calling package has carrier privileges</>
14788      *     <li>throw SecurityException: if the caller does not meet any of the requirements.
14789      * </ul>
14790      */
checkCallingOrSelfReadDeviceIdentifiersForAnySub(Context context, String callingPackage, @Nullable String callingFeatureId, String message)14791     private static boolean checkCallingOrSelfReadDeviceIdentifiersForAnySub(Context context,
14792             String callingPackage, @Nullable String callingFeatureId, String message) {
14793         for (Phone phone : PhoneFactory.getPhones()) {
14794             if (TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(context,
14795                     phone.getSubId(), callingPackage, callingFeatureId, message)) {
14796                 return true;
14797             }
14798         }
14799         return false;
14800     }
14801 
14802     /**
14803      * @return The subscription manager service instance.
14804      */
getSubscriptionManagerService()14805     public SubscriptionManagerService getSubscriptionManagerService() {
14806         return SubscriptionManagerService.getInstance();
14807     }
14808 
14809     /**
14810      * Class binds the consumer[callback] and carrierId.
14811      */
14812     private static class CallerCallbackInfo {
14813         private final Consumer<Integer> mConsumer;
14814         private final Set<Integer> mCarrierIds;
14815 
CallerCallbackInfo(Consumer<Integer> consumer, Set<Integer> carrierIds)14816         public CallerCallbackInfo(Consumer<Integer> consumer, Set<Integer> carrierIds) {
14817             mConsumer = consumer;
14818             mCarrierIds = carrierIds;
14819         }
14820 
getConsumer()14821         public Consumer<Integer> getConsumer() {
14822             return mConsumer;
14823         }
14824 
getCarrierIds()14825         public Set<Integer> getCarrierIds() {
14826             return mCarrierIds;
14827         }
14828     }
14829 
14830     /*
14831     * PhoneInterfaceManager is a singleton. Unit test calls the init() with context.
14832     * But the context that is passed in is unused if the phone app is already alive.
14833     * In this case PackageManager object is different in PhoneInterfaceManager and Unit test.
14834     */
14835     @VisibleForTesting
setPackageManager(PackageManager packageManager)14836     public void setPackageManager(PackageManager packageManager) {
14837         mPackageManager = packageManager;
14838     }
14839 
14840     /*
14841      * PhoneInterfaceManager is a singleton. Unit test calls the init() with context.
14842      * But the context that is passed in is unused if the phone app is already alive.
14843      * In this case PackageManager object is different in PhoneInterfaceManager and Unit test.
14844      */
14845     @VisibleForTesting
setAppOpsManager(AppOpsManager appOps)14846     public void setAppOpsManager(AppOpsManager appOps) {
14847         mAppOps = appOps;
14848     }
14849 
14850     /*
14851      * PhoneInterfaceManager is a singleton. Unit test calls the init() with FeatureFlags.
14852      * But the FeatureFlags that is passed in is unused if the phone app is already alive.
14853      * In this case FeatureFlags object is different in PhoneInterfaceManager and Unit test.
14854      */
14855     @VisibleForTesting
setFeatureFlags(FeatureFlags featureFlags)14856     public void setFeatureFlags(FeatureFlags featureFlags) {
14857         mFeatureFlags = featureFlags;
14858     }
14859 
14860     /**
14861      * Make sure the device has required telephony feature
14862      *
14863      * @throws UnsupportedOperationException if the device does not have required telephony feature
14864      */
enforceTelephonyFeatureWithException(@ullable String callingPackage, @NonNull String telephonyFeature, @NonNull String methodName)14865     private void enforceTelephonyFeatureWithException(@Nullable String callingPackage,
14866             @NonNull String telephonyFeature, @NonNull String methodName) {
14867         if (callingPackage == null || mPackageManager == null) {
14868             return;
14869         }
14870 
14871         if (!CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, callingPackage,
14872                 Binder.getCallingUserHandle())
14873                 || mVendorApiLevel < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
14874             // Skip to check associated telephony feature,
14875             // if compatibility change is not enabled for the current process or
14876             // the SDK version of vendor partition is less than Android V.
14877             return;
14878         }
14879 
14880         if (!mPackageManager.hasSystemFeature(telephonyFeature)) {
14881             throw new UnsupportedOperationException(
14882                     methodName + " is unsupported without " + telephonyFeature);
14883         }
14884     }
14885 
14886     /**
14887      * Make sure the device has at least one of the required telephony feature
14888      *
14889      * @throws UnsupportedOperationException if the device does not have any of the required
14890      *     telephony feature
14891      */
enforceTelephonyFeatureWithException( @ullable String callingPackage, @NonNull List<String> anyOfTelephonyFeatures, @NonNull String methodName)14892     private void enforceTelephonyFeatureWithException(
14893             @Nullable String callingPackage,
14894             @NonNull List<String> anyOfTelephonyFeatures,
14895             @NonNull String methodName) {
14896         if (callingPackage == null || mPackageManager == null) {
14897             return;
14898         }
14899 
14900         if (!CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, callingPackage,
14901                 Binder.getCallingUserHandle())
14902                 || mVendorApiLevel < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
14903             // Skip to check associated telephony feature,
14904             // if compatibility change is not enabled for the current process or
14905             // the SDK version of vendor partition is less than Android V.
14906             return;
14907         }
14908         for (String feature : anyOfTelephonyFeatures) {
14909             if (mPackageManager.hasSystemFeature(feature)) {
14910                 // At least one feature is present, so the requirement is satisfied.
14911                 return;
14912             }
14913         }
14914 
14915         // No features were found.
14916         throw new UnsupportedOperationException(
14917                 methodName + " is unsupported without any of " + anyOfTelephonyFeatures);
14918     }
14919 
14920     /**
14921      * Registers for the satellite communication allowed state changed.
14922      *
14923      * @param subId The subId of the subscription to register for the satellite communication
14924      *              allowed state changed.
14925      * @param callback The callback to handle the satellite communication allowed
14926      *                 state changed event.
14927      *
14928      * @return The {@link SatelliteManager.SatelliteResult} result of the operation.
14929      *
14930      * @throws SecurityException if the caller doesn't have the required permission.
14931      */
14932     @Override
registerForCommunicationAccessStateChanged( int subId, @NonNull ISatelliteCommunicationAccessStateCallback callback)14933     @SatelliteManager.SatelliteResult public int registerForCommunicationAccessStateChanged(
14934             int subId, @NonNull ISatelliteCommunicationAccessStateCallback callback) {
14935         enforceSatelliteCommunicationPermission("registerForCommunicationAccessStateChanged");
14936         final long identity = Binder.clearCallingIdentity();
14937         try {
14938             return mSatelliteAccessController.registerForCommunicationAccessStateChanged(
14939                     subId, callback);
14940         } finally {
14941             Binder.restoreCallingIdentity(identity);
14942         }
14943     }
14944 
14945     /**
14946      * Unregisters for the satellite communication allowed state changed.
14947      * If callback was not registered before, the request will be ignored.
14948      *
14949      * @param subId    The subId of the subscription to unregister for the satellite communication
14950      *                 allowed state changed.
14951      * @param callback The callback that was passed to
14952      *                 {@link #registerForCommunicationAccessStateChanged(int,
14953      *                 ISatelliteCommunicationAccessStateCallback)}.     *
14954      * @throws SecurityException if the caller doesn't have the required permission.
14955      */
14956     @Override
unregisterForCommunicationAccessStateChanged( int subId, @NonNull ISatelliteCommunicationAccessStateCallback callback)14957     public void unregisterForCommunicationAccessStateChanged(
14958             int subId, @NonNull ISatelliteCommunicationAccessStateCallback callback) {
14959         enforceSatelliteCommunicationPermission("unregisterForCommunicationAccessStateChanged");
14960         final long identity = Binder.clearCallingIdentity();
14961         try {
14962             mSatelliteAccessController.unregisterForCommunicationAccessStateChanged(subId,
14963                     callback);
14964         } finally {
14965             Binder.restoreCallingIdentity(identity);
14966         }
14967     }
14968 
14969     /**
14970      * Request to get the {@link SatelliteSessionStats} of the satellite service.
14971      *
14972      * @param subId The subId of the subscription to the satellite session stats for.
14973      * @param result The result receiver that returns the {@link SatelliteSessionStats}
14974      *               if the request is successful or an error code if the request failed.
14975      *
14976      * @throws SecurityException if the caller doesn't have required permission.
14977      */
14978     @Override
requestSatelliteSessionStats(int subId, @NonNull ResultReceiver result)14979     public void requestSatelliteSessionStats(int subId, @NonNull ResultReceiver result) {
14980         enforceModifyPermission();
14981         enforcePackageUsageStatsPermission("requestSatelliteSessionStats");
14982         final long identity = Binder.clearCallingIdentity();
14983         try {
14984             mSatelliteController.requestSatelliteSessionStats(subId, result);
14985         } finally {
14986             Binder.restoreCallingIdentity(identity);
14987         }
14988     }
14989 
14990     /**
14991      * Request to get list of prioritized satellite subscriber ids to be used for provision.
14992      *
14993      * @param result The result receiver, which returns the list of prioritized satellite tokens
14994      * to be used for provision if the request is successful or an error code if the request failed.
14995      *
14996      * @throws SecurityException if the caller doesn't have the required permission.
14997      */
14998     @Override
requestSatelliteSubscriberProvisionStatus(@onNull ResultReceiver result)14999     public void requestSatelliteSubscriberProvisionStatus(@NonNull ResultReceiver result) {
15000         enforceSatelliteCommunicationPermission("requestSatelliteSubscriberProvisionStatus");
15001         final long identity = Binder.clearCallingIdentity();
15002         try {
15003             mSatelliteController.requestSatelliteSubscriberProvisionStatus(result);
15004         } finally {
15005             Binder.restoreCallingIdentity(identity);
15006         }
15007     }
15008 
15009     /**
15010      * Deliver the list of provisioned satellite subscriber ids.
15011      *
15012      * @param list List of provisioned satellite subscriber ids.
15013      * @param result The result receiver that returns whether deliver success or fail.
15014      *
15015      * @throws SecurityException if the caller doesn't have the required permission.
15016      */
15017     @Override
provisionSatellite(@onNull List<SatelliteSubscriberInfo> list, @NonNull ResultReceiver result)15018     public void provisionSatellite(@NonNull List<SatelliteSubscriberInfo> list,
15019             @NonNull ResultReceiver result) {
15020         enforceSatelliteCommunicationPermission("provisionSatellite");
15021         final long identity = Binder.clearCallingIdentity();
15022         try {
15023             mSatelliteController.provisionSatellite(list, result);
15024         } finally {
15025             Binder.restoreCallingIdentity(identity);
15026         }
15027     }
15028 
15029     /**
15030      * Deliver the list of deprovisioned satellite subscriber ids.
15031      *
15032      * @param list List of deprovisioned satellite subscriber ids.
15033      * @param result The result receiver that returns whether deliver success or fail.
15034      *
15035      * @throws SecurityException if the caller doesn't have the required permission.
15036      */
15037     @Override
deprovisionSatellite(@onNull List<SatelliteSubscriberInfo> list, @NonNull ResultReceiver result)15038     public void deprovisionSatellite(@NonNull List<SatelliteSubscriberInfo> list,
15039             @NonNull ResultReceiver result) {
15040         enforceSatelliteCommunicationPermission("deprovisionSatellite");
15041         final long identity = Binder.clearCallingIdentity();
15042         try {
15043             mSatelliteController.deprovisionSatellite(list, result);
15044         } finally {
15045             Binder.restoreCallingIdentity(identity);
15046         }
15047     }
15048 
15049 
15050     /**
15051      * Inform whether application supports NTN SMS in satellite mode.
15052      *
15053      * This method is used by default messaging application to inform framework whether it supports
15054      * NTN SMS or not.
15055      *
15056      * @param ntnSmsSupported {@code true} If application supports NTN SMS, else {@code false}.
15057      *
15058      * @throws SecurityException if the caller doesn't have required permission.
15059      */
15060     @Override
setNtnSmsSupported(boolean ntnSmsSupported)15061     public void setNtnSmsSupported(boolean ntnSmsSupported) {
15062         enforceSatelliteCommunicationPermission("setNtnSmsSupported");
15063         enforceSendSmsPermission();
15064 
15065         final long identity = Binder.clearCallingIdentity();
15066         try {
15067             mSatelliteController.setNtnSmsSupportedByMessagesApp(ntnSmsSupported);
15068         } finally {
15069             Binder.restoreCallingIdentity(identity);
15070         }
15071     }
15072 
15073     /**
15074      * This API can be used by only CTS to override the cached value for the device overlay config
15075      * value :
15076      * config_satellite_gateway_service_package and
15077      * config_satellite_carrier_roaming_esos_provisioned_class.
15078      * These values are set before sending an intent to broadcast there are any change to list of
15079      * subscriber informations.
15080      *
15081      * @param name the name is one of the following that constitute an intent.
15082      * Component package name, or component class name.
15083      * @return {@code true} if the setting is successful, {@code false} otherwise.
15084      */
15085     @Override
setSatelliteSubscriberIdListChangedIntentComponent(String name)15086     public boolean setSatelliteSubscriberIdListChangedIntentComponent(String name) {
15087         if (!mFeatureFlags.carrierRoamingNbIotNtn()) {
15088             Log.d(LOG_TAG, "setSatelliteSubscriberIdListChangedIntentComponent:"
15089                     + " carrierRoamingNbIotNtn is disabled");
15090             return false;
15091         }
15092         Log.d(LOG_TAG, "setSatelliteSubscriberIdListChangedIntentComponent");
15093         TelephonyPermissions.enforceShellOnly(
15094                 Binder.getCallingUid(), "setSatelliteSubscriberIdListChangedIntentComponent");
15095         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
15096                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
15097                 "setSatelliteSubscriberIdListChangedIntentComponent");
15098         final long identity = Binder.clearCallingIdentity();
15099         try {
15100             return mSatelliteController.setSatelliteSubscriberIdListChangedIntentComponent(name);
15101         } finally {
15102             Binder.restoreCallingIdentity(identity);
15103         }
15104     }
15105 
15106     /**
15107      * This API can be used by only CTS to override the Euicc UI component.
15108      *
15109      * @param componentName ui component to be launched for testing. {@code null} to reset.
15110      *
15111      * @hide
15112      */
15113     @Override
setTestEuiccUiComponent(@ullable ComponentName componentName)15114     public void setTestEuiccUiComponent(@Nullable ComponentName componentName) {
15115         enforceModifyPermission();
15116         log("setTestEuiccUiComponent: " + componentName);
15117         mTestEuiccUiComponent = componentName;
15118     }
15119 
15120     /**
15121      * This API can be used by only CTS to retrieve the Euicc UI component.
15122      *
15123      * @return Euicc UI component. {@code null} if not available.
15124      * @hide
15125      */
15126     @Override
15127     @Nullable
getTestEuiccUiComponent()15128     public ComponentName getTestEuiccUiComponent() {
15129         enforceReadPrivilegedPermission("getTestEuiccUiComponent");
15130         return mTestEuiccUiComponent;
15131     }
15132 
15133     /**
15134      * This API can be used only for test purpose to override the carrier roaming Ntn eligibility
15135      *
15136      * @param state        to update Ntn Eligibility.
15137      * @param resetRequired to reset the overridden flag in satellite controller.
15138      * @return {@code true} if the shell command is successful, {@code false} otherwise.
15139      */
overrideCarrierRoamingNtnEligibilityChanged(boolean state, boolean resetRequired)15140     public boolean overrideCarrierRoamingNtnEligibilityChanged(boolean state,
15141             boolean resetRequired) {
15142         final long identity = Binder.clearCallingIdentity();
15143         try {
15144             return mSatelliteAccessController.overrideCarrierRoamingNtnEligibilityChanged(state,
15145                     resetRequired);
15146         } finally {
15147             Binder.restoreCallingIdentity(identity);
15148         }
15149     }
15150 
15151     /**
15152      * Returns carrier id maps to the passing {@link CarrierIdentifier}.
15153      *
15154      * @param carrierIdentifier {@link CarrierIdentifier}.
15155      *
15156      * @return carrier id from passing {@link CarrierIdentifier} or UNKNOWN_CARRIER_ID
15157      * if the carrier cannot be identified
15158      */
getCarrierIdFromIdentifier(@onNull CarrierIdentifier carrierIdentifier)15159     public int getCarrierIdFromIdentifier(@NonNull CarrierIdentifier carrierIdentifier) {
15160         enforceReadPrivilegedPermission("getCarrierIdFromIdentifier");
15161         enforceTelephonyFeatureWithException(getCurrentPackageName(),
15162                 PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getCarrierIdFromIdentifier");
15163 
15164         final long identity = Binder.clearCallingIdentity();
15165         try {
15166             return CarrierResolver.getCarrierIdFromIdentifier(mApp, carrierIdentifier);
15167         } finally {
15168             Binder.restoreCallingIdentity(identity);
15169         }
15170     }
15171 
15172     /**
15173      * Get list of applications that are optimized for low bandwidth satellite data.
15174      *
15175      * @return List of Application Name with data optimized network property.
15176      * {@link #PROPERTY_SATELLITE_DATA_OPTIMIZED}
15177      */
15178     @Override
getSatelliteDataOptimizedApps()15179     public List<String> getSatelliteDataOptimizedApps() {
15180         enforceSatelliteCommunicationPermission("getSatelliteDataOptimizedApps");
15181         List<String> appNames = new ArrayList<>();
15182         int userId = Binder.getCallingUserHandle().getIdentifier();
15183         final long identity = Binder.clearCallingIdentity();
15184         try {
15185             appNames = mSatelliteController.getSatelliteDataOptimizedApps(userId);
15186         } finally {
15187             Binder.restoreCallingIdentity(identity);
15188         }
15189 
15190         return appNames;
15191     }
15192 
15193     /**
15194      * Method to return the current satellite data service policy supported mode for the
15195      * subscriptionId based on carrier config.
15196      *
15197      * @param subId current subscription id.
15198      *
15199      * @return Supported modes {@link SatelliteManager#SatelliteDataSupportMode}
15200      * @throws IllegalArgumentException if the subscription is invalid.
15201      *
15202      * @hide
15203      */
15204     @Override
15205     @SatelliteManager.SatelliteDataSupportMode
getSatelliteDataSupportMode(int subId)15206     public int getSatelliteDataSupportMode(int subId) {
15207         enforceSatelliteCommunicationPermission("getSatelliteDataSupportMode");
15208         int satelliteMode = SatelliteManager.SATELLITE_DATA_SUPPORT_UNKNOWN;
15209 
15210         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
15211             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
15212         }
15213 
15214         final long identity = Binder.clearCallingIdentity();
15215         try {
15216             satelliteMode = mSatelliteController.getSatelliteDataSupportMode(subId);
15217         } finally {
15218             Binder.restoreCallingIdentity(identity);
15219         }
15220 
15221         return satelliteMode;
15222     }
15223 
15224     /**
15225      * This API can be used by only CTS to ignore plmn list from storage.
15226      *
15227      * @param enabled Whether to enable boolean config.
15228      * @return {@code true} if the value is set successfully, {@code false} otherwise.
15229      */
setSatelliteIgnorePlmnListFromStorage(boolean enabled)15230     public boolean setSatelliteIgnorePlmnListFromStorage(boolean enabled) {
15231         Log.d(LOG_TAG, "setSatelliteIgnorePlmnListFromStorage - " + enabled);
15232         TelephonyPermissions.enforceShellOnly(
15233                 Binder.getCallingUid(), "setSatelliteIgnorePlmnListFromStorage");
15234         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
15235                 SubscriptionManager.INVALID_SUBSCRIPTION_ID,
15236                 "setSatelliteIgnorePlmnListFromStorage");
15237         return mSatelliteController.setSatelliteIgnorePlmnListFromStorage(enabled);
15238     }
15239 }
15240