• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.phone;
18 
19 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20 
21 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_CDMA;
22 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_GSM;
23 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_IMS;
24 import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
25 
26 import android.Manifest.permission;
27 import android.annotation.NonNull;
28 import android.annotation.Nullable;
29 import android.app.AppOpsManager;
30 import android.app.PendingIntent;
31 import android.content.ComponentName;
32 import android.content.ContentResolver;
33 import android.content.Context;
34 import android.content.Intent;
35 import android.content.SharedPreferences;
36 import android.content.pm.ApplicationInfo;
37 import android.content.pm.ComponentInfo;
38 import android.content.pm.PackageInfo;
39 import android.content.pm.PackageManager;
40 import android.net.Uri;
41 import android.os.AsyncResult;
42 import android.os.Binder;
43 import android.os.Build;
44 import android.os.Bundle;
45 import android.os.Handler;
46 import android.os.IBinder;
47 import android.os.Looper;
48 import android.os.Message;
49 import android.os.Messenger;
50 import android.os.ParcelFileDescriptor;
51 import android.os.ParcelUuid;
52 import android.os.PersistableBundle;
53 import android.os.Process;
54 import android.os.RemoteException;
55 import android.os.ResultReceiver;
56 import android.os.ServiceSpecificException;
57 import android.os.UserHandle;
58 import android.os.UserManager;
59 import android.os.WorkSource;
60 import android.preference.PreferenceManager;
61 import android.provider.DeviceConfig;
62 import android.provider.Settings;
63 import android.provider.Telephony;
64 import android.sysprop.TelephonyProperties;
65 import android.telecom.PhoneAccount;
66 import android.telecom.PhoneAccountHandle;
67 import android.telecom.TelecomManager;
68 import android.telephony.Annotation.ApnType;
69 import android.telephony.CallForwardingInfo;
70 import android.telephony.CarrierConfigManager;
71 import android.telephony.CarrierRestrictionRules;
72 import android.telephony.CellIdentity;
73 import android.telephony.CellIdentityCdma;
74 import android.telephony.CellIdentityGsm;
75 import android.telephony.CellInfo;
76 import android.telephony.CellInfoGsm;
77 import android.telephony.CellInfoWcdma;
78 import android.telephony.ClientRequestStats;
79 import android.telephony.ICellInfoCallback;
80 import android.telephony.IccOpenLogicalChannelResponse;
81 import android.telephony.LocationAccessPolicy;
82 import android.telephony.ModemActivityInfo;
83 import android.telephony.NeighboringCellInfo;
84 import android.telephony.NetworkScanRequest;
85 import android.telephony.PhoneCapability;
86 import android.telephony.PhoneNumberRange;
87 import android.telephony.RadioAccessFamily;
88 import android.telephony.RadioAccessSpecifier;
89 import android.telephony.ServiceState;
90 import android.telephony.SignalStrength;
91 import android.telephony.SubscriptionInfo;
92 import android.telephony.SubscriptionManager;
93 import android.telephony.TelephonyFrameworkInitializer;
94 import android.telephony.TelephonyHistogram;
95 import android.telephony.TelephonyManager;
96 import android.telephony.TelephonyScanManager;
97 import android.telephony.UiccCardInfo;
98 import android.telephony.UiccSlotInfo;
99 import android.telephony.UssdResponse;
100 import android.telephony.VisualVoicemailSmsFilterSettings;
101 import android.telephony.data.ApnSetting;
102 import android.telephony.emergency.EmergencyNumber;
103 import android.telephony.ims.ImsException;
104 import android.telephony.ims.ProvisioningManager;
105 import android.telephony.ims.RegistrationManager;
106 import android.telephony.ims.aidl.IImsCapabilityCallback;
107 import android.telephony.ims.aidl.IImsConfig;
108 import android.telephony.ims.aidl.IImsConfigCallback;
109 import android.telephony.ims.aidl.IImsMmTelFeature;
110 import android.telephony.ims.aidl.IImsRcsFeature;
111 import android.telephony.ims.aidl.IImsRegistration;
112 import android.telephony.ims.aidl.IImsRegistrationCallback;
113 import android.telephony.ims.feature.ImsFeature;
114 import android.telephony.ims.feature.MmTelFeature;
115 import android.telephony.ims.feature.RcsFeature;
116 import android.telephony.ims.stub.ImsConfigImplBase;
117 import android.telephony.ims.stub.ImsRegistrationImplBase;
118 import android.text.TextUtils;
119 import android.util.ArraySet;
120 import android.util.EventLog;
121 import android.util.Log;
122 import android.util.Pair;
123 
124 import com.android.ims.ImsManager;
125 import com.android.ims.internal.IImsServiceFeatureCallback;
126 import com.android.internal.telephony.CallForwardInfo;
127 import com.android.internal.telephony.CallManager;
128 import com.android.internal.telephony.CallStateException;
129 import com.android.internal.telephony.CarrierInfoManager;
130 import com.android.internal.telephony.CarrierResolver;
131 import com.android.internal.telephony.CellNetworkScanResult;
132 import com.android.internal.telephony.CommandException;
133 import com.android.internal.telephony.CommandsInterface;
134 import com.android.internal.telephony.DefaultPhoneNotifier;
135 import com.android.internal.telephony.GsmCdmaPhone;
136 import com.android.internal.telephony.HalVersion;
137 import com.android.internal.telephony.IBooleanConsumer;
138 import com.android.internal.telephony.IIntegerConsumer;
139 import com.android.internal.telephony.INumberVerificationCallback;
140 import com.android.internal.telephony.ITelephony;
141 import com.android.internal.telephony.IccCard;
142 import com.android.internal.telephony.LocaleTracker;
143 import com.android.internal.telephony.NetworkScanRequestTracker;
144 import com.android.internal.telephony.OperatorInfo;
145 import com.android.internal.telephony.Phone;
146 import com.android.internal.telephony.PhoneConfigurationManager;
147 import com.android.internal.telephony.PhoneConstantConversions;
148 import com.android.internal.telephony.PhoneConstants;
149 import com.android.internal.telephony.PhoneFactory;
150 import com.android.internal.telephony.ProxyController;
151 import com.android.internal.telephony.RIL;
152 import com.android.internal.telephony.RILConstants;
153 import com.android.internal.telephony.ServiceStateTracker;
154 import com.android.internal.telephony.SmsController;
155 import com.android.internal.telephony.SmsPermissions;
156 import com.android.internal.telephony.SubscriptionController;
157 import com.android.internal.telephony.TelephonyIntents;
158 import com.android.internal.telephony.TelephonyPermissions;
159 import com.android.internal.telephony.dataconnection.ApnSettingUtils;
160 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
161 import com.android.internal.telephony.euicc.EuiccConnector;
162 import com.android.internal.telephony.ims.ImsResolver;
163 import com.android.internal.telephony.imsphone.ImsPhone;
164 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
165 import com.android.internal.telephony.metrics.TelephonyMetrics;
166 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
167 import com.android.internal.telephony.uicc.IccIoResult;
168 import com.android.internal.telephony.uicc.IccRecords;
169 import com.android.internal.telephony.uicc.IccUtils;
170 import com.android.internal.telephony.uicc.SIMRecords;
171 import com.android.internal.telephony.uicc.UiccCard;
172 import com.android.internal.telephony.uicc.UiccCardApplication;
173 import com.android.internal.telephony.uicc.UiccController;
174 import com.android.internal.telephony.uicc.UiccProfile;
175 import com.android.internal.telephony.uicc.UiccSlot;
176 import com.android.internal.telephony.util.LocaleUtils;
177 import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
178 import com.android.internal.util.HexDump;
179 import com.android.phone.settings.PickSmsSubscriptionActivity;
180 import com.android.phone.vvm.PhoneAccountHandleConverter;
181 import com.android.phone.vvm.RemoteVvmTaskManager;
182 import com.android.phone.vvm.VisualVoicemailSettingsUtil;
183 import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
184 import com.android.telephony.Rlog;
185 
186 import java.io.FileDescriptor;
187 import java.io.PrintWriter;
188 import java.util.ArrayList;
189 import java.util.Arrays;
190 import java.util.HashMap;
191 import java.util.HashSet;
192 import java.util.List;
193 import java.util.Locale;
194 import java.util.Map;
195 import java.util.NoSuchElementException;
196 import java.util.Set;
197 import java.util.concurrent.atomic.AtomicBoolean;
198 import java.util.function.Consumer;
199 
200 /**
201  * Implementation of the ITelephony interface.
202  */
203 public class PhoneInterfaceManager extends ITelephony.Stub {
204     private static final String LOG_TAG = "PhoneInterfaceManager";
205     private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
206     private static final boolean DBG_LOC = false;
207     private static final boolean DBG_MERGE = false;
208 
209     // Message codes used with mMainThreadHandler
210     private static final int CMD_HANDLE_PIN_MMI = 1;
211     private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
212     private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
213     private static final int CMD_OPEN_CHANNEL = 9;
214     private static final int EVENT_OPEN_CHANNEL_DONE = 10;
215     private static final int CMD_CLOSE_CHANNEL = 11;
216     private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
217     private static final int CMD_NV_READ_ITEM = 13;
218     private static final int EVENT_NV_READ_ITEM_DONE = 14;
219     private static final int CMD_NV_WRITE_ITEM = 15;
220     private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
221     private static final int CMD_NV_WRITE_CDMA_PRL = 17;
222     private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
223     private static final int CMD_RESET_MODEM_CONFIG = 19;
224     private static final int EVENT_RESET_MODEM_CONFIG_DONE = 20;
225     private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21;
226     private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22;
227     private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23;
228     private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24;
229     private static final int CMD_SEND_ENVELOPE = 25;
230     private static final int EVENT_SEND_ENVELOPE_DONE = 26;
231     private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
232     private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
233     private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
234     private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
235     private static final int CMD_EXCHANGE_SIM_IO = 31;
236     private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
237     private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
238     private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
239     private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
240     private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
241     private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
242     private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
243     private static final int CMD_PERFORM_NETWORK_SCAN = 39;
244     private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
245     private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
246     private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
247     private static final int CMD_SET_ALLOWED_CARRIERS = 43;
248     private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
249     private static final int CMD_GET_ALLOWED_CARRIERS = 45;
250     private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
251     private static final int CMD_HANDLE_USSD_REQUEST = 47;
252     private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
253     private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
254     private static final int CMD_SWITCH_SLOTS = 50;
255     private static final int EVENT_SWITCH_SLOTS_DONE = 51;
256     private static final int CMD_GET_NETWORK_SELECTION_MODE = 52;
257     private static final int EVENT_GET_NETWORK_SELECTION_MODE_DONE = 53;
258     private static final int CMD_GET_CDMA_ROAMING_MODE = 54;
259     private static final int EVENT_GET_CDMA_ROAMING_MODE_DONE = 55;
260     private static final int CMD_SET_CDMA_ROAMING_MODE = 56;
261     private static final int EVENT_SET_CDMA_ROAMING_MODE_DONE = 57;
262     private static final int CMD_SET_CDMA_SUBSCRIPTION_MODE = 58;
263     private static final int EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE = 59;
264     private static final int CMD_GET_ALL_CELL_INFO = 60;
265     private static final int EVENT_GET_ALL_CELL_INFO_DONE = 61;
266     private static final int CMD_GET_CELL_LOCATION = 62;
267     private static final int EVENT_GET_CELL_LOCATION_DONE = 63;
268     private static final int CMD_MODEM_REBOOT = 64;
269     private static final int EVENT_CMD_MODEM_REBOOT_DONE = 65;
270     private static final int CMD_REQUEST_CELL_INFO_UPDATE = 66;
271     private static final int EVENT_REQUEST_CELL_INFO_UPDATE_DONE = 67;
272     private static final int CMD_REQUEST_ENABLE_MODEM = 68;
273     private static final int EVENT_ENABLE_MODEM_DONE = 69;
274     private static final int CMD_GET_MODEM_STATUS = 70;
275     private static final int EVENT_GET_MODEM_STATUS_DONE = 71;
276     private static final int CMD_SET_FORBIDDEN_PLMNS = 72;
277     private static final int EVENT_SET_FORBIDDEN_PLMNS_DONE = 73;
278     private static final int CMD_ERASE_MODEM_CONFIG = 74;
279     private static final int EVENT_ERASE_MODEM_CONFIG_DONE = 75;
280     private static final int CMD_CHANGE_ICC_LOCK_PASSWORD = 76;
281     private static final int EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE = 77;
282     private static final int CMD_SET_ICC_LOCK_ENABLED = 78;
283     private static final int EVENT_SET_ICC_LOCK_ENABLED_DONE = 79;
284     private static final int CMD_SET_SYSTEM_SELECTION_CHANNELS = 80;
285     private static final int EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE = 81;
286     private static final int MSG_NOTIFY_USER_ACTIVITY = 82;
287     private static final int CMD_GET_CALL_FORWARDING = 83;
288     private static final int EVENT_GET_CALL_FORWARDING_DONE = 84;
289     private static final int CMD_SET_CALL_FORWARDING = 85;
290     private static final int EVENT_SET_CALL_FORWARDING_DONE = 86;
291     private static final int CMD_GET_CALL_WAITING = 87;
292     private static final int EVENT_GET_CALL_WAITING_DONE = 88;
293     private static final int CMD_SET_CALL_WAITING = 89;
294     private static final int EVENT_SET_CALL_WAITING_DONE = 90;
295 
296     // Parameters of select command.
297     private static final int SELECT_COMMAND = 0xA4;
298     private static final int SELECT_P1 = 0x04;
299     private static final int SELECT_P2 = 0;
300     private static final int SELECT_P3 = 0x10;
301 
302     /** The singleton instance. */
303     private static PhoneInterfaceManager sInstance;
304 
305     private PhoneGlobals mApp;
306     private CallManager mCM;
307     private ImsResolver mImsResolver;
308     private UserManager mUserManager;
309     private AppOpsManager mAppOps;
310     private MainThreadHandler mMainThreadHandler;
311     private SubscriptionController mSubscriptionController;
312     private SharedPreferences mTelephonySharedPreferences;
313     private PhoneConfigurationManager mPhoneConfigurationManager;
314 
315     /** User Activity */
316     private AtomicBoolean mNotifyUserActivity;
317     private static final int USER_ACTIVITY_NOTIFICATION_DELAY = 200;
318 
319     private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
320     private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
321     private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
322     private static final String PREF_PROVISION_IMS_MMTEL_PREFIX = "provision_ims_mmtel_";
323 
324     // String to store multi SIM allowed
325     private static final String PREF_MULTI_SIM_RESTRICTED = "multisim_restricted";
326 
327     // The AID of ISD-R.
328     private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
329 
330     private NetworkScanRequestTracker mNetworkScanRequestTracker;
331 
332     private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
333     private static final int MANUFACTURER_CODE_LENGTH = 8;
334 
335     /**
336      * Experiment flag to enable erase modem config on reset network, default value is false
337      */
338     public static final String RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED =
339             "reset_network_erase_modem_config_enabled";
340 
341     /**
342      * A request object to use for transmitting data to an ICC.
343      */
344     private static final class IccAPDUArgument {
345         public int channel, cla, command, p1, p2, p3;
346         public String data;
347 
IccAPDUArgument(int channel, int cla, int command, int p1, int p2, int p3, String data)348         public IccAPDUArgument(int channel, int cla, int command,
349                 int p1, int p2, int p3, String data) {
350             this.channel = channel;
351             this.cla = cla;
352             this.command = command;
353             this.p1 = p1;
354             this.p2 = p2;
355             this.p3 = p3;
356             this.data = data;
357         }
358     }
359 
360     /**
361      * A request object to use for transmitting data to an ICC.
362      */
363     private static final class ManualNetworkSelectionArgument {
364         public OperatorInfo operatorInfo;
365         public boolean persistSelection;
366 
ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection)367         public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
368             this.operatorInfo = operatorInfo;
369             this.persistSelection = persistSelection;
370         }
371     }
372 
373     /**
374      * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
375      * request after sending. The main thread will notify the request when it is complete.
376      */
377     private static final class MainThreadRequest {
378         /** The argument to use for the request */
379         public Object argument;
380         /** The result of the request that is run on the main thread */
381         public Object result;
382         // The subscriber id that this request applies to. Defaults to
383         // SubscriptionManager.INVALID_SUBSCRIPTION_ID
384         public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
385 
386         // In cases where subId is unavailable, the caller needs to specify the phone.
387         public Phone phone;
388 
389         public WorkSource workSource;
390 
MainThreadRequest(Object argument)391         public MainThreadRequest(Object argument) {
392             this.argument = argument;
393         }
394 
MainThreadRequest(Object argument, Phone phone, WorkSource workSource)395         MainThreadRequest(Object argument, Phone phone, WorkSource workSource) {
396             this.argument = argument;
397             if (phone != null) {
398                 this.phone = phone;
399             }
400             this.workSource = workSource;
401         }
402 
MainThreadRequest(Object argument, Integer subId, WorkSource workSource)403         MainThreadRequest(Object argument, Integer subId, WorkSource workSource) {
404             this.argument = argument;
405             if (subId != null) {
406                 this.subId = subId;
407             }
408             this.workSource = workSource;
409         }
410     }
411 
412     private static final class IncomingThirdPartyCallArgs {
413         public final ComponentName component;
414         public final String callId;
415         public final String callerDisplayName;
416 
IncomingThirdPartyCallArgs(ComponentName component, String callId, String callerDisplayName)417         public IncomingThirdPartyCallArgs(ComponentName component, String callId,
418                 String callerDisplayName) {
419             this.component = component;
420             this.callId = callId;
421             this.callerDisplayName = callerDisplayName;
422         }
423     }
424 
425     /**
426      * A handler that processes messages on the main thread in the phone process. Since many
427      * of the Phone calls are not thread safe this is needed to shuttle the requests from the
428      * inbound binder threads to the main thread in the phone process.  The Binder thread
429      * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
430      * on, which will be notified when the operation completes and will contain the result of the
431      * request.
432      *
433      * <p>If a MainThreadRequest object is provided in the msg.obj field,
434      * note that request.result must be set to something non-null for the calling thread to
435      * unblock.
436      */
437     private final class MainThreadHandler extends Handler {
438         @Override
handleMessage(Message msg)439         public void handleMessage(Message msg) {
440             MainThreadRequest request;
441             Message onCompleted;
442             AsyncResult ar;
443             UiccCard uiccCard;
444             IccAPDUArgument iccArgument;
445             final Phone defaultPhone = getDefaultPhone();
446 
447             switch (msg.what) {
448                 case CMD_HANDLE_USSD_REQUEST: {
449                     request = (MainThreadRequest) msg.obj;
450                     final Phone phone = getPhoneFromRequest(request);
451                     Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
452                     String ussdRequest =  ussdObject.first;
453                     ResultReceiver wrappedCallback = ussdObject.second;
454 
455                     if (!isUssdApiAllowed(request.subId)) {
456                         // Carrier does not support use of this API, return failure.
457                         Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
458                         UssdResponse response = new UssdResponse(ussdRequest, null);
459                         Bundle returnData = new Bundle();
460                         returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
461                         wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
462 
463                         request.result = true;
464                         notifyRequester(request);
465                         return;
466                     }
467 
468                     try {
469                         request.result = phone != null
470                                 ? phone.handleUssdRequest(ussdRequest, wrappedCallback) : false;
471                     } catch (CallStateException cse) {
472                         request.result = false;
473                     }
474                     // Wake up the requesting thread
475                     notifyRequester(request);
476                     break;
477                 }
478 
479                 case CMD_HANDLE_PIN_MMI: {
480                     request = (MainThreadRequest) msg.obj;
481                     final Phone phone = getPhoneFromRequest(request);
482                     request.result = phone != null ?
483                             getPhoneFromRequest(request).handlePinMmi((String) request.argument)
484                             : false;
485                     // Wake up the requesting thread
486                     notifyRequester(request);
487                     break;
488                 }
489 
490                 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
491                     request = (MainThreadRequest) msg.obj;
492                     iccArgument = (IccAPDUArgument) request.argument;
493                     uiccCard = getUiccCardFromRequest(request);
494                     if (uiccCard == null) {
495                         loge("iccTransmitApduLogicalChannel: No UICC");
496                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
497                         notifyRequester(request);
498                     } else {
499                         onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
500                             request);
501                         uiccCard.iccTransmitApduLogicalChannel(
502                             iccArgument.channel, iccArgument.cla, iccArgument.command,
503                             iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
504                             onCompleted);
505                     }
506                     break;
507 
508                 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
509                     ar = (AsyncResult) msg.obj;
510                     request = (MainThreadRequest) ar.userObj;
511                     if (ar.exception == null && ar.result != null) {
512                         request.result = ar.result;
513                     } else {
514                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
515                         if (ar.result == null) {
516                             loge("iccTransmitApduLogicalChannel: Empty response");
517                         } else if (ar.exception instanceof CommandException) {
518                             loge("iccTransmitApduLogicalChannel: CommandException: " +
519                                     ar.exception);
520                         } else {
521                             loge("iccTransmitApduLogicalChannel: Unknown exception");
522                         }
523                     }
524                     notifyRequester(request);
525                     break;
526 
527                 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
528                     request = (MainThreadRequest) msg.obj;
529                     iccArgument = (IccAPDUArgument) request.argument;
530                     uiccCard = getUiccCardFromRequest(request);
531                     if (uiccCard == null) {
532                         loge("iccTransmitApduBasicChannel: No UICC");
533                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
534                         notifyRequester(request);
535                     } else {
536                         onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
537                             request);
538                         uiccCard.iccTransmitApduBasicChannel(
539                             iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
540                             iccArgument.p3, iccArgument.data, onCompleted);
541                     }
542                     break;
543 
544                 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
545                     ar = (AsyncResult) msg.obj;
546                     request = (MainThreadRequest) ar.userObj;
547                     if (ar.exception == null && ar.result != null) {
548                         request.result = ar.result;
549                     } else {
550                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
551                         if (ar.result == null) {
552                             loge("iccTransmitApduBasicChannel: Empty response");
553                         } else if (ar.exception instanceof CommandException) {
554                             loge("iccTransmitApduBasicChannel: CommandException: " +
555                                     ar.exception);
556                         } else {
557                             loge("iccTransmitApduBasicChannel: Unknown exception");
558                         }
559                     }
560                     notifyRequester(request);
561                     break;
562 
563                 case CMD_EXCHANGE_SIM_IO:
564                     request = (MainThreadRequest) msg.obj;
565                     iccArgument = (IccAPDUArgument) request.argument;
566                     uiccCard = getUiccCardFromRequest(request);
567                     if (uiccCard == null) {
568                         loge("iccExchangeSimIO: No UICC");
569                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
570                         notifyRequester(request);
571                     } else {
572                         onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
573                                 request);
574                         uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
575                                 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
576                                 iccArgument.data, onCompleted);
577                     }
578                     break;
579 
580                 case EVENT_EXCHANGE_SIM_IO_DONE:
581                     ar = (AsyncResult) msg.obj;
582                     request = (MainThreadRequest) ar.userObj;
583                     if (ar.exception == null && ar.result != null) {
584                         request.result = ar.result;
585                     } else {
586                         request.result = new IccIoResult(0x6f, 0, (byte[])null);
587                     }
588                     notifyRequester(request);
589                     break;
590 
591                 case CMD_SEND_ENVELOPE:
592                     request = (MainThreadRequest) msg.obj;
593                     uiccCard = getUiccCardFromRequest(request);
594                     if (uiccCard == null) {
595                         loge("sendEnvelopeWithStatus: No UICC");
596                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
597                         notifyRequester(request);
598                     } else {
599                         onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
600                         uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
601                     }
602                     break;
603 
604                 case EVENT_SEND_ENVELOPE_DONE:
605                     ar = (AsyncResult) msg.obj;
606                     request = (MainThreadRequest) ar.userObj;
607                     if (ar.exception == null && ar.result != null) {
608                         request.result = ar.result;
609                     } else {
610                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
611                         if (ar.result == null) {
612                             loge("sendEnvelopeWithStatus: Empty response");
613                         } else if (ar.exception instanceof CommandException) {
614                             loge("sendEnvelopeWithStatus: CommandException: " +
615                                     ar.exception);
616                         } else {
617                             loge("sendEnvelopeWithStatus: exception:" + ar.exception);
618                         }
619                     }
620                     notifyRequester(request);
621                     break;
622 
623                 case CMD_OPEN_CHANNEL:
624                     request = (MainThreadRequest) msg.obj;
625                     uiccCard = getUiccCardFromRequest(request);
626                     Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
627                     if (uiccCard == null) {
628                         loge("iccOpenLogicalChannel: No UICC");
629                         request.result = new IccOpenLogicalChannelResponse(-1,
630                             IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
631                         notifyRequester(request);
632                     } else {
633                         onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
634                         uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
635                                 openChannelArgs.second, onCompleted);
636                     }
637                     break;
638 
639                 case EVENT_OPEN_CHANNEL_DONE:
640                     ar = (AsyncResult) msg.obj;
641                     request = (MainThreadRequest) ar.userObj;
642                     IccOpenLogicalChannelResponse openChannelResp;
643                     if (ar.exception == null && ar.result != null) {
644                         int[] result = (int[]) ar.result;
645                         int channelId = result[0];
646                         byte[] selectResponse = null;
647                         if (result.length > 1) {
648                             selectResponse = new byte[result.length - 1];
649                             for (int i = 1; i < result.length; ++i) {
650                                 selectResponse[i - 1] = (byte) result[i];
651                             }
652                         }
653                         openChannelResp = new IccOpenLogicalChannelResponse(channelId,
654                             IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
655                     } else {
656                         if (ar.result == null) {
657                             loge("iccOpenLogicalChannel: Empty response");
658                         }
659                         if (ar.exception != null) {
660                             loge("iccOpenLogicalChannel: Exception: " + ar.exception);
661                         }
662 
663                         int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
664                         if (ar.exception instanceof CommandException) {
665                             CommandException.Error error =
666                                 ((CommandException) (ar.exception)).getCommandError();
667                             if (error == CommandException.Error.MISSING_RESOURCE) {
668                                 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
669                             } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
670                                 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
671                             }
672                         }
673                         openChannelResp = new IccOpenLogicalChannelResponse(
674                             IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
675                     }
676                     request.result = openChannelResp;
677                     notifyRequester(request);
678                     break;
679 
680                 case CMD_CLOSE_CHANNEL:
681                     request = (MainThreadRequest) msg.obj;
682                     uiccCard = getUiccCardFromRequest(request);
683                     if (uiccCard == null) {
684                         loge("iccCloseLogicalChannel: No UICC");
685                         request.result = false;
686                         notifyRequester(request);
687                     } else {
688                         onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
689                         uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
690                     }
691                     break;
692 
693                 case EVENT_CLOSE_CHANNEL_DONE:
694                     handleNullReturnEvent(msg, "iccCloseLogicalChannel");
695                     break;
696 
697                 case CMD_NV_READ_ITEM:
698                     request = (MainThreadRequest) msg.obj;
699                     onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
700                     defaultPhone.nvReadItem((Integer) request.argument, onCompleted,
701                             request.workSource);
702                     break;
703 
704                 case EVENT_NV_READ_ITEM_DONE:
705                     ar = (AsyncResult) msg.obj;
706                     request = (MainThreadRequest) ar.userObj;
707                     if (ar.exception == null && ar.result != null) {
708                         request.result = ar.result;     // String
709                     } else {
710                         request.result = "";
711                         if (ar.result == null) {
712                             loge("nvReadItem: Empty response");
713                         } else if (ar.exception instanceof CommandException) {
714                             loge("nvReadItem: CommandException: " +
715                                     ar.exception);
716                         } else {
717                             loge("nvReadItem: Unknown exception");
718                         }
719                     }
720                     notifyRequester(request);
721                     break;
722 
723                 case CMD_NV_WRITE_ITEM:
724                     request = (MainThreadRequest) msg.obj;
725                     onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
726                     Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
727                     defaultPhone.nvWriteItem(idValue.first, idValue.second, onCompleted,
728                             request.workSource);
729                     break;
730 
731                 case EVENT_NV_WRITE_ITEM_DONE:
732                     handleNullReturnEvent(msg, "nvWriteItem");
733                     break;
734 
735                 case CMD_NV_WRITE_CDMA_PRL:
736                     request = (MainThreadRequest) msg.obj;
737                     onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
738                     defaultPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
739                     break;
740 
741                 case EVENT_NV_WRITE_CDMA_PRL_DONE:
742                     handleNullReturnEvent(msg, "nvWriteCdmaPrl");
743                     break;
744 
745                 case CMD_RESET_MODEM_CONFIG:
746                     request = (MainThreadRequest) msg.obj;
747                     onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
748                     defaultPhone.resetModemConfig(onCompleted);
749                     break;
750 
751                 case EVENT_RESET_MODEM_CONFIG_DONE:
752                     handleNullReturnEvent(msg, "resetModemConfig");
753                     break;
754 
755                 case CMD_GET_PREFERRED_NETWORK_TYPE:
756                     request = (MainThreadRequest) msg.obj;
757                     onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
758                     getPhoneFromRequest(request).getPreferredNetworkType(onCompleted);
759                     break;
760 
761                 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
762                     ar = (AsyncResult) msg.obj;
763                     request = (MainThreadRequest) ar.userObj;
764                     if (ar.exception == null && ar.result != null) {
765                         request.result = ar.result;     // Integer
766                     } else {
767                         request.result = null;
768                         if (ar.result == null) {
769                             loge("getPreferredNetworkType: Empty response");
770                         } else if (ar.exception instanceof CommandException) {
771                             loge("getPreferredNetworkType: CommandException: " +
772                                     ar.exception);
773                         } else {
774                             loge("getPreferredNetworkType: Unknown exception");
775                         }
776                     }
777                     notifyRequester(request);
778                     break;
779 
780                 case CMD_SET_PREFERRED_NETWORK_TYPE:
781                     request = (MainThreadRequest) msg.obj;
782                     onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
783                     int networkType = (Integer) request.argument;
784                     getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted);
785                     break;
786 
787                 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
788                     handleNullReturnEvent(msg, "setPreferredNetworkType");
789                     break;
790 
791                 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
792                     request = (MainThreadRequest)msg.obj;
793                     onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
794                     defaultPhone.invokeOemRilRequestRaw((byte[]) request.argument, onCompleted);
795                     break;
796 
797                 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
798                     ar = (AsyncResult)msg.obj;
799                     request = (MainThreadRequest)ar.userObj;
800                     request.result = ar;
801                     notifyRequester(request);
802                     break;
803 
804                 case CMD_SET_VOICEMAIL_NUMBER:
805                     request = (MainThreadRequest) msg.obj;
806                     onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
807                     Pair<String, String> tagNum = (Pair<String, String>) request.argument;
808                     getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
809                             onCompleted);
810                     break;
811 
812                 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
813                     handleNullReturnEvent(msg, "setVoicemailNumber");
814                     break;
815 
816                 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
817                     request = (MainThreadRequest) msg.obj;
818                     onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
819                             request);
820                     getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
821                     break;
822 
823                 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
824                     handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
825                     break;
826 
827                 case CMD_PERFORM_NETWORK_SCAN:
828                     request = (MainThreadRequest) msg.obj;
829                     onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
830                     getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
831                     break;
832 
833                 case CMD_GET_CALL_FORWARDING:
834                     request = (MainThreadRequest) msg.obj;
835                     onCompleted = obtainMessage(EVENT_GET_CALL_FORWARDING_DONE, request);
836                     int callForwardingReason = (Integer) request.argument;
837                     getPhoneFromRequest(request).getCallForwardingOption(
838                             callForwardingReason, onCompleted);
839                     break;
840 
841                 case EVENT_GET_CALL_FORWARDING_DONE:
842                     ar = (AsyncResult) msg.obj;
843                     request = (MainThreadRequest) ar.userObj;
844                     CallForwardingInfo callForwardingInfo = null;
845                     if (ar.exception == null && ar.result != null) {
846                         CallForwardInfo[] callForwardInfos = (CallForwardInfo[]) ar.result;
847                         for (CallForwardInfo callForwardInfo : callForwardInfos) {
848                             // Service Class is a bit mask per 3gpp 27.007. Search for
849                             // any service for voice call.
850                             if ((callForwardInfo.serviceClass
851                                     & CommandsInterface.SERVICE_CLASS_VOICE) > 0) {
852                                 callForwardingInfo = new CallForwardingInfo(
853                                         callForwardInfo.serviceClass, callForwardInfo.reason,
854                                                 callForwardInfo.number,
855                                                         callForwardInfo.timeSeconds);
856                                 break;
857                             }
858                         }
859                         // Didn't find a call forward info for voice call.
860                         if (callForwardingInfo == null) {
861                             callForwardingInfo = new CallForwardingInfo(
862                                     CallForwardingInfo.STATUS_UNKNOWN_ERROR,
863                                             0 /* reason */, null /* number */, 0 /* timeout */);
864                         }
865                     } else {
866                         if (ar.result == null) {
867                             loge("EVENT_GET_CALL_FORWARDING_DONE: Empty response");
868                         }
869                         if (ar.exception != null) {
870                             loge("EVENT_GET_CALL_FORWARDING_DONE: Exception: " + ar.exception);
871                         }
872                         int errorCode = CallForwardingInfo.STATUS_UNKNOWN_ERROR;
873                         if (ar.exception instanceof CommandException) {
874                             CommandException.Error error =
875                                     ((CommandException) (ar.exception)).getCommandError();
876                             if (error == CommandException.Error.FDN_CHECK_FAILURE) {
877                                 errorCode = CallForwardingInfo.STATUS_FDN_CHECK_FAILURE;
878                             } else if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
879                                 errorCode = CallForwardingInfo.STATUS_NOT_SUPPORTED;
880                             }
881                         }
882                         callForwardingInfo = new CallForwardingInfo(
883                                 errorCode, 0 /* reason */, null /* number */, 0 /* timeout */);
884                     }
885                     request.result = callForwardingInfo;
886                     notifyRequester(request);
887                     break;
888 
889                 case CMD_SET_CALL_FORWARDING:
890                     request = (MainThreadRequest) msg.obj;
891                     onCompleted = obtainMessage(EVENT_SET_CALL_FORWARDING_DONE, request);
892                     CallForwardingInfo callForwardingInfoToSet =
893                             (CallForwardingInfo) request.argument;
894                     getPhoneFromRequest(request).setCallForwardingOption(
895                             callForwardingInfoToSet.getStatus(),
896                             callForwardingInfoToSet.getReason(),
897                             callForwardingInfoToSet.getNumber(),
898                             callForwardingInfoToSet.getTimeoutSeconds(), onCompleted);
899                     break;
900 
901                 case EVENT_SET_CALL_FORWARDING_DONE:
902                     ar = (AsyncResult) msg.obj;
903                     request = (MainThreadRequest) ar.userObj;
904                     if (ar.exception == null) {
905                         request.result = true;
906                     } else {
907                         request.result = false;
908                         loge("setCallForwarding exception: " + ar.exception);
909                     }
910                     notifyRequester(request);
911                     break;
912 
913                 case CMD_GET_CALL_WAITING:
914                     request = (MainThreadRequest) msg.obj;
915                     onCompleted = obtainMessage(EVENT_GET_CALL_WAITING_DONE, request);
916                     getPhoneFromRequest(request).getCallWaiting(onCompleted);
917                     break;
918 
919                 case EVENT_GET_CALL_WAITING_DONE:
920                     ar = (AsyncResult) msg.obj;
921                     request = (MainThreadRequest) ar.userObj;
922                     int callForwardingStatus = TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR;
923                     if (ar.exception == null && ar.result != null) {
924                         int[] callForwardResults = (int[]) ar.result;
925                         // Service Class is a bit mask per 3gpp 27.007.
926                         // Search for any service for voice call.
927                         if (callForwardResults.length > 1
928                                 && ((callForwardResults[1]
929                                         & CommandsInterface.SERVICE_CLASS_VOICE) > 0)) {
930                             callForwardingStatus = callForwardResults[0] == 0
931                                     ? TelephonyManager.CALL_WAITING_STATUS_INACTIVE
932                                             : TelephonyManager.CALL_WAITING_STATUS_ACTIVE;
933                         } else {
934                             callForwardingStatus = TelephonyManager.CALL_WAITING_STATUS_INACTIVE;
935                         }
936                     } else {
937                         if (ar.result == null) {
938                             loge("EVENT_GET_CALL_WAITING_DONE: Empty response");
939                         }
940                         if (ar.exception != null) {
941                             loge("EVENT_GET_CALL_WAITING_DONE: Exception: " + ar.exception);
942                         }
943                         if (ar.exception instanceof CommandException) {
944                             CommandException.Error error =
945                                     ((CommandException) (ar.exception)).getCommandError();
946                             if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
947                                 callForwardingStatus =
948                                         TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED;
949                             }
950                         }
951                     }
952                     request.result = callForwardingStatus;
953                     notifyRequester(request);
954                     break;
955 
956                 case CMD_SET_CALL_WAITING:
957                     request = (MainThreadRequest) msg.obj;
958                     onCompleted = obtainMessage(EVENT_SET_CALL_WAITING_DONE, request);
959                     boolean isEnable = (Boolean) request.argument;
960                     getPhoneFromRequest(request).setCallWaiting(isEnable, onCompleted);
961                     break;
962 
963                 case EVENT_SET_CALL_WAITING_DONE:
964                     ar = (AsyncResult) msg.obj;
965                     request = (MainThreadRequest) ar.userObj;
966                     if (ar.exception == null) {
967                         request.result = true;
968                     } else {
969                         request.result = false;
970                         loge("setCallWaiting exception: " + ar.exception);
971                     }
972                     notifyRequester(request);
973                     break;
974 
975                 case EVENT_PERFORM_NETWORK_SCAN_DONE:
976                     ar = (AsyncResult) msg.obj;
977                     request = (MainThreadRequest) ar.userObj;
978                     CellNetworkScanResult cellScanResult;
979                     if (ar.exception == null && ar.result != null) {
980                         cellScanResult = new CellNetworkScanResult(
981                                 CellNetworkScanResult.STATUS_SUCCESS,
982                                 (List<OperatorInfo>) ar.result);
983                     } else {
984                         if (ar.result == null) {
985                             loge("getCellNetworkScanResults: Empty response");
986                         }
987                         if (ar.exception != null) {
988                             loge("getCellNetworkScanResults: Exception: " + ar.exception);
989                         }
990                         int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
991                         if (ar.exception instanceof CommandException) {
992                             CommandException.Error error =
993                                 ((CommandException) (ar.exception)).getCommandError();
994                             if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
995                                 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
996                             } else if (error == CommandException.Error.GENERIC_FAILURE) {
997                                 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
998                             }
999                         }
1000                         cellScanResult = new CellNetworkScanResult(errorCode, null);
1001                     }
1002                     request.result = cellScanResult;
1003                     notifyRequester(request);
1004                     break;
1005 
1006                 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
1007                     request = (MainThreadRequest) msg.obj;
1008                     ManualNetworkSelectionArgument selArg =
1009                             (ManualNetworkSelectionArgument) request.argument;
1010                     onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
1011                             request);
1012                     getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
1013                             selArg.persistSelection, onCompleted);
1014                     break;
1015 
1016                 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
1017                     ar = (AsyncResult) msg.obj;
1018                     request = (MainThreadRequest) ar.userObj;
1019                     if (ar.exception == null) {
1020                         request.result = true;
1021                     } else {
1022                         request.result = false;
1023                         loge("setNetworkSelectionModeManual " + ar.exception);
1024                     }
1025                     notifyRequester(request);
1026                     mApp.onNetworkSelectionChanged(request.subId);
1027                     break;
1028 
1029                 case CMD_GET_MODEM_ACTIVITY_INFO:
1030                     request = (MainThreadRequest) msg.obj;
1031                     onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
1032                     if (defaultPhone != null) {
1033                         defaultPhone.getModemActivityInfo(onCompleted, request.workSource);
1034                     } else {
1035                         ResultReceiver result = (ResultReceiver) request.argument;
1036                         Bundle bundle = new Bundle();
1037                         bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY,
1038                                 new ModemActivityInfo(0, 0, 0, new int[0], 0));
1039                         result.send(0, bundle);
1040                     }
1041                     break;
1042 
1043                 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE:
1044                     ar = (AsyncResult) msg.obj;
1045                     request = (MainThreadRequest) ar.userObj;
1046                     ResultReceiver result = (ResultReceiver) request.argument;
1047 
1048                     ModemActivityInfo ret = new ModemActivityInfo(0, 0, 0, new int[0], 0);
1049                     if (ar.exception == null && ar.result != null) {
1050                         // Update the last modem activity info and the result of the request.
1051                         ModemActivityInfo info = (ModemActivityInfo) ar.result;
1052                         if (isModemActivityInfoValid(info)) {
1053                             int[] mergedTxTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
1054                             int[] txTimeMs = info.getTransmitTimeMillis();
1055                             int[] lastModemTxTimeMs = mLastModemActivityInfo
1056                                     .getTransmitTimeMillis();
1057                             for (int i = 0; i < mergedTxTimeMs.length; i++) {
1058                                 mergedTxTimeMs[i] = txTimeMs[i] + lastModemTxTimeMs[i];
1059                             }
1060                             mLastModemActivityInfo.setTimestamp(info.getTimestamp());
1061                             mLastModemActivityInfo.setSleepTimeMillis(info.getSleepTimeMillis()
1062                                     + mLastModemActivityInfo.getSleepTimeMillis());
1063                             mLastModemActivityInfo.setIdleTimeMillis(info.getIdleTimeMillis()
1064                                     + mLastModemActivityInfo.getIdleTimeMillis());
1065                             mLastModemActivityInfo.setTransmitTimeMillis(mergedTxTimeMs);
1066                             mLastModemActivityInfo.setReceiveTimeMillis(
1067                                     info.getReceiveTimeMillis()
1068                                             + mLastModemActivityInfo.getReceiveTimeMillis());
1069                         }
1070                         ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestamp(),
1071                                 mLastModemActivityInfo.getSleepTimeMillis(),
1072                                 mLastModemActivityInfo.getIdleTimeMillis(),
1073                                 mLastModemActivityInfo.getTransmitTimeMillis(),
1074                                 mLastModemActivityInfo.getReceiveTimeMillis());
1075                     } else {
1076                         if (ar.result == null) {
1077                             loge("queryModemActivityInfo: Empty response");
1078                         } else if (ar.exception instanceof CommandException) {
1079                             loge("queryModemActivityInfo: CommandException: " +
1080                                     ar.exception);
1081                         } else {
1082                             loge("queryModemActivityInfo: Unknown exception");
1083                         }
1084                     }
1085                     Bundle bundle = new Bundle();
1086                     bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
1087                     result.send(0, bundle);
1088                     notifyRequester(request);
1089                     break;
1090 
1091                 case CMD_SET_ALLOWED_CARRIERS:
1092                     request = (MainThreadRequest) msg.obj;
1093                     CarrierRestrictionRules argument =
1094                             (CarrierRestrictionRules) request.argument;
1095                     onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
1096                     defaultPhone.setAllowedCarriers(argument, onCompleted, request.workSource);
1097                     break;
1098 
1099                 case EVENT_SET_ALLOWED_CARRIERS_DONE:
1100                     ar = (AsyncResult) msg.obj;
1101                     request = (MainThreadRequest) ar.userObj;
1102                     if (ar.exception == null && ar.result != null) {
1103                         request.result = ar.result;
1104                     } else {
1105                         request.result = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
1106                         if (ar.exception instanceof CommandException) {
1107                             loge("setAllowedCarriers: CommandException: " + ar.exception);
1108                             CommandException.Error error =
1109                                     ((CommandException) (ar.exception)).getCommandError();
1110                             if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
1111                                 request.result =
1112                                         TelephonyManager.SET_CARRIER_RESTRICTION_NOT_SUPPORTED;
1113                             }
1114                         } else {
1115                             loge("setAllowedCarriers: Unknown exception");
1116                         }
1117                     }
1118                     notifyRequester(request);
1119                     break;
1120 
1121                 case CMD_GET_ALLOWED_CARRIERS:
1122                     request = (MainThreadRequest) msg.obj;
1123                     onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
1124                     defaultPhone.getAllowedCarriers(onCompleted, request.workSource);
1125                     break;
1126 
1127                 case EVENT_GET_ALLOWED_CARRIERS_DONE:
1128                     ar = (AsyncResult) msg.obj;
1129                     request = (MainThreadRequest) ar.userObj;
1130                     if (ar.exception == null && ar.result != null) {
1131                         request.result = ar.result;
1132                     } else {
1133                         request.result = new IllegalStateException(
1134                             "Failed to get carrier restrictions");
1135                         if (ar.result == null) {
1136                             loge("getAllowedCarriers: Empty response");
1137                         } else if (ar.exception instanceof CommandException) {
1138                             loge("getAllowedCarriers: CommandException: " +
1139                                     ar.exception);
1140                         } else {
1141                             loge("getAllowedCarriers: Unknown exception");
1142                         }
1143                     }
1144                     notifyRequester(request);
1145                     break;
1146 
1147                 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
1148                     ar = (AsyncResult) msg.obj;
1149                     request = (MainThreadRequest) ar.userObj;
1150                     if (ar.exception == null && ar.result != null) {
1151                         request.result = ar.result;
1152                     } else {
1153                         request.result = new IllegalArgumentException(
1154                                 "Failed to retrieve Forbidden Plmns");
1155                         if (ar.result == null) {
1156                             loge("getForbiddenPlmns: Empty response");
1157                         } else {
1158                             loge("getForbiddenPlmns: Unknown exception");
1159                         }
1160                     }
1161                     notifyRequester(request);
1162                     break;
1163 
1164                 case CMD_GET_FORBIDDEN_PLMNS:
1165                     request = (MainThreadRequest) msg.obj;
1166                     uiccCard = getUiccCardFromRequest(request);
1167                     if (uiccCard == null) {
1168                         loge("getForbiddenPlmns() UiccCard is null");
1169                         request.result = new IllegalArgumentException(
1170                                 "getForbiddenPlmns() UiccCard is null");
1171                         notifyRequester(request);
1172                         break;
1173                     }
1174                     Integer appType = (Integer) request.argument;
1175                     UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
1176                     if (uiccApp == null) {
1177                         loge("getForbiddenPlmns() no app with specified type -- "
1178                                 + appType);
1179                         request.result = new IllegalArgumentException("Failed to get UICC App");
1180                         notifyRequester(request);
1181                         break;
1182                     } else {
1183                         if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
1184                                 + " specified type -- " + appType);
1185                     }
1186                     onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
1187                     ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
1188                               onCompleted);
1189                     break;
1190 
1191                 case CMD_SWITCH_SLOTS:
1192                     request = (MainThreadRequest) msg.obj;
1193                     int[] physicalSlots = (int[]) request.argument;
1194                     onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
1195                     UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
1196                     break;
1197 
1198                 case EVENT_SWITCH_SLOTS_DONE:
1199                     ar = (AsyncResult) msg.obj;
1200                     request = (MainThreadRequest) ar.userObj;
1201                     request.result = (ar.exception == null);
1202                     notifyRequester(request);
1203                     break;
1204                 case CMD_GET_NETWORK_SELECTION_MODE:
1205                     request = (MainThreadRequest) msg.obj;
1206                     onCompleted = obtainMessage(EVENT_GET_NETWORK_SELECTION_MODE_DONE, request);
1207                     getPhoneFromRequest(request).getNetworkSelectionMode(onCompleted);
1208                     break;
1209 
1210                 case EVENT_GET_NETWORK_SELECTION_MODE_DONE:
1211                     ar = (AsyncResult) msg.obj;
1212                     request = (MainThreadRequest) ar.userObj;
1213                     if (ar.exception != null) {
1214                         request.result = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
1215                     } else {
1216                         int mode = ((int[]) ar.result)[0];
1217                         if (mode == 0) {
1218                             request.result = TelephonyManager.NETWORK_SELECTION_MODE_AUTO;
1219                         } else {
1220                             request.result = TelephonyManager.NETWORK_SELECTION_MODE_MANUAL;
1221                         }
1222                     }
1223                     notifyRequester(request);
1224                     break;
1225                 case CMD_GET_CDMA_ROAMING_MODE:
1226                     request = (MainThreadRequest) msg.obj;
1227                     onCompleted = obtainMessage(EVENT_GET_CDMA_ROAMING_MODE_DONE, request);
1228                     getPhoneFromRequest(request).queryCdmaRoamingPreference(onCompleted);
1229                     break;
1230                 case EVENT_GET_CDMA_ROAMING_MODE_DONE:
1231                     ar = (AsyncResult) msg.obj;
1232                     request = (MainThreadRequest) ar.userObj;
1233                     if (ar.exception != null) {
1234                         request.result = TelephonyManager.CDMA_ROAMING_MODE_RADIO_DEFAULT;
1235                     } else {
1236                         request.result = ((int[]) ar.result)[0];
1237                     }
1238                     notifyRequester(request);
1239                     break;
1240                 case CMD_SET_CDMA_ROAMING_MODE:
1241                     request = (MainThreadRequest) msg.obj;
1242                     onCompleted = obtainMessage(EVENT_SET_CDMA_ROAMING_MODE_DONE, request);
1243                     int mode = (int) request.argument;
1244                     getPhoneFromRequest(request).setCdmaRoamingPreference(mode, onCompleted);
1245                     break;
1246                 case EVENT_SET_CDMA_ROAMING_MODE_DONE:
1247                     ar = (AsyncResult) msg.obj;
1248                     request = (MainThreadRequest) ar.userObj;
1249                     request.result = ar.exception == null;
1250                     notifyRequester(request);
1251                     break;
1252                 case CMD_SET_CDMA_SUBSCRIPTION_MODE:
1253                     request = (MainThreadRequest) msg.obj;
1254                     onCompleted = obtainMessage(EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE, request);
1255                     int subscriptionMode = (int) request.argument;
1256                     getPhoneFromRequest(request).setCdmaSubscription(subscriptionMode, onCompleted);
1257                     break;
1258                 case EVENT_SET_CDMA_SUBSCRIPTION_MODE_DONE:
1259                     ar = (AsyncResult) msg.obj;
1260                     request = (MainThreadRequest) ar.userObj;
1261                     request.result = ar.exception == null;
1262                     notifyRequester(request);
1263                     break;
1264                 case CMD_GET_ALL_CELL_INFO:
1265                     request = (MainThreadRequest) msg.obj;
1266                     onCompleted = obtainMessage(EVENT_GET_ALL_CELL_INFO_DONE, request);
1267                     request.phone.requestCellInfoUpdate(request.workSource, onCompleted);
1268                     break;
1269                 case EVENT_GET_ALL_CELL_INFO_DONE:
1270                     ar = (AsyncResult) msg.obj;
1271                     request = (MainThreadRequest) ar.userObj;
1272                     // If a timeout occurs, the response will be null
1273                     request.result = (ar.exception == null && ar.result != null)
1274                             ? ar.result : new ArrayList<CellInfo>();
1275                     synchronized (request) {
1276                         request.notifyAll();
1277                     }
1278                     break;
1279                 case CMD_REQUEST_CELL_INFO_UPDATE:
1280                     request = (MainThreadRequest) msg.obj;
1281                     request.phone.requestCellInfoUpdate(request.workSource,
1282                             obtainMessage(EVENT_REQUEST_CELL_INFO_UPDATE_DONE, request));
1283                     break;
1284                 case EVENT_REQUEST_CELL_INFO_UPDATE_DONE:
1285                     ar = (AsyncResult) msg.obj;
1286                     request = (MainThreadRequest) ar.userObj;
1287                     ICellInfoCallback cb = (ICellInfoCallback) request.argument;
1288                     try {
1289                         if (ar.exception != null) {
1290                             Log.e(LOG_TAG, "Exception retrieving CellInfo=" + ar.exception);
1291                             cb.onError(
1292                                     TelephonyManager.CellInfoCallback.ERROR_MODEM_ERROR,
1293                                     ar.exception.getClass().getName(),
1294                                     ar.exception.toString());
1295                         } else if (ar.result == null) {
1296                             Log.w(LOG_TAG, "Timeout Waiting for CellInfo!");
1297                             cb.onError(TelephonyManager.CellInfoCallback.ERROR_TIMEOUT, null, null);
1298                         } else {
1299                             // use the result as returned
1300                             cb.onCellInfo((List<CellInfo>) ar.result);
1301                         }
1302                     } catch (RemoteException re) {
1303                         Log.w(LOG_TAG, "Discarded CellInfo due to Callback RemoteException");
1304                     }
1305                     break;
1306                 case CMD_GET_CELL_LOCATION:
1307                     request = (MainThreadRequest) msg.obj;
1308                     WorkSource ws = (WorkSource) request.argument;
1309                     Phone phone = getPhoneFromRequest(request);
1310                     phone.getCellIdentity(ws, obtainMessage(EVENT_GET_CELL_LOCATION_DONE, request));
1311                     break;
1312                 case EVENT_GET_CELL_LOCATION_DONE:
1313                     ar = (AsyncResult) msg.obj;
1314                     request = (MainThreadRequest) ar.userObj;
1315                     if (ar.exception == null) {
1316                         request.result = ar.result;
1317                     } else {
1318                         phone = getPhoneFromRequest(request);
1319                         request.result = (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
1320                                 ? new CellIdentityCdma() : new CellIdentityGsm();
1321                     }
1322 
1323                     synchronized (request) {
1324                         request.notifyAll();
1325                     }
1326                     break;
1327                 case CMD_MODEM_REBOOT:
1328                     request = (MainThreadRequest) msg.obj;
1329                     onCompleted = obtainMessage(EVENT_RESET_MODEM_CONFIG_DONE, request);
1330                     defaultPhone.rebootModem(onCompleted);
1331                     break;
1332                 case EVENT_CMD_MODEM_REBOOT_DONE:
1333                     handleNullReturnEvent(msg, "rebootModem");
1334                     break;
1335                 case CMD_REQUEST_ENABLE_MODEM:
1336                     request = (MainThreadRequest) msg.obj;
1337                     boolean enable = (boolean) request.argument;
1338                     onCompleted = obtainMessage(EVENT_ENABLE_MODEM_DONE, request);
1339                     onCompleted.arg1 = enable ? 1 : 0;
1340                     PhoneConfigurationManager.getInstance()
1341                             .enablePhone(request.phone, enable, onCompleted);
1342                     break;
1343                 case EVENT_ENABLE_MODEM_DONE:
1344                     ar = (AsyncResult) msg.obj;
1345                     request = (MainThreadRequest) ar.userObj;
1346                     request.result = (ar.exception == null);
1347                     int phoneId = request.phone.getPhoneId();
1348                     //update the cache as modem status has changed
1349                     if ((boolean) request.result) {
1350                         mPhoneConfigurationManager.addToPhoneStatusCache(phoneId, msg.arg1 == 1);
1351                         updateModemStateMetrics();
1352                     } else {
1353                         Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1354                                 + ar.exception);
1355                     }
1356                     notifyRequester(request);
1357                     break;
1358                 case CMD_GET_MODEM_STATUS:
1359                     request = (MainThreadRequest) msg.obj;
1360                     onCompleted = obtainMessage(EVENT_GET_MODEM_STATUS_DONE, request);
1361                     PhoneConfigurationManager.getInstance()
1362                             .getPhoneStatusFromModem(request.phone, onCompleted);
1363                     break;
1364                 case EVENT_GET_MODEM_STATUS_DONE:
1365                     ar = (AsyncResult) msg.obj;
1366                     request = (MainThreadRequest) ar.userObj;
1367                     int id = request.phone.getPhoneId();
1368                     if (ar.exception == null && ar.result != null) {
1369                         request.result = ar.result;
1370                         //update the cache as modem status has changed
1371                         mPhoneConfigurationManager.addToPhoneStatusCache(id,
1372                                 (boolean) request.result);
1373                     } else {
1374                         // Return true if modem status cannot be retrieved. For most cases,
1375                         // modem status is on. And for older version modems, GET_MODEM_STATUS
1376                         // and disable modem are not supported. Modem is always on.
1377                         // TODO: this should be fixed in R to support a third
1378                         // status UNKNOWN b/131631629
1379                         request.result = true;
1380                         Log.e(LOG_TAG, msg.what + " failure. Not updating modem status."
1381                                 + ar.exception);
1382                     }
1383                     notifyRequester(request);
1384                     break;
1385                 case CMD_SET_SYSTEM_SELECTION_CHANNELS: {
1386                     request = (MainThreadRequest) msg.obj;
1387                     onCompleted = obtainMessage(EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE, request);
1388                     Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1389                             (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1390                     request.phone.setSystemSelectionChannels(args.first, onCompleted);
1391                     break;
1392                 }
1393                 case EVENT_SET_SYSTEM_SELECTION_CHANNELS_DONE: {
1394                     ar = (AsyncResult) msg.obj;
1395                     request = (MainThreadRequest) ar.userObj;
1396                     Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> args =
1397                             (Pair<List<RadioAccessSpecifier>, Consumer<Boolean>>) request.argument;
1398                     args.second.accept(ar.exception == null);
1399                     notifyRequester(request);
1400                     break;
1401                 }
1402                 case EVENT_SET_FORBIDDEN_PLMNS_DONE:
1403                     ar = (AsyncResult) msg.obj;
1404                     request = (MainThreadRequest) ar.userObj;
1405                     if (ar.exception == null && ar.result != null) {
1406                         request.result = ar.result;
1407                     } else {
1408                         request.result = -1;
1409                         loge("Failed to set Forbidden Plmns");
1410                         if (ar.result == null) {
1411                             loge("setForbidenPlmns: Empty response");
1412                         } else if (ar.exception != null) {
1413                             loge("setForbiddenPlmns: Exception: " + ar.exception);
1414                             request.result = -1;
1415                         } else {
1416                             loge("setForbiddenPlmns: Unknown exception");
1417                         }
1418                     }
1419                     notifyRequester(request);
1420                     break;
1421                 case CMD_SET_FORBIDDEN_PLMNS:
1422                     request = (MainThreadRequest) msg.obj;
1423                     uiccCard = getUiccCardFromRequest(request);
1424                     if (uiccCard == null) {
1425                         loge("setForbiddenPlmns: UiccCard is null");
1426                         request.result = -1;
1427                         notifyRequester(request);
1428                         break;
1429                     }
1430                     Pair<Integer, List<String>> setFplmnsArgs =
1431                             (Pair<Integer, List<String>>) request.argument;
1432                     appType = setFplmnsArgs.first;
1433                     List<String> fplmns = setFplmnsArgs.second;
1434                     uiccApp = uiccCard.getApplicationByType(appType);
1435                     if (uiccApp == null) {
1436                         loge("setForbiddenPlmns: no app with specified type -- " + appType);
1437                         request.result = -1;
1438                         loge("Failed to get UICC App");
1439                         notifyRequester(request);
1440                     } else {
1441                         onCompleted = obtainMessage(EVENT_SET_FORBIDDEN_PLMNS_DONE, request);
1442                         ((SIMRecords) uiccApp.getIccRecords())
1443                                 .setForbiddenPlmns(onCompleted, fplmns);
1444                     }
1445                     break;
1446                 case CMD_ERASE_MODEM_CONFIG:
1447                     request = (MainThreadRequest) msg.obj;
1448                     onCompleted = obtainMessage(EVENT_ERASE_MODEM_CONFIG_DONE, request);
1449                     defaultPhone.eraseModemConfig(onCompleted);
1450                     break;
1451                 case EVENT_ERASE_MODEM_CONFIG_DONE:
1452                     handleNullReturnEvent(msg, "eraseModemConfig");
1453                     break;
1454 
1455                 case CMD_CHANGE_ICC_LOCK_PASSWORD:
1456                     request = (MainThreadRequest) msg.obj;
1457                     onCompleted = obtainMessage(EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE, request);
1458                     Pair<String, String> changed = (Pair<String, String>) request.argument;
1459                     getPhoneFromRequest(request).getIccCard().changeIccLockPassword(
1460                             changed.first, changed.second, onCompleted);
1461                     break;
1462                 case EVENT_CHANGE_ICC_LOCK_PASSWORD_DONE:
1463                     ar = (AsyncResult) msg.obj;
1464                     request = (MainThreadRequest) ar.userObj;
1465                     if (ar.exception == null) {
1466                         request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
1467                     } else {
1468                         request.result = msg.arg1;
1469                     }
1470                     notifyRequester(request);
1471                     break;
1472 
1473                 case CMD_SET_ICC_LOCK_ENABLED:
1474                     request = (MainThreadRequest) msg.obj;
1475                     onCompleted = obtainMessage(EVENT_SET_ICC_LOCK_ENABLED_DONE, request);
1476                     Pair<Boolean, String> enabled = (Pair<Boolean, String>) request.argument;
1477                     getPhoneFromRequest(request).getIccCard().setIccLockEnabled(
1478                             enabled.first, enabled.second, onCompleted);
1479                     break;
1480                 case EVENT_SET_ICC_LOCK_ENABLED_DONE:
1481                     ar = (AsyncResult) msg.obj;
1482                     request = (MainThreadRequest) ar.userObj;
1483                     if (ar.exception == null) {
1484                         request.result = TelephonyManager.CHANGE_ICC_LOCK_SUCCESS;
1485                     } else {
1486                         request.result = msg.arg1;
1487                     }
1488                     notifyRequester(request);
1489                     break;
1490 
1491                 case MSG_NOTIFY_USER_ACTIVITY:
1492                     removeMessages(MSG_NOTIFY_USER_ACTIVITY);
1493                     Intent intent = new Intent(TelephonyIntents.ACTION_USER_ACTIVITY_NOTIFICATION);
1494                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
1495                     getDefaultPhone().getContext().sendBroadcastAsUser(
1496                             intent, UserHandle.ALL, permission.USER_ACTIVITY);
1497                     break;
1498                 default:
1499                     Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
1500                     break;
1501             }
1502         }
1503 
notifyRequester(MainThreadRequest request)1504         private void notifyRequester(MainThreadRequest request) {
1505             synchronized (request) {
1506                 request.notifyAll();
1507             }
1508         }
1509 
handleNullReturnEvent(Message msg, String command)1510         private void handleNullReturnEvent(Message msg, String command) {
1511             AsyncResult ar = (AsyncResult) msg.obj;
1512             MainThreadRequest request = (MainThreadRequest) ar.userObj;
1513             if (ar.exception == null) {
1514                 request.result = true;
1515             } else {
1516                 request.result = false;
1517                 if (ar.exception instanceof CommandException) {
1518                     loge(command + ": CommandException: " + ar.exception);
1519                 } else {
1520                     loge(command + ": Unknown exception");
1521                 }
1522             }
1523             notifyRequester(request);
1524         }
1525     }
1526 
1527     /**
1528      * Posts the specified command to be executed on the main thread,
1529      * waits for the request to complete, and returns the result.
1530      * @see #sendRequestAsync
1531      */
sendRequest(int command, Object argument)1532     private Object sendRequest(int command, Object argument) {
1533         return sendRequest(
1534                 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, null, null);
1535     }
1536 
1537     /**
1538      * Posts the specified command to be executed on the main thread,
1539      * waits for the request to complete, and returns the result.
1540      * @see #sendRequestAsync
1541      */
sendRequest(int command, Object argument, WorkSource workSource)1542     private Object sendRequest(int command, Object argument, WorkSource workSource) {
1543         return sendRequest(command, argument,  SubscriptionManager.INVALID_SUBSCRIPTION_ID,
1544                 null, workSource);
1545     }
1546 
1547     /**
1548      * Posts the specified command to be executed on the main thread,
1549      * waits for the request to complete, and returns the result.
1550      * @see #sendRequestAsync
1551      */
sendRequest(int command, Object argument, Integer subId)1552     private Object sendRequest(int command, Object argument, Integer subId) {
1553         return sendRequest(command, argument, subId, null, null);
1554     }
1555 
1556     /**
1557      * Posts the specified command to be executed on the main thread,
1558      * waits for the request to complete, and returns the result.
1559      * @see #sendRequestAsync
1560      */
sendRequest(int command, Object argument, int subId, WorkSource workSource)1561     private Object sendRequest(int command, Object argument, int subId, WorkSource workSource) {
1562         return sendRequest(command, argument, subId, null, workSource);
1563     }
1564 
1565     /**
1566      * Posts the specified command to be executed on the main thread,
1567      * waits for the request to complete, and returns the result.
1568      * @see #sendRequestAsync
1569      */
sendRequest(int command, Object argument, Phone phone, WorkSource workSource)1570     private Object sendRequest(int command, Object argument, Phone phone, WorkSource workSource) {
1571         return sendRequest(
1572                 command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID, phone, workSource);
1573     }
1574 
1575     /**
1576      * Posts the specified command to be executed on the main thread,
1577      * waits for the request to complete, and returns the result.
1578      * @see #sendRequestAsync
1579      */
sendRequest( int command, Object argument, Integer subId, Phone phone, WorkSource workSource)1580     private Object sendRequest(
1581             int command, Object argument, Integer subId, Phone phone, WorkSource workSource) {
1582         if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
1583             throw new RuntimeException("This method will deadlock if called from the main thread.");
1584         }
1585 
1586         MainThreadRequest request = null;
1587         if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID && phone != null) {
1588             throw new IllegalArgumentException("subId and phone cannot both be specified!");
1589         } else if (phone != null) {
1590             request = new MainThreadRequest(argument, phone, workSource);
1591         } else {
1592             request = new MainThreadRequest(argument, subId, workSource);
1593         }
1594 
1595         Message msg = mMainThreadHandler.obtainMessage(command, request);
1596         msg.sendToTarget();
1597 
1598         // Wait for the request to complete
1599         synchronized (request) {
1600             while (request.result == null) {
1601                 try {
1602                     request.wait();
1603                 } catch (InterruptedException e) {
1604                     // Do nothing, go back and wait until the request is complete
1605                 }
1606             }
1607         }
1608         return request.result;
1609     }
1610 
1611     /**
1612      * Asynchronous ("fire and forget") version of sendRequest():
1613      * Posts the specified command to be executed on the main thread, and
1614      * returns immediately.
1615      * @see #sendRequest
1616      */
sendRequestAsync(int command)1617     private void sendRequestAsync(int command) {
1618         mMainThreadHandler.sendEmptyMessage(command);
1619     }
1620 
1621     /**
1622      * Same as {@link #sendRequestAsync(int)} except it takes an argument.
1623      * @see {@link #sendRequest(int)}
1624      */
sendRequestAsync(int command, Object argument)1625     private void sendRequestAsync(int command, Object argument) {
1626         sendRequestAsync(command, argument, null, null);
1627     }
1628 
1629     /**
1630      * Same as {@link #sendRequestAsync(int,Object)} except it takes a Phone and WorkSource.
1631      * @see {@link #sendRequest(int,Object)}
1632      */
sendRequestAsync( int command, Object argument, Phone phone, WorkSource workSource)1633     private void sendRequestAsync(
1634             int command, Object argument, Phone phone, WorkSource workSource) {
1635         MainThreadRequest request = new MainThreadRequest(argument, phone, workSource);
1636         Message msg = mMainThreadHandler.obtainMessage(command, request);
1637         msg.sendToTarget();
1638     }
1639 
1640     /**
1641      * Initialize the singleton PhoneInterfaceManager instance.
1642      * This is only done once, at startup, from PhoneApp.onCreate().
1643      */
init(PhoneGlobals app)1644     /* package */ static PhoneInterfaceManager init(PhoneGlobals app) {
1645         synchronized (PhoneInterfaceManager.class) {
1646             if (sInstance == null) {
1647                 sInstance = new PhoneInterfaceManager(app);
1648             } else {
1649                 Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
1650             }
1651             return sInstance;
1652         }
1653     }
1654 
1655     /** Private constructor; @see init() */
PhoneInterfaceManager(PhoneGlobals app)1656     private PhoneInterfaceManager(PhoneGlobals app) {
1657         mApp = app;
1658         mCM = PhoneGlobals.getInstance().mCM;
1659         mImsResolver = PhoneGlobals.getInstance().getImsResolver();
1660         mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
1661         mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
1662         mMainThreadHandler = new MainThreadHandler();
1663         mSubscriptionController = SubscriptionController.getInstance();
1664         mTelephonySharedPreferences =
1665                 PreferenceManager.getDefaultSharedPreferences(mApp);
1666         mNetworkScanRequestTracker = new NetworkScanRequestTracker();
1667         mPhoneConfigurationManager = PhoneConfigurationManager.getInstance();
1668         mNotifyUserActivity = new AtomicBoolean(false);
1669 
1670         publish();
1671     }
1672 
getDefaultPhone()1673     private Phone getDefaultPhone() {
1674         Phone thePhone = getPhone(getDefaultSubscription());
1675         return (thePhone != null) ? thePhone : PhoneFactory.getDefaultPhone();
1676     }
1677 
publish()1678     private void publish() {
1679         if (DBG) log("publish: " + this);
1680 
1681         TelephonyFrameworkInitializer
1682                 .getTelephonyServiceManager()
1683                 .getTelephonyServiceRegisterer()
1684                 .register(this);
1685     }
1686 
getPhoneFromRequest(MainThreadRequest request)1687     private Phone getPhoneFromRequest(MainThreadRequest request) {
1688         if (request.phone != null) {
1689             return request.phone;
1690         } else {
1691             return getPhoneFromSubId(request.subId);
1692         }
1693     }
1694 
getPhoneFromSubId(int subId)1695     private Phone getPhoneFromSubId(int subId) {
1696         return (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
1697                 ? getDefaultPhone() : getPhone(subId);
1698     }
1699 
getUiccCardFromRequest(MainThreadRequest request)1700     private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
1701         Phone phone = getPhoneFromRequest(request);
1702         return phone == null ? null :
1703                 UiccController.getInstance().getUiccCard(phone.getPhoneId());
1704     }
1705 
1706     // returns phone associated with the subId.
getPhone(int subId)1707     private Phone getPhone(int subId) {
1708         return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
1709     }
1710 
sendEraseModemConfig(Phone phone)1711     private void sendEraseModemConfig(Phone phone) {
1712         if (phone != null) {
1713             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
1714                   mApp, phone.getSubId(), "eraseModemConfig");
1715             final long identity = Binder.clearCallingIdentity();
1716             try {
1717                 Boolean success = (Boolean) sendRequest(CMD_ERASE_MODEM_CONFIG, null);
1718                 if (DBG) log("eraseModemConfig:" + ' ' + (success ? "ok" : "fail"));
1719             } finally {
1720                 Binder.restoreCallingIdentity(identity);
1721             }
1722         }
1723     }
1724 
isImsAvailableOnDevice()1725     private boolean isImsAvailableOnDevice() {
1726         PackageManager pm = getDefaultPhone().getContext().getPackageManager();
1727         if (pm == null) {
1728             // For some reason package manger is not available.. This will fail internally anyway,
1729             // so do not throw error and allow.
1730             return true;
1731         }
1732         return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_IMS, 0);
1733     }
1734 
dial(String number)1735     public void dial(String number) {
1736         dialForSubscriber(getPreferredVoiceSubscription(), number);
1737     }
1738 
dialForSubscriber(int subId, String number)1739     public void dialForSubscriber(int subId, String number) {
1740         if (DBG) log("dial: " + number);
1741         // No permission check needed here: This is just a wrapper around the
1742         // ACTION_DIAL intent, which is available to any app since it puts up
1743         // the UI before it does anything.
1744 
1745         final long identity = Binder.clearCallingIdentity();
1746         try {
1747             String url = createTelUrl(number);
1748             if (url == null) {
1749                 return;
1750             }
1751 
1752             // PENDING: should we just silently fail if phone is offhook or ringing?
1753             PhoneConstants.State state = mCM.getState(subId);
1754             if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
1755                 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
1756                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1757                 mApp.startActivity(intent);
1758             }
1759         } finally {
1760             Binder.restoreCallingIdentity(identity);
1761         }
1762     }
1763 
call(String callingPackage, String number)1764     public void call(String callingPackage, String number) {
1765         callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
1766     }
1767 
callForSubscriber(int subId, String callingPackage, String number)1768     public void callForSubscriber(int subId, String callingPackage, String number) {
1769         if (DBG) log("call: " + number);
1770 
1771         // This is just a wrapper around the ACTION_CALL intent, but we still
1772         // need to do a permission check since we're calling startActivity()
1773         // from the context of the phone app.
1774         enforceCallPermission();
1775 
1776         if (mAppOps.noteOp(AppOpsManager.OPSTR_CALL_PHONE, Binder.getCallingUid(), callingPackage)
1777                 != AppOpsManager.MODE_ALLOWED) {
1778             return;
1779         }
1780 
1781         final long identity = Binder.clearCallingIdentity();
1782         try {
1783             String url = createTelUrl(number);
1784             if (url == null) {
1785                 return;
1786             }
1787 
1788             boolean isValid = false;
1789             final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
1790             if (slist != null) {
1791                 for (SubscriptionInfo subInfoRecord : slist) {
1792                     if (subInfoRecord.getSubscriptionId() == subId) {
1793                         isValid = true;
1794                         break;
1795                     }
1796                 }
1797             }
1798             if (!isValid) {
1799                 return;
1800             }
1801 
1802             Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
1803             intent.putExtra(SUBSCRIPTION_KEY, subId);
1804             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1805             mApp.startActivity(intent);
1806         } finally {
1807             Binder.restoreCallingIdentity(identity);
1808         }
1809     }
1810 
supplyPinForSubscriber(int subId, String pin)1811     public boolean supplyPinForSubscriber(int subId, String pin) {
1812         int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
1813         return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1814     }
1815 
supplyPukForSubscriber(int subId, String puk, String pin)1816     public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
1817         int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
1818         return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1819     }
1820 
supplyPinReportResultForSubscriber(int subId, String pin)1821     public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
1822         enforceModifyPermission();
1823 
1824         final long identity = Binder.clearCallingIdentity();
1825         try {
1826             final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
1827             checkSimPin.start();
1828             return checkSimPin.unlockSim(null, pin);
1829         } finally {
1830             Binder.restoreCallingIdentity(identity);
1831         }
1832     }
1833 
supplyPukReportResultForSubscriber(int subId, String puk, String pin)1834     public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
1835         enforceModifyPermission();
1836 
1837         final long identity = Binder.clearCallingIdentity();
1838         try {
1839             final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
1840             checkSimPuk.start();
1841             return checkSimPuk.unlockSim(puk, pin);
1842         } finally {
1843             Binder.restoreCallingIdentity(identity);
1844         }
1845     }
1846 
1847     /**
1848      * Helper thread to turn async call to SimCard#supplyPin into
1849      * a synchronous one.
1850      */
1851     private static class UnlockSim extends Thread {
1852 
1853         private final IccCard mSimCard;
1854 
1855         private boolean mDone = false;
1856         private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1857         private int mRetryCount = -1;
1858 
1859         // For replies from SimCard interface
1860         private Handler mHandler;
1861 
1862         // For async handler to identify request type
1863         private static final int SUPPLY_PIN_COMPLETE = 100;
1864 
UnlockSim(IccCard simCard)1865         public UnlockSim(IccCard simCard) {
1866             mSimCard = simCard;
1867         }
1868 
1869         @Override
run()1870         public void run() {
1871             Looper.prepare();
1872             synchronized (UnlockSim.this) {
1873                 mHandler = new Handler() {
1874                     @Override
1875                     public void handleMessage(Message msg) {
1876                         AsyncResult ar = (AsyncResult) msg.obj;
1877                         switch (msg.what) {
1878                             case SUPPLY_PIN_COMPLETE:
1879                                 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
1880                                 synchronized (UnlockSim.this) {
1881                                     mRetryCount = msg.arg1;
1882                                     if (ar.exception != null) {
1883                                         if (ar.exception instanceof CommandException &&
1884                                                 ((CommandException)(ar.exception)).getCommandError()
1885                                                 == CommandException.Error.PASSWORD_INCORRECT) {
1886                                             mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
1887                                         } else {
1888                                             mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1889                                         }
1890                                     } else {
1891                                         mResult = PhoneConstants.PIN_RESULT_SUCCESS;
1892                                     }
1893                                     mDone = true;
1894                                     UnlockSim.this.notifyAll();
1895                                 }
1896                                 break;
1897                         }
1898                     }
1899                 };
1900                 UnlockSim.this.notifyAll();
1901             }
1902             Looper.loop();
1903         }
1904 
1905         /*
1906          * Use PIN or PUK to unlock SIM card
1907          *
1908          * If PUK is null, unlock SIM card with PIN
1909          *
1910          * If PUK is not null, unlock SIM card with PUK and set PIN code
1911          */
unlockSim(String puk, String pin)1912         synchronized int[] unlockSim(String puk, String pin) {
1913 
1914             while (mHandler == null) {
1915                 try {
1916                     wait();
1917                 } catch (InterruptedException e) {
1918                     Thread.currentThread().interrupt();
1919                 }
1920             }
1921             Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
1922 
1923             if (puk == null) {
1924                 mSimCard.supplyPin(pin, callback);
1925             } else {
1926                 mSimCard.supplyPuk(puk, pin, callback);
1927             }
1928 
1929             while (!mDone) {
1930                 try {
1931                     Log.d(LOG_TAG, "wait for done");
1932                     wait();
1933                 } catch (InterruptedException e) {
1934                     // Restore the interrupted status
1935                     Thread.currentThread().interrupt();
1936                 }
1937             }
1938             Log.d(LOG_TAG, "done");
1939             int[] resultArray = new int[2];
1940             resultArray[0] = mResult;
1941             resultArray[1] = mRetryCount;
1942             return resultArray;
1943         }
1944     }
1945 
updateServiceLocation()1946     public void updateServiceLocation() {
1947         updateServiceLocationForSubscriber(getDefaultSubscription());
1948 
1949     }
1950 
updateServiceLocationForSubscriber(int subId)1951     public void updateServiceLocationForSubscriber(int subId) {
1952         // No permission check needed here: this call is harmless, and it's
1953         // needed for the ServiceState.requestStateUpdate() call (which is
1954         // already intentionally exposed to 3rd parties.)
1955         final long identity = Binder.clearCallingIdentity();
1956         try {
1957             final Phone phone = getPhone(subId);
1958             if (phone != null) {
1959                 phone.updateServiceLocation();
1960             }
1961         } finally {
1962             Binder.restoreCallingIdentity(identity);
1963         }
1964     }
1965 
1966     @Deprecated
1967     @Override
isRadioOn(String callingPackage)1968     public boolean isRadioOn(String callingPackage) {
1969         return isRadioOnWithFeature(callingPackage, null);
1970     }
1971 
1972 
1973     @Override
isRadioOnWithFeature(String callingPackage, String callingFeatureId)1974     public boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId) {
1975         return isRadioOnForSubscriberWithFeature(getDefaultSubscription(), callingPackage,
1976                 callingFeatureId);
1977     }
1978 
1979     @Deprecated
1980     @Override
isRadioOnForSubscriber(int subId, String callingPackage)1981     public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
1982         return isRadioOnForSubscriberWithFeature(subId, callingPackage, null);
1983     }
1984 
1985     @Override
isRadioOnForSubscriberWithFeature(int subId, String callingPackage, String callingFeatureId)1986     public boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage,
1987             String callingFeatureId) {
1988         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1989                 mApp, subId, callingPackage, callingFeatureId, "isRadioOnForSubscriber")) {
1990             return false;
1991         }
1992 
1993         final long identity = Binder.clearCallingIdentity();
1994         try {
1995             return isRadioOnForSubscriber(subId);
1996         } finally {
1997             Binder.restoreCallingIdentity(identity);
1998         }
1999     }
2000 
isRadioOnForSubscriber(int subId)2001     private boolean isRadioOnForSubscriber(int subId) {
2002         final long identity = Binder.clearCallingIdentity();
2003         try {
2004             final Phone phone = getPhone(subId);
2005             if (phone != null) {
2006                 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
2007             } else {
2008                 return false;
2009             }
2010         } finally {
2011             Binder.restoreCallingIdentity(identity);
2012         }
2013     }
2014 
toggleRadioOnOff()2015     public void toggleRadioOnOff() {
2016         toggleRadioOnOffForSubscriber(getDefaultSubscription());
2017     }
2018 
toggleRadioOnOffForSubscriber(int subId)2019     public void toggleRadioOnOffForSubscriber(int subId) {
2020         enforceModifyPermission();
2021 
2022         final long identity = Binder.clearCallingIdentity();
2023         try {
2024             final Phone phone = getPhone(subId);
2025             if (phone != null) {
2026                 phone.setRadioPower(!isRadioOnForSubscriber(subId));
2027             }
2028         } finally {
2029             Binder.restoreCallingIdentity(identity);
2030         }
2031     }
2032 
setRadio(boolean turnOn)2033     public boolean setRadio(boolean turnOn) {
2034         return setRadioForSubscriber(getDefaultSubscription(), turnOn);
2035     }
2036 
setRadioForSubscriber(int subId, boolean turnOn)2037     public boolean setRadioForSubscriber(int subId, boolean turnOn) {
2038         enforceModifyPermission();
2039 
2040         final long identity = Binder.clearCallingIdentity();
2041         try {
2042             final Phone phone = getPhone(subId);
2043             if (phone == null) {
2044                 return false;
2045             }
2046             if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
2047                 toggleRadioOnOffForSubscriber(subId);
2048             }
2049             return true;
2050         } finally {
2051             Binder.restoreCallingIdentity(identity);
2052         }
2053     }
2054 
needMobileRadioShutdown()2055     public boolean needMobileRadioShutdown() {
2056         enforceReadPrivilegedPermission("needMobileRadioShutdown");
2057         /*
2058          * If any of the Radios are available, it will need to be
2059          * shutdown. So return true if any Radio is available.
2060          */
2061         final long identity = Binder.clearCallingIdentity();
2062         try {
2063             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
2064                 Phone phone = PhoneFactory.getPhone(i);
2065                 if (phone != null && phone.isRadioAvailable()) return true;
2066             }
2067             logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
2068             return false;
2069         } finally {
2070             Binder.restoreCallingIdentity(identity);
2071         }
2072     }
2073 
2074     @Override
shutdownMobileRadios()2075     public void shutdownMobileRadios() {
2076         enforceModifyPermission();
2077 
2078         final long identity = Binder.clearCallingIdentity();
2079         try {
2080             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
2081                 logv("Shutting down Phone " + i);
2082                 shutdownRadioUsingPhoneId(i);
2083             }
2084         } finally {
2085             Binder.restoreCallingIdentity(identity);
2086         }
2087     }
2088 
shutdownRadioUsingPhoneId(int phoneId)2089     private void shutdownRadioUsingPhoneId(int phoneId) {
2090         Phone phone = PhoneFactory.getPhone(phoneId);
2091         if (phone != null && phone.isRadioAvailable()) {
2092             phone.shutdownRadio();
2093         }
2094     }
2095 
setRadioPower(boolean turnOn)2096     public boolean setRadioPower(boolean turnOn) {
2097         enforceModifyPermission();
2098 
2099         final long identity = Binder.clearCallingIdentity();
2100         try {
2101             final Phone defaultPhone = PhoneFactory.getDefaultPhone();
2102             if (defaultPhone != null) {
2103                 defaultPhone.setRadioPower(turnOn);
2104                 return true;
2105             } else {
2106                 loge("There's no default phone.");
2107                 return false;
2108             }
2109         } finally {
2110             Binder.restoreCallingIdentity(identity);
2111         }
2112     }
2113 
setRadioPowerForSubscriber(int subId, boolean turnOn)2114     public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
2115         enforceModifyPermission();
2116 
2117         final long identity = Binder.clearCallingIdentity();
2118         try {
2119             final Phone phone = getPhone(subId);
2120             if (phone != null) {
2121                 phone.setRadioPower(turnOn);
2122                 return true;
2123             } else {
2124                 return false;
2125             }
2126         } finally {
2127             Binder.restoreCallingIdentity(identity);
2128         }
2129     }
2130 
2131     // FIXME: subId version needed
2132     @Override
enableDataConnectivity()2133     public boolean enableDataConnectivity() {
2134         enforceModifyPermission();
2135 
2136         final long identity = Binder.clearCallingIdentity();
2137         try {
2138             int subId = mSubscriptionController.getDefaultDataSubId();
2139             final Phone phone = getPhone(subId);
2140             if (phone != null) {
2141                 phone.getDataEnabledSettings().setUserDataEnabled(true);
2142                 return true;
2143             } else {
2144                 return false;
2145             }
2146         } finally {
2147             Binder.restoreCallingIdentity(identity);
2148         }
2149     }
2150 
2151     // FIXME: subId version needed
2152     @Override
disableDataConnectivity()2153     public boolean disableDataConnectivity() {
2154         enforceModifyPermission();
2155 
2156         final long identity = Binder.clearCallingIdentity();
2157         try {
2158             int subId = mSubscriptionController.getDefaultDataSubId();
2159             final Phone phone = getPhone(subId);
2160             if (phone != null) {
2161                 phone.getDataEnabledSettings().setUserDataEnabled(false);
2162                 return true;
2163             } else {
2164                 return false;
2165             }
2166         } finally {
2167             Binder.restoreCallingIdentity(identity);
2168         }
2169     }
2170 
2171     @Override
isDataConnectivityPossible(int subId)2172     public boolean isDataConnectivityPossible(int subId) {
2173         final long identity = Binder.clearCallingIdentity();
2174         try {
2175             final Phone phone = getPhone(subId);
2176             if (phone != null) {
2177                 return phone.isDataAllowed(ApnSetting.TYPE_DEFAULT);
2178             } else {
2179                 return false;
2180             }
2181         } finally {
2182             Binder.restoreCallingIdentity(identity);
2183         }
2184     }
2185 
handlePinMmi(String dialString)2186     public boolean handlePinMmi(String dialString) {
2187         return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
2188     }
2189 
handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback)2190     public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
2191         enforceCallPermission();
2192 
2193         final long identity = Binder.clearCallingIdentity();
2194         try {
2195             if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2196                 return;
2197             }
2198             Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
2199             sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
2200         } finally {
2201             Binder.restoreCallingIdentity(identity);
2202         }
2203     };
2204 
handlePinMmiForSubscriber(int subId, String dialString)2205     public boolean handlePinMmiForSubscriber(int subId, String dialString) {
2206         enforceModifyPermission();
2207 
2208         final long identity = Binder.clearCallingIdentity();
2209         try {
2210             if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2211                 return false;
2212             }
2213             return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
2214         } finally {
2215             Binder.restoreCallingIdentity(identity);
2216         }
2217     }
2218 
getCallState()2219     public int getCallState() {
2220         return getCallStateForSlot(getSlotForDefaultSubscription());
2221     }
2222 
getCallStateForSlot(int slotIndex)2223     public int getCallStateForSlot(int slotIndex) {
2224         final long identity = Binder.clearCallingIdentity();
2225         try {
2226             Phone phone = PhoneFactory.getPhone(slotIndex);
2227             return phone == null ? TelephonyManager.CALL_STATE_IDLE :
2228                     PhoneConstantConversions.convertCallState(phone.getState());
2229         } finally {
2230             Binder.restoreCallingIdentity(identity);
2231         }
2232     }
2233 
2234     @Override
getDataState()2235     public int getDataState() {
2236         return getDataStateForSubId(mSubscriptionController.getDefaultDataSubId());
2237     }
2238 
2239     @Override
getDataStateForSubId(int subId)2240     public int getDataStateForSubId(int subId) {
2241         final long identity = Binder.clearCallingIdentity();
2242         try {
2243             final Phone phone = getPhone(subId);
2244             if (phone != null) {
2245                 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
2246             } else {
2247                 return PhoneConstantConversions.convertDataState(
2248                         PhoneConstants.DataState.DISCONNECTED);
2249             }
2250         } finally {
2251             Binder.restoreCallingIdentity(identity);
2252         }
2253     }
2254 
2255     @Override
getDataActivity()2256     public int getDataActivity() {
2257         return getDataActivityForSubId(mSubscriptionController.getDefaultDataSubId());
2258     }
2259 
2260     @Override
getDataActivityForSubId(int subId)2261     public int getDataActivityForSubId(int subId) {
2262         final long identity = Binder.clearCallingIdentity();
2263         try {
2264             final Phone phone = getPhone(subId);
2265             if (phone != null) {
2266                 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
2267             } else {
2268                 return TelephonyManager.DATA_ACTIVITY_NONE;
2269             }
2270         } finally {
2271             Binder.restoreCallingIdentity(identity);
2272         }
2273     }
2274 
2275     @Override
getCellLocation(String callingPackage, String callingFeatureId)2276     public CellIdentity getCellLocation(String callingPackage, String callingFeatureId) {
2277         mApp.getSystemService(AppOpsManager.class)
2278                 .checkPackage(Binder.getCallingUid(), callingPackage);
2279 
2280         LocationAccessPolicy.LocationPermissionResult locationResult =
2281                 LocationAccessPolicy.checkLocationPermission(mApp,
2282                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
2283                                 .setCallingPackage(callingPackage)
2284                                 .setCallingFeatureId(callingFeatureId)
2285                                 .setCallingPid(Binder.getCallingPid())
2286                                 .setCallingUid(Binder.getCallingUid())
2287                                 .setMethod("getCellLocation")
2288                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2289                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2290                                 .build());
2291         switch (locationResult) {
2292             case DENIED_HARD:
2293                 throw new SecurityException("Not allowed to access cell location");
2294             case DENIED_SOFT:
2295                 return (getDefaultPhone().getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA)
2296                         ? new CellIdentityCdma() : new CellIdentityGsm();
2297         }
2298 
2299         WorkSource workSource = getWorkSource(Binder.getCallingUid());
2300         final long identity = Binder.clearCallingIdentity();
2301         try {
2302             if (DBG_LOC) log("getCellLocation: is active user");
2303             int subId = mSubscriptionController.getDefaultDataSubId();
2304             return (CellIdentity) sendRequest(CMD_GET_CELL_LOCATION, workSource, subId);
2305         } finally {
2306             Binder.restoreCallingIdentity(identity);
2307         }
2308     }
2309 
2310     @Override
getNetworkCountryIsoForPhone(int phoneId)2311     public String getNetworkCountryIsoForPhone(int phoneId) {
2312         // Reporting the correct network country is ambiguous when IWLAN could conflict with
2313         // registered cell info, so return a NULL country instead.
2314         final long identity = Binder.clearCallingIdentity();
2315         try {
2316             if (phoneId == SubscriptionManager.INVALID_PHONE_INDEX) {
2317                 // Get default phone in this case.
2318                 phoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
2319             }
2320             final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
2321             Phone phone = PhoneFactory.getPhone(phoneId);
2322             if (phone == null) return "";
2323             ServiceStateTracker sst = phone.getServiceStateTracker();
2324             if (sst == null) return "";
2325             LocaleTracker lt = sst.getLocaleTracker();
2326             if (lt == null) return "";
2327             if (!TextUtils.isEmpty(lt.getCurrentCountry())) return lt.getCurrentCountry();
2328             EmergencyNumberTracker ent = phone.getEmergencyNumberTracker();
2329             return (ent == null) ? "" : ent.getEmergencyCountryIso();
2330         } finally {
2331             Binder.restoreCallingIdentity(identity);
2332         }
2333     }
2334 
2335     @Override
enableLocationUpdates()2336     public void enableLocationUpdates() {
2337         enableLocationUpdatesForSubscriber(getDefaultSubscription());
2338     }
2339 
2340     @Override
enableLocationUpdatesForSubscriber(int subId)2341     public void enableLocationUpdatesForSubscriber(int subId) {
2342         mApp.enforceCallingOrSelfPermission(
2343                 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
2344 
2345         final long identity = Binder.clearCallingIdentity();
2346         try {
2347             final Phone phone = getPhone(subId);
2348             if (phone != null) {
2349                 phone.enableLocationUpdates();
2350             }
2351         } finally {
2352             Binder.restoreCallingIdentity(identity);
2353         }
2354     }
2355 
2356     @Override
disableLocationUpdates()2357     public void disableLocationUpdates() {
2358         disableLocationUpdatesForSubscriber(getDefaultSubscription());
2359     }
2360 
2361     @Override
disableLocationUpdatesForSubscriber(int subId)2362     public void disableLocationUpdatesForSubscriber(int subId) {
2363         mApp.enforceCallingOrSelfPermission(
2364                 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
2365 
2366         final long identity = Binder.clearCallingIdentity();
2367         try {
2368             final Phone phone = getPhone(subId);
2369             if (phone != null) {
2370                 phone.disableLocationUpdates();
2371             }
2372         } finally {
2373             Binder.restoreCallingIdentity(identity);
2374         }
2375     }
2376 
2377     /**
2378      * Returns the target SDK version number for a given package name.
2379      *
2380      * This call MUST be invoked before clearing the calling UID.
2381      *
2382      * @return target SDK if the package is found or INT_MAX.
2383      */
getTargetSdk(String packageName)2384     private int getTargetSdk(String packageName) {
2385         try {
2386             final ApplicationInfo ai = mApp.getPackageManager().getApplicationInfoAsUser(
2387                     packageName, 0, UserHandle.getUserHandleForUid(Binder.getCallingUid()));
2388             if (ai != null) return ai.targetSdkVersion;
2389         } catch (PackageManager.NameNotFoundException unexpected) {
2390             loge("Failed to get package info for pkg="
2391                     + packageName + ", uid=" + Binder.getCallingUid());
2392         }
2393         return Integer.MAX_VALUE;
2394     }
2395 
2396     @Override
2397     @SuppressWarnings("unchecked")
getNeighboringCellInfo(String callingPackage, String callingFeatureId)2398     public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage,
2399             String callingFeatureId) {
2400         final int targetSdk = getTargetSdk(callingPackage);
2401         if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
2402             throw new SecurityException(
2403                     "getNeighboringCellInfo() is unavailable to callers targeting Q+ SDK levels.");
2404         }
2405 
2406         if (mAppOps.noteOp(AppOpsManager.OPSTR_NEIGHBORING_CELLS, Binder.getCallingUid(),
2407                 callingPackage) != AppOpsManager.MODE_ALLOWED) {
2408             return null;
2409         }
2410 
2411         if (DBG_LOC) log("getNeighboringCellInfo: is active user");
2412 
2413         List<CellInfo> info = getAllCellInfo(callingPackage, callingFeatureId);
2414         if (info == null) return null;
2415 
2416         List<NeighboringCellInfo> neighbors = new ArrayList<NeighboringCellInfo>();
2417         for (CellInfo ci : info) {
2418             if (ci instanceof CellInfoGsm) {
2419                 neighbors.add(new NeighboringCellInfo((CellInfoGsm) ci));
2420             } else if (ci instanceof CellInfoWcdma) {
2421                 neighbors.add(new NeighboringCellInfo((CellInfoWcdma) ci));
2422             }
2423         }
2424         return (neighbors.size()) > 0 ? neighbors : null;
2425     }
2426 
getCachedCellInfo()2427     private List<CellInfo> getCachedCellInfo() {
2428         List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2429         for (Phone phone : PhoneFactory.getPhones()) {
2430             List<CellInfo> info = phone.getAllCellInfo();
2431             if (info != null) cellInfos.addAll(info);
2432         }
2433         return cellInfos;
2434     }
2435 
2436     @Override
getAllCellInfo(String callingPackage, String callingFeatureId)2437     public List<CellInfo> getAllCellInfo(String callingPackage, String callingFeatureId) {
2438         mApp.getSystemService(AppOpsManager.class)
2439                 .checkPackage(Binder.getCallingUid(), callingPackage);
2440 
2441         LocationAccessPolicy.LocationPermissionResult locationResult =
2442                 LocationAccessPolicy.checkLocationPermission(mApp,
2443                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
2444                                 .setCallingPackage(callingPackage)
2445                                 .setCallingFeatureId(callingFeatureId)
2446                                 .setCallingPid(Binder.getCallingPid())
2447                                 .setCallingUid(Binder.getCallingUid())
2448                                 .setMethod("getAllCellInfo")
2449                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2450                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
2451                                 .build());
2452         switch (locationResult) {
2453             case DENIED_HARD:
2454                 throw new SecurityException("Not allowed to access cell info");
2455             case DENIED_SOFT:
2456                 return new ArrayList<>();
2457         }
2458 
2459         final int targetSdk = getTargetSdk(callingPackage);
2460         if (targetSdk >= android.os.Build.VERSION_CODES.Q) {
2461             return getCachedCellInfo();
2462         }
2463 
2464         if (DBG_LOC) log("getAllCellInfo: is active user");
2465         WorkSource workSource = getWorkSource(Binder.getCallingUid());
2466         final long identity = Binder.clearCallingIdentity();
2467         try {
2468             List<CellInfo> cellInfos = new ArrayList<CellInfo>();
2469             for (Phone phone : PhoneFactory.getPhones()) {
2470                 final List<CellInfo> info = (List<CellInfo>) sendRequest(
2471                         CMD_GET_ALL_CELL_INFO, null, phone, workSource);
2472                 if (info != null) cellInfos.addAll(info);
2473             }
2474             return cellInfos;
2475         } finally {
2476             Binder.restoreCallingIdentity(identity);
2477         }
2478     }
2479 
2480     @Override
requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage, String callingFeatureId)2481     public void requestCellInfoUpdate(int subId, ICellInfoCallback cb, String callingPackage,
2482             String callingFeatureId) {
2483         requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId,
2484                 getWorkSource(Binder.getCallingUid()));
2485     }
2486 
2487     @Override
requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb, String callingPackage, String callingFeatureId, WorkSource workSource)2488     public void requestCellInfoUpdateWithWorkSource(int subId, ICellInfoCallback cb,
2489             String callingPackage, String callingFeatureId, WorkSource workSource) {
2490         enforceModifyPermission();
2491         requestCellInfoUpdateInternal(subId, cb, callingPackage, callingFeatureId, workSource);
2492     }
2493 
requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb, String callingPackage, String callingFeatureId, WorkSource workSource)2494     private void requestCellInfoUpdateInternal(int subId, ICellInfoCallback cb,
2495             String callingPackage, String callingFeatureId, WorkSource workSource) {
2496         mApp.getSystemService(AppOpsManager.class)
2497                 .checkPackage(Binder.getCallingUid(), callingPackage);
2498 
2499         LocationAccessPolicy.LocationPermissionResult locationResult =
2500                 LocationAccessPolicy.checkLocationPermission(mApp,
2501                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
2502                                 .setCallingPackage(callingPackage)
2503                                 .setCallingFeatureId(callingFeatureId)
2504                                 .setCallingPid(Binder.getCallingPid())
2505                                 .setCallingUid(Binder.getCallingUid())
2506                                 .setMethod("requestCellInfoUpdate")
2507                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.BASE)
2508                                 .setMinSdkVersionForFine(Build.VERSION_CODES.BASE)
2509                                 .build());
2510         switch (locationResult) {
2511             case DENIED_HARD:
2512                 if (getTargetSdk(callingPackage) < Build.VERSION_CODES.Q) {
2513                     // Safetynet logging for b/154934934
2514                     EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
2515                 }
2516                 throw new SecurityException("Not allowed to access cell info");
2517             case DENIED_SOFT:
2518                 if (getTargetSdk(callingPackage) < Build.VERSION_CODES.Q) {
2519                     // Safetynet logging for b/154934934
2520                     EventLog.writeEvent(0x534e4554, "154934934", Binder.getCallingUid());
2521                 }
2522                 try {
2523                     cb.onCellInfo(new ArrayList<CellInfo>());
2524                 } catch (RemoteException re) {
2525                     // Drop without consequences
2526                 }
2527                 return;
2528         }
2529 
2530 
2531         final Phone phone = getPhoneFromSubId(subId);
2532         if (phone == null) throw new IllegalArgumentException("Invalid Subscription Id: " + subId);
2533 
2534         sendRequestAsync(CMD_REQUEST_CELL_INFO_UPDATE, cb, phone, workSource);
2535     }
2536 
2537     @Override
setCellInfoListRate(int rateInMillis)2538     public void setCellInfoListRate(int rateInMillis) {
2539         enforceModifyPermission();
2540         WorkSource workSource = getWorkSource(Binder.getCallingUid());
2541 
2542         final long identity = Binder.clearCallingIdentity();
2543         try {
2544             getDefaultPhone().setCellInfoListRate(rateInMillis, workSource);
2545         } finally {
2546             Binder.restoreCallingIdentity(identity);
2547         }
2548     }
2549 
2550     @Override
getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId)2551     public String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
2552         Phone phone = PhoneFactory.getPhone(slotIndex);
2553         if (phone == null) {
2554             return null;
2555         }
2556         int subId = phone.getSubId();
2557         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
2558                 callingPackage, callingFeatureId, "getImeiForSlot")) {
2559             return null;
2560         }
2561 
2562         final long identity = Binder.clearCallingIdentity();
2563         try {
2564             return phone.getImei();
2565         } finally {
2566             Binder.restoreCallingIdentity(identity);
2567         }
2568     }
2569 
2570     @Override
getTypeAllocationCodeForSlot(int slotIndex)2571     public String getTypeAllocationCodeForSlot(int slotIndex) {
2572         Phone phone = PhoneFactory.getPhone(slotIndex);
2573         String tac = null;
2574         if (phone != null) {
2575             String imei = phone.getImei();
2576             tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
2577         }
2578         return tac;
2579     }
2580 
2581     @Override
getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId)2582     public String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
2583         Phone phone = PhoneFactory.getPhone(slotIndex);
2584         if (phone == null) {
2585             return null;
2586         }
2587 
2588         int subId = phone.getSubId();
2589         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
2590                 callingPackage, callingFeatureId, "getMeidForSlot")) {
2591             return null;
2592         }
2593 
2594         final long identity = Binder.clearCallingIdentity();
2595         try {
2596             return phone.getMeid();
2597         } finally {
2598             Binder.restoreCallingIdentity(identity);
2599         }
2600     }
2601 
2602     @Override
getManufacturerCodeForSlot(int slotIndex)2603     public String getManufacturerCodeForSlot(int slotIndex) {
2604         Phone phone = PhoneFactory.getPhone(slotIndex);
2605         String manufacturerCode = null;
2606         if (phone != null) {
2607             String meid = phone.getMeid();
2608             manufacturerCode = meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
2609         }
2610         return manufacturerCode;
2611     }
2612 
2613     @Override
getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage, String callingFeatureId)2614     public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage,
2615             String callingFeatureId) {
2616         Phone phone = PhoneFactory.getPhone(slotIndex);
2617         if (phone == null) {
2618             return null;
2619         }
2620         int subId = phone.getSubId();
2621         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2622                 mApp, subId, callingPackage, callingFeatureId,
2623                 "getDeviceSoftwareVersionForSlot")) {
2624             return null;
2625         }
2626 
2627         final long identity = Binder.clearCallingIdentity();
2628         try {
2629             return phone.getDeviceSvn();
2630         } finally {
2631             Binder.restoreCallingIdentity(identity);
2632         }
2633     }
2634 
2635     @Override
getSubscriptionCarrierId(int subId)2636     public int getSubscriptionCarrierId(int subId) {
2637         final long identity = Binder.clearCallingIdentity();
2638         try {
2639             final Phone phone = getPhone(subId);
2640             return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
2641         } finally {
2642             Binder.restoreCallingIdentity(identity);
2643         }
2644     }
2645 
2646     @Override
getSubscriptionCarrierName(int subId)2647     public String getSubscriptionCarrierName(int subId) {
2648         final long identity = Binder.clearCallingIdentity();
2649         try {
2650             final Phone phone = getPhone(subId);
2651             return phone == null ? null : phone.getCarrierName();
2652         } finally {
2653             Binder.restoreCallingIdentity(identity);
2654         }
2655     }
2656 
2657     @Override
getSubscriptionSpecificCarrierId(int subId)2658     public int getSubscriptionSpecificCarrierId(int subId) {
2659         final long identity = Binder.clearCallingIdentity();
2660         try {
2661             final Phone phone = getPhone(subId);
2662             return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID
2663                     : phone.getSpecificCarrierId();
2664         } finally {
2665             Binder.restoreCallingIdentity(identity);
2666         }
2667     }
2668 
2669     @Override
getSubscriptionSpecificCarrierName(int subId)2670     public String getSubscriptionSpecificCarrierName(int subId) {
2671         final long identity = Binder.clearCallingIdentity();
2672         try {
2673             final Phone phone = getPhone(subId);
2674             return phone == null ? null : phone.getSpecificCarrierName();
2675         } finally {
2676             Binder.restoreCallingIdentity(identity);
2677         }
2678     }
2679 
2680     @Override
getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc)2681     public int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc) {
2682         if (!isSubscriptionMccMnc) {
2683             enforceReadPrivilegedPermission("getCarrierIdFromMccMnc");
2684         }
2685         final Phone phone = PhoneFactory.getPhone(slotIndex);
2686         if (phone == null) {
2687             return TelephonyManager.UNKNOWN_CARRIER_ID;
2688         }
2689         final long identity = Binder.clearCallingIdentity();
2690         try {
2691             return CarrierResolver.getCarrierIdFromMccMnc(phone.getContext(), mccmnc);
2692         } finally {
2693             Binder.restoreCallingIdentity(identity);
2694         }
2695     }
2696 
2697     //
2698     // Internal helper methods.
2699     //
2700 
2701     /**
2702      * Make sure the caller has the MODIFY_PHONE_STATE permission.
2703      *
2704      * @throws SecurityException if the caller does not have the required permission
2705      */
enforceModifyPermission()2706     private void enforceModifyPermission() {
2707         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
2708     }
2709 
2710     /**
2711      * Make sure the caller is system.
2712      *
2713      * @throws SecurityException if the caller is not system.
2714      */
enforceSystemCaller()2715     private void enforceSystemCaller() {
2716         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
2717             throw new SecurityException("Caller must be system");
2718         }
2719     }
2720 
enforceActiveEmergencySessionPermission()2721     private void enforceActiveEmergencySessionPermission() {
2722         mApp.enforceCallingOrSelfPermission(
2723                 android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null);
2724     }
2725 
2726     /**
2727      * Make sure the caller has the CALL_PHONE permission.
2728      *
2729      * @throws SecurityException if the caller does not have the required permission
2730      */
enforceCallPermission()2731     private void enforceCallPermission() {
2732         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
2733     }
2734 
enforceSettingsPermission()2735     private void enforceSettingsPermission() {
2736         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS, null);
2737     }
2738 
createTelUrl(String number)2739     private String createTelUrl(String number) {
2740         if (TextUtils.isEmpty(number)) {
2741             return null;
2742         }
2743 
2744         return "tel:" + number;
2745     }
2746 
log(String msg)2747     private static void log(String msg) {
2748         Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
2749     }
2750 
logv(String msg)2751     private static void logv(String msg) {
2752         Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
2753     }
2754 
loge(String msg)2755     private static void loge(String msg) {
2756         Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
2757     }
2758 
2759     @Override
getActivePhoneType()2760     public int getActivePhoneType() {
2761         return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
2762     }
2763 
2764     @Override
getActivePhoneTypeForSlot(int slotIndex)2765     public int getActivePhoneTypeForSlot(int slotIndex) {
2766         final long identity = Binder.clearCallingIdentity();
2767         try {
2768             final Phone phone = PhoneFactory.getPhone(slotIndex);
2769             if (phone == null) {
2770                 return PhoneConstants.PHONE_TYPE_NONE;
2771             } else {
2772                 return phone.getPhoneType();
2773             }
2774         } finally {
2775             Binder.restoreCallingIdentity(identity);
2776         }
2777     }
2778 
2779     /**
2780      * Returns the CDMA ERI icon index to display
2781      */
2782     @Override
getCdmaEriIconIndex(String callingPackage, String callingFeatureId)2783     public int getCdmaEriIconIndex(String callingPackage, String callingFeatureId) {
2784         return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage,
2785                 callingFeatureId);
2786     }
2787 
2788     @Override
getCdmaEriIconIndexForSubscriber(int subId, String callingPackage, String callingFeatureId)2789     public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
2790             String callingFeatureId) {
2791         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2792                 mApp, subId, callingPackage, callingFeatureId,
2793                 "getCdmaEriIconIndexForSubscriber")) {
2794             return -1;
2795         }
2796 
2797         final long identity = Binder.clearCallingIdentity();
2798         try {
2799             final Phone phone = getPhone(subId);
2800             if (phone != null) {
2801                 return phone.getCdmaEriIconIndex();
2802             } else {
2803                 return -1;
2804             }
2805         } finally {
2806             Binder.restoreCallingIdentity(identity);
2807         }
2808     }
2809 
2810     /**
2811      * Returns the CDMA ERI icon mode,
2812      * 0 - ON
2813      * 1 - FLASHING
2814      */
2815     @Override
getCdmaEriIconMode(String callingPackage, String callingFeatureId)2816     public int getCdmaEriIconMode(String callingPackage, String callingFeatureId) {
2817         return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage,
2818                 callingFeatureId);
2819     }
2820 
2821     @Override
getCdmaEriIconModeForSubscriber(int subId, String callingPackage, String callingFeatureId)2822     public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
2823             String callingFeatureId) {
2824         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2825                 mApp, subId, callingPackage, callingFeatureId,
2826                 "getCdmaEriIconModeForSubscriber")) {
2827             return -1;
2828         }
2829 
2830         final long identity = Binder.clearCallingIdentity();
2831         try {
2832             final Phone phone = getPhone(subId);
2833             if (phone != null) {
2834                 return phone.getCdmaEriIconMode();
2835             } else {
2836                 return -1;
2837             }
2838         } finally {
2839             Binder.restoreCallingIdentity(identity);
2840         }
2841     }
2842 
2843     /**
2844      * Returns the CDMA ERI text,
2845      */
2846     @Override
getCdmaEriText(String callingPackage, String callingFeatureId)2847     public String getCdmaEriText(String callingPackage, String callingFeatureId) {
2848         return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage,
2849                 callingFeatureId);
2850     }
2851 
2852     @Override
getCdmaEriTextForSubscriber(int subId, String callingPackage, String callingFeatureId)2853     public String getCdmaEriTextForSubscriber(int subId, String callingPackage,
2854             String callingFeatureId) {
2855         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2856                 mApp, subId, callingPackage, callingFeatureId,
2857                 "getCdmaEriIconTextForSubscriber")) {
2858             return null;
2859         }
2860 
2861         final long identity = Binder.clearCallingIdentity();
2862         try {
2863             final Phone phone = getPhone(subId);
2864             if (phone != null) {
2865                 return phone.getCdmaEriText();
2866             } else {
2867                 return null;
2868             }
2869         } finally {
2870             Binder.restoreCallingIdentity(identity);
2871         }
2872     }
2873 
2874     /**
2875      * Returns the CDMA MDN.
2876      */
2877     @Override
getCdmaMdn(int subId)2878     public String getCdmaMdn(int subId) {
2879         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2880                 mApp, subId, "getCdmaMdn");
2881 
2882         final long identity = Binder.clearCallingIdentity();
2883         try {
2884             final Phone phone = getPhone(subId);
2885             if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2886                 return phone.getLine1Number();
2887             } else {
2888                 loge("getCdmaMdn: no phone found. Invalid subId: " + subId);
2889                 return null;
2890             }
2891         } finally {
2892             Binder.restoreCallingIdentity(identity);
2893         }
2894     }
2895 
2896     /**
2897      * Returns the CDMA MIN.
2898      */
2899     @Override
getCdmaMin(int subId)2900     public String getCdmaMin(int subId) {
2901         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2902                 mApp, subId, "getCdmaMin");
2903 
2904         final long identity = Binder.clearCallingIdentity();
2905         try {
2906             final Phone phone = getPhone(subId);
2907             if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2908                 return phone.getCdmaMin();
2909             } else {
2910                 return null;
2911             }
2912         } finally {
2913             Binder.restoreCallingIdentity(identity);
2914         }
2915     }
2916 
2917     @Override
requestNumberVerification(PhoneNumberRange range, long timeoutMillis, INumberVerificationCallback callback, String callingPackage)2918     public void requestNumberVerification(PhoneNumberRange range, long timeoutMillis,
2919             INumberVerificationCallback callback, String callingPackage) {
2920         if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
2921                 != PERMISSION_GRANTED) {
2922             throw new SecurityException("Caller must hold the MODIFY_PHONE_STATE permission");
2923         }
2924         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2925 
2926         String authorizedPackage = NumberVerificationManager.getAuthorizedPackage(mApp);
2927         if (!TextUtils.equals(callingPackage, authorizedPackage)) {
2928             throw new SecurityException("Calling package must be configured in the device config");
2929         }
2930 
2931         if (range == null) {
2932             throw new NullPointerException("Range must be non-null");
2933         }
2934 
2935         timeoutMillis = Math.min(timeoutMillis,
2936                 TelephonyManager.getMaxNumberVerificationTimeoutMillis());
2937 
2938         NumberVerificationManager.getInstance().requestVerification(range, callback, timeoutMillis);
2939     }
2940 
2941     /**
2942      * Returns true if CDMA provisioning needs to run.
2943      */
needsOtaServiceProvisioning()2944     public boolean needsOtaServiceProvisioning() {
2945         final long identity = Binder.clearCallingIdentity();
2946         try {
2947             return getDefaultPhone().needsOtaServiceProvisioning();
2948         } finally {
2949             Binder.restoreCallingIdentity(identity);
2950         }
2951     }
2952 
2953     /**
2954      * Sets the voice mail number of a given subId.
2955      */
2956     @Override
setVoiceMailNumber(int subId, String alphaTag, String number)2957     public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
2958         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
2959                 mApp, subId, "setVoiceMailNumber");
2960 
2961         final long identity = Binder.clearCallingIdentity();
2962         try {
2963             Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
2964                     new Pair<String, String>(alphaTag, number), new Integer(subId));
2965             return success;
2966         } finally {
2967             Binder.restoreCallingIdentity(identity);
2968         }
2969     }
2970 
2971     @Override
getVisualVoicemailSettings(String callingPackage, int subId)2972     public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
2973         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2974         TelecomManager tm = mApp.getSystemService(TelecomManager.class);
2975         String systemDialer = tm.getSystemDialerPackage();
2976         if (!TextUtils.equals(callingPackage, systemDialer)) {
2977             throw new SecurityException("caller must be system dialer");
2978         }
2979 
2980         final long identity = Binder.clearCallingIdentity();
2981         try {
2982             PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
2983             if (phoneAccountHandle == null) {
2984                 return null;
2985             }
2986             return VisualVoicemailSettingsUtil.dump(mApp, phoneAccountHandle);
2987         } finally {
2988             Binder.restoreCallingIdentity(identity);
2989         }
2990     }
2991 
2992     @Override
getVisualVoicemailPackageName(String callingPackage, String callingFeatureId, int subId)2993     public String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId,
2994             int subId) {
2995         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2996         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2997                 mApp, subId, callingPackage, callingFeatureId,
2998                 "getVisualVoicemailPackageName")) {
2999             return null;
3000         }
3001 
3002         final long identity = Binder.clearCallingIdentity();
3003         try {
3004             return RemoteVvmTaskManager.getRemotePackage(mApp, subId).getPackageName();
3005         } finally {
3006             Binder.restoreCallingIdentity(identity);
3007         }
3008     }
3009 
3010     @Override
enableVisualVoicemailSmsFilter(String callingPackage, int subId, VisualVoicemailSmsFilterSettings settings)3011     public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
3012             VisualVoicemailSmsFilterSettings settings) {
3013         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3014 
3015         final long identity = Binder.clearCallingIdentity();
3016         try {
3017             VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
3018                     mApp, callingPackage, subId, settings);
3019         } finally {
3020             Binder.restoreCallingIdentity(identity);
3021         }
3022     }
3023 
3024     @Override
disableVisualVoicemailSmsFilter(String callingPackage, int subId)3025     public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
3026         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3027 
3028         final long identity = Binder.clearCallingIdentity();
3029         try {
3030             VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
3031                     mApp, callingPackage, subId);
3032         } finally {
3033             Binder.restoreCallingIdentity(identity);
3034         }
3035     }
3036 
3037     @Override
getVisualVoicemailSmsFilterSettings( String callingPackage, int subId)3038     public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
3039             String callingPackage, int subId) {
3040         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3041 
3042         final long identity = Binder.clearCallingIdentity();
3043         try {
3044             return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
3045                     mApp, callingPackage, subId);
3046         } finally {
3047             Binder.restoreCallingIdentity(identity);
3048         }
3049     }
3050 
3051     @Override
getActiveVisualVoicemailSmsFilterSettings(int subId)3052     public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
3053         enforceReadPrivilegedPermission("getActiveVisualVoicemailSmsFilterSettings");
3054 
3055         final long identity = Binder.clearCallingIdentity();
3056         try {
3057             return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
3058                     mApp, subId);
3059         } finally {
3060             Binder.restoreCallingIdentity(identity);
3061         }
3062     }
3063 
3064     @Override
sendVisualVoicemailSmsForSubscriber(String callingPackage, String callingAttributionTag, int subId, String number, int port, String text, PendingIntent sentIntent)3065     public void sendVisualVoicemailSmsForSubscriber(String callingPackage,
3066             String callingAttributionTag, int subId, String number, int port, String text,
3067             PendingIntent sentIntent) {
3068         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3069         enforceVisualVoicemailPackage(callingPackage, subId);
3070         enforceSendSmsPermission();
3071         SmsController smsController = PhoneFactory.getSmsController();
3072         smsController.sendVisualVoicemailSmsForSubscriber(callingPackage, callingAttributionTag,
3073                 subId, number, port, text, sentIntent);
3074     }
3075 
3076     /**
3077      * Sets the voice activation state of a given subId.
3078      */
3079     @Override
setVoiceActivationState(int subId, int activationState)3080     public void setVoiceActivationState(int subId, int activationState) {
3081         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3082                 mApp, subId, "setVoiceActivationState");
3083 
3084         final long identity = Binder.clearCallingIdentity();
3085         try {
3086             final Phone phone = getPhone(subId);
3087             if (phone != null) {
3088                 phone.setVoiceActivationState(activationState);
3089             } else {
3090                 loge("setVoiceActivationState fails with invalid subId: " + subId);
3091             }
3092         } finally {
3093             Binder.restoreCallingIdentity(identity);
3094         }
3095     }
3096 
3097     /**
3098      * Sets the data activation state of a given subId.
3099      */
3100     @Override
setDataActivationState(int subId, int activationState)3101     public void setDataActivationState(int subId, int activationState) {
3102         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3103                 mApp, subId, "setDataActivationState");
3104 
3105         final long identity = Binder.clearCallingIdentity();
3106         try {
3107             final Phone phone = getPhone(subId);
3108             if (phone != null) {
3109                 phone.setDataActivationState(activationState);
3110             } else {
3111                 loge("setDataActivationState fails with invalid subId: " + subId);
3112             }
3113         } finally {
3114             Binder.restoreCallingIdentity(identity);
3115         }
3116     }
3117 
3118     /**
3119      * Returns the voice activation state of a given subId.
3120      */
3121     @Override
getVoiceActivationState(int subId, String callingPackage)3122     public int getVoiceActivationState(int subId, String callingPackage) {
3123         enforceReadPrivilegedPermission("getVoiceActivationState");
3124 
3125         final Phone phone = getPhone(subId);
3126         final long identity = Binder.clearCallingIdentity();
3127         try {
3128             if (phone != null) {
3129                 return phone.getVoiceActivationState();
3130             } else {
3131                 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
3132             }
3133         } finally {
3134             Binder.restoreCallingIdentity(identity);
3135         }
3136     }
3137 
3138     /**
3139      * Returns the data activation state of a given subId.
3140      */
3141     @Override
getDataActivationState(int subId, String callingPackage)3142     public int getDataActivationState(int subId, String callingPackage) {
3143         enforceReadPrivilegedPermission("getDataActivationState");
3144 
3145         final Phone phone = getPhone(subId);
3146         final long identity = Binder.clearCallingIdentity();
3147         try {
3148             if (phone != null) {
3149                 return phone.getDataActivationState();
3150             } else {
3151                 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
3152             }
3153         } finally {
3154             Binder.restoreCallingIdentity(identity);
3155         }
3156     }
3157 
3158     /**
3159      * Returns the unread count of voicemails for a subId
3160      */
3161     @Override
getVoiceMessageCountForSubscriber(int subId, String callingPackage, String callingFeatureId)3162     public int getVoiceMessageCountForSubscriber(int subId, String callingPackage,
3163             String callingFeatureId) {
3164         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3165                 mApp, subId, callingPackage, callingFeatureId,
3166                 "getVoiceMessageCountForSubscriber")) {
3167             return 0;
3168         }
3169         final long identity = Binder.clearCallingIdentity();
3170         try {
3171             final Phone phone = getPhone(subId);
3172             if (phone != null) {
3173                 return phone.getVoiceMessageCount();
3174             } else {
3175                 return 0;
3176             }
3177         } finally {
3178             Binder.restoreCallingIdentity(identity);
3179         }
3180     }
3181 
3182     /**
3183       * returns true, if the device is in a state where both voice and data
3184       * are supported simultaneously. This can change based on location or network condition.
3185      */
3186     @Override
isConcurrentVoiceAndDataAllowed(int subId)3187     public boolean isConcurrentVoiceAndDataAllowed(int subId) {
3188         final long identity = Binder.clearCallingIdentity();
3189         try {
3190             final Phone phone = getPhone(subId);
3191             return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
3192         } finally {
3193             Binder.restoreCallingIdentity(identity);
3194         }
3195     }
3196 
3197     /**
3198      * Send the dialer code if called from the current default dialer or the caller has
3199      * carrier privilege.
3200      * @param inputCode The dialer code to send
3201      */
3202     @Override
sendDialerSpecialCode(String callingPackage, String inputCode)3203     public void sendDialerSpecialCode(String callingPackage, String inputCode) {
3204         final Phone defaultPhone = getDefaultPhone();
3205         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3206         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
3207         String defaultDialer = tm.getDefaultDialerPackage();
3208         if (!TextUtils.equals(callingPackage, defaultDialer)) {
3209             TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
3210                     getDefaultSubscription(), "sendDialerSpecialCode");
3211         }
3212 
3213         final long identity = Binder.clearCallingIdentity();
3214         try {
3215             defaultPhone.sendDialerSpecialCode(inputCode);
3216         } finally {
3217             Binder.restoreCallingIdentity(identity);
3218         }
3219     }
3220 
3221     @Override
getNetworkSelectionMode(int subId)3222     public int getNetworkSelectionMode(int subId) {
3223         TelephonyPermissions
3224                     .enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3225                     mApp, subId, "getNetworkSelectionMode");
3226         final long identity = Binder.clearCallingIdentity();
3227         try {
3228             if (!isActiveSubscription(subId)) {
3229                 return TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN;
3230             }
3231             return (int) sendRequest(CMD_GET_NETWORK_SELECTION_MODE, null /* argument */, subId);
3232         } finally {
3233             Binder.restoreCallingIdentity(identity);
3234         }
3235     }
3236 
3237     @Override
isInEmergencySmsMode()3238     public boolean isInEmergencySmsMode() {
3239         enforceReadPrivilegedPermission("isInEmergencySmsMode");
3240         final long identity = Binder.clearCallingIdentity();
3241         try {
3242             for (Phone phone : PhoneFactory.getPhones()) {
3243                 if (phone.isInEmergencySmsMode()) {
3244                     return true;
3245                 }
3246             }
3247         } finally {
3248             Binder.restoreCallingIdentity(identity);
3249         }
3250         return false;
3251     }
3252 
3253     /**
3254      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3255      * @param subId The subscription to use to check the configuration.
3256      * @param c The callback that will be used to send the result.
3257      */
3258     @Override
registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)3259     public void registerImsRegistrationCallback(int subId, IImsRegistrationCallback c)
3260             throws RemoteException {
3261         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3262                 mApp, subId, "registerImsRegistrationCallback");
3263 
3264         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3265             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3266                     "IMS not available on device.");
3267         }
3268         final long token = Binder.clearCallingIdentity();
3269         try {
3270             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3271             ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3272                     .addRegistrationCallbackForSubscription(c, subId);
3273         } catch (ImsException e) {
3274             throw new ServiceSpecificException(e.getCode());
3275         } finally {
3276             Binder.restoreCallingIdentity(token);
3277         }
3278     }
3279 
3280     /**
3281      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3282      * @param subId The subscription to use to check the configuration.
3283      * @param c The callback that will be used to send the result.
3284      */
3285     @Override
unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c)3286     public void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c) {
3287         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3288                 mApp, subId, "unregisterImsRegistrationCallback");
3289         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3290             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3291         }
3292         final long token = Binder.clearCallingIdentity();
3293         try {
3294             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
3295             ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3296                     .removeRegistrationCallbackForSubscription(c, subId);
3297         } catch (ImsException e) {
3298             Log.i(LOG_TAG, "unregisterImsRegistrationCallback: " + subId
3299                     + "is inactive, ignoring unregister.");
3300             // If the subscription is no longer active, just return, since the callback
3301             // will already have been removed internally.
3302         } finally {
3303             Binder.restoreCallingIdentity(token);
3304         }
3305     }
3306 
3307     /**
3308      * Get the IMS service registration state for the MmTelFeature associated with this sub id.
3309      */
3310     @Override
getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer)3311     public void getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer) {
3312         enforceReadPrivilegedPermission("getImsMmTelRegistrationState");
3313         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3314             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3315                     "IMS not available on device.");
3316         }
3317         final long token = Binder.clearCallingIdentity();
3318         try {
3319             Phone phone = getPhone(subId);
3320             if (phone == null) {
3321                 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
3322                         + subId + "'");
3323                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3324             }
3325             phone.getImsRegistrationState(regState -> {
3326                 try {
3327                     consumer.accept((regState == null)
3328                             ? RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED : regState);
3329                 } catch (RemoteException e) {
3330                     // Ignore if the remote process is no longer available to call back.
3331                     Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
3332                 }
3333             });
3334         } finally {
3335             Binder.restoreCallingIdentity(token);
3336         }
3337     }
3338 
3339     /**
3340      * Get the transport type for the IMS service registration state.
3341      */
3342     @Override
getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer)3343     public void getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer) {
3344         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3345                 mApp, subId, "getImsMmTelRegistrationTransportType");
3346         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3347             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3348                     "IMS not available on device.");
3349         }
3350         final long token = Binder.clearCallingIdentity();
3351         try {
3352             Phone phone = getPhone(subId);
3353             if (phone == null) {
3354                 Log.w(LOG_TAG, "getImsMmTelRegistrationState: called with an invalid subscription '"
3355                         + subId + "'");
3356                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3357             }
3358             phone.getImsRegistrationTech(regTech -> {
3359                 // Convert registration tech from ImsRegistrationImplBase -> RegistrationManager
3360                 int regTechConverted = (regTech == null)
3361                         ? ImsRegistrationImplBase.REGISTRATION_TECH_NONE : regTech;
3362                 regTechConverted = RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(
3363                         regTechConverted);
3364                 try {
3365                     consumer.accept(regTechConverted);
3366                 } catch (RemoteException e) {
3367                     // Ignore if the remote process is no longer available to call back.
3368                     Log.w(LOG_TAG, "getImsMmTelRegistrationState: callback not available.");
3369                 }
3370             });
3371         } finally {
3372             Binder.restoreCallingIdentity(token);
3373         }
3374     }
3375 
3376     /**
3377      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3378      * @param subId The subscription to use to check the configuration.
3379      * @param c The callback that will be used to send the result.
3380      */
3381     @Override
registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)3382     public void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)
3383             throws RemoteException {
3384         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3385                 mApp, subId, "registerMmTelCapabilityCallback");
3386         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3387             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3388                     "IMS not available on device.");
3389         }
3390         // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3391         final long token = Binder.clearCallingIdentity();
3392         try {
3393             ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3394                     .addCapabilitiesCallbackForSubscription(c, subId);
3395         } catch (ImsException e) {
3396             throw new ServiceSpecificException(e.getCode());
3397         } finally {
3398             Binder.restoreCallingIdentity(token);
3399         }
3400     }
3401 
3402     /**
3403      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3404      * @param subId The subscription to use to check the configuration.
3405      * @param c The callback that will be used to send the result.
3406      */
3407     @Override
unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c)3408     public void unregisterMmTelCapabilityCallback(int subId, IImsCapabilityCallback c) {
3409         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3410                 mApp, subId, "unregisterMmTelCapabilityCallback");
3411         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3412             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3413         }
3414 
3415         final long token = Binder.clearCallingIdentity();
3416         try {
3417             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone.
3418             ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3419                         .removeCapabilitiesCallbackForSubscription(c, subId);
3420         } catch (ImsException e) {
3421             Log.i(LOG_TAG, "unregisterMmTelCapabilityCallback: " + subId
3422                      + "is inactive, ignoring unregister.");
3423              // If the subscription is no longer active, just return, since the callback
3424              // will already have been removed internally.
3425         } finally {
3426             Binder.restoreCallingIdentity(token);
3427         }
3428     }
3429 
3430     @Override
isCapable(int subId, int capability, int regTech)3431     public boolean isCapable(int subId, int capability, int regTech) {
3432         enforceReadPrivilegedPermission("isCapable");
3433         // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3434         final long token = Binder.clearCallingIdentity();
3435         try {
3436             return ImsManager.getInstance(mApp,
3437                     getSlotIndexOrException(subId)).queryMmTelCapability(capability, regTech);
3438         } catch (com.android.ims.ImsException e) {
3439             Log.w(LOG_TAG, "IMS isCapable - service unavailable: " + e.getMessage());
3440             return false;
3441         } catch (ImsException e) {
3442             Log.i(LOG_TAG, "isCapable: " + subId + " is inactive, returning false.");
3443             return false;
3444         } finally {
3445             Binder.restoreCallingIdentity(token);
3446         }
3447     }
3448 
3449     @Override
isAvailable(int subId, int capability, int regTech)3450     public boolean isAvailable(int subId, int capability, int regTech) {
3451         enforceReadPrivilegedPermission("isAvailable");
3452         final long token = Binder.clearCallingIdentity();
3453         try {
3454             Phone phone = getPhone(subId);
3455             if (phone == null) return false;
3456             return phone.isImsCapabilityAvailable(capability, regTech);
3457         } catch (com.android.ims.ImsException e) {
3458             Log.w(LOG_TAG, "IMS isAvailable - service unavailable: " + e.getMessage());
3459             return false;
3460         } finally {
3461             Binder.restoreCallingIdentity(token);
3462         }
3463     }
3464 
3465     /**
3466      * Determines if the MmTel feature capability is supported by the carrier configuration for this
3467      * subscription.
3468      * @param subId The subscription to use to check the configuration.
3469      * @param callback The callback that will be used to send the result.
3470      * @param capability The MmTelFeature capability that will be used to send the result.
3471      * @param transportType The transport type of the MmTelFeature capability.
3472      */
3473     @Override
isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability, int transportType)3474     public void isMmTelCapabilitySupported(int subId, IIntegerConsumer callback, int capability,
3475             int transportType) {
3476         enforceReadPrivilegedPermission("isMmTelCapabilitySupported");
3477         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
3478             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3479                     "IMS not available on device.");
3480         }
3481         final long token = Binder.clearCallingIdentity();
3482         try {
3483             int slotId = getSlotIndex(subId);
3484             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
3485                 Log.w(LOG_TAG, "isMmTelCapabilitySupported: called with an inactive subscription '"
3486                         + subId + "'");
3487                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
3488             }
3489             ImsManager.getInstance(mApp, slotId).isSupported(capability,
3490                     transportType, aBoolean -> {
3491                         try {
3492                             callback.accept((aBoolean == null) ? 0 : (aBoolean ? 1 : 0));
3493                         } catch (RemoteException e) {
3494                             Log.w(LOG_TAG, "isMmTelCapabilitySupported: remote caller is not "
3495                                     + "running. Ignore");
3496                         }
3497                     });
3498         } finally {
3499             Binder.restoreCallingIdentity(token);
3500         }
3501     }
3502 
3503     /**
3504      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3505      * @param subId The subscription to use to check the configuration.
3506      */
3507     @Override
isAdvancedCallingSettingEnabled(int subId)3508     public boolean isAdvancedCallingSettingEnabled(int subId) {
3509         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3510                 mApp, subId, "isAdvancedCallingSettingEnabled");
3511 
3512         // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3513         final long token = Binder.clearCallingIdentity();
3514         try {
3515             return ImsManager.getInstance(mApp,
3516                     getSlotIndexOrException(subId)).isEnhanced4gLteModeSettingEnabledByUser();
3517         } catch (ImsException e) {
3518             throw new ServiceSpecificException(e.getCode());
3519         } finally {
3520             Binder.restoreCallingIdentity(token);
3521         }
3522     }
3523 
3524     @Override
setAdvancedCallingSettingEnabled(int subId, boolean isEnabled)3525     public void setAdvancedCallingSettingEnabled(int subId, boolean isEnabled) {
3526         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3527                 "setAdvancedCallingSettingEnabled");
3528         final long identity = Binder.clearCallingIdentity();
3529         try {
3530             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3531             ImsManager.getInstance(mApp,
3532                     getSlotIndexOrException(subId)).setEnhanced4gLteModeSetting(isEnabled);
3533         } catch (ImsException e) {
3534             throw new ServiceSpecificException(e.getCode());
3535         } finally {
3536             Binder.restoreCallingIdentity(identity);
3537         }
3538     }
3539 
3540     /**
3541      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3542      * @param subId The subscription to use to check the configuration.
3543      */
3544     @Override
isVtSettingEnabled(int subId)3545     public boolean isVtSettingEnabled(int subId) {
3546         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3547                 mApp, subId, "isVtSettingEnabled");
3548         final long identity = Binder.clearCallingIdentity();
3549         try {
3550             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3551             return ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).isVtEnabledByUser();
3552         } catch (ImsException e) {
3553             throw new ServiceSpecificException(e.getCode());
3554         } finally {
3555             Binder.restoreCallingIdentity(identity);
3556         }
3557     }
3558 
3559     @Override
setVtSettingEnabled(int subId, boolean isEnabled)3560     public void setVtSettingEnabled(int subId, boolean isEnabled) {
3561         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3562                 "setVtSettingEnabled");
3563         final long identity = Binder.clearCallingIdentity();
3564         try {
3565             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3566             ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setVtSetting(isEnabled);
3567         } catch (ImsException e) {
3568             throw new ServiceSpecificException(e.getCode());
3569         } finally {
3570             Binder.restoreCallingIdentity(identity);
3571         }
3572     }
3573 
3574     /**
3575      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3576      * @param subId The subscription to use to check the configuration.
3577      */
3578     @Override
isVoWiFiSettingEnabled(int subId)3579     public boolean isVoWiFiSettingEnabled(int subId) {
3580         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3581                 mApp, subId, "isVoWiFiSettingEnabled");
3582         final long identity = Binder.clearCallingIdentity();
3583         try {
3584             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3585             return ImsManager.getInstance(mApp,
3586                     getSlotIndexOrException(subId)).isWfcEnabledByUser();
3587         } catch (ImsException e) {
3588             throw new ServiceSpecificException(e.getCode());
3589         } finally {
3590             Binder.restoreCallingIdentity(identity);
3591         }
3592     }
3593 
3594     @Override
setVoWiFiSettingEnabled(int subId, boolean isEnabled)3595     public void setVoWiFiSettingEnabled(int subId, boolean isEnabled) {
3596         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3597                 "setVoWiFiSettingEnabled");
3598         final long identity = Binder.clearCallingIdentity();
3599         try {
3600             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3601             ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setWfcSetting(isEnabled);
3602         } catch (ImsException e) {
3603             throw new ServiceSpecificException(e.getCode());
3604         } finally {
3605             Binder.restoreCallingIdentity(identity);
3606         }
3607     }
3608 
3609     /**
3610      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3611      * @param subId The subscription to use to check the configuration.
3612      */
3613     @Override
isVoWiFiRoamingSettingEnabled(int subId)3614     public boolean isVoWiFiRoamingSettingEnabled(int subId) {
3615         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3616                 mApp, subId, "isVoWiFiRoamingSettingEnabled");
3617         final long identity = Binder.clearCallingIdentity();
3618         try {
3619             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3620             return ImsManager.getInstance(mApp,
3621                     getSlotIndexOrException(subId)).isWfcRoamingEnabledByUser();
3622         } catch (ImsException e) {
3623             throw new ServiceSpecificException(e.getCode());
3624         } finally {
3625             Binder.restoreCallingIdentity(identity);
3626         }
3627     }
3628 
3629     @Override
setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled)3630     public void setVoWiFiRoamingSettingEnabled(int subId, boolean isEnabled) {
3631         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3632                 "setVoWiFiRoamingSettingEnabled");
3633         final long identity = Binder.clearCallingIdentity();
3634         try {
3635             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3636             ImsManager.getInstance(mApp,
3637                     getSlotIndexOrException(subId)).setWfcRoamingSetting(isEnabled);
3638         } catch (ImsException e) {
3639             throw new ServiceSpecificException(e.getCode());
3640         } finally {
3641             Binder.restoreCallingIdentity(identity);
3642         }
3643     }
3644 
3645     @Override
setVoWiFiNonPersistent(int subId, boolean isCapable, int mode)3646     public void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode) {
3647         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3648                 "setVoWiFiNonPersistent");
3649         final long identity = Binder.clearCallingIdentity();
3650         try {
3651             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3652             ImsManager.getInstance(mApp,
3653                     getSlotIndexOrException(subId)).setWfcNonPersistent(isCapable, mode);
3654         } catch (ImsException e) {
3655             throw new ServiceSpecificException(e.getCode());
3656         } finally {
3657             Binder.restoreCallingIdentity(identity);
3658         }
3659     }
3660 
3661     /**
3662      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3663      * @param subId The subscription to use to check the configuration.
3664      */
3665     @Override
getVoWiFiModeSetting(int subId)3666     public int getVoWiFiModeSetting(int subId) {
3667         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3668                 mApp, subId, "getVoWiFiModeSetting");
3669         final long identity = Binder.clearCallingIdentity();
3670         try {
3671             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3672             return ImsManager.getInstance(mApp,
3673                     getSlotIndexOrException(subId)).getWfcMode(false /*isRoaming*/);
3674         } catch (ImsException e) {
3675             throw new ServiceSpecificException(e.getCode());
3676         } finally {
3677             Binder.restoreCallingIdentity(identity);
3678         }
3679     }
3680 
3681     @Override
setVoWiFiModeSetting(int subId, int mode)3682     public void setVoWiFiModeSetting(int subId, int mode) {
3683         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3684                 "setVoWiFiModeSetting");
3685         final long identity = Binder.clearCallingIdentity();
3686         try {
3687             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3688             ImsManager.getInstance(mApp,
3689                     getSlotIndexOrException(subId)).setWfcMode(mode, false /*isRoaming*/);
3690         } catch (ImsException e) {
3691             throw new ServiceSpecificException(e.getCode());
3692         } finally {
3693             Binder.restoreCallingIdentity(identity);
3694         }
3695     }
3696 
3697     @Override
getVoWiFiRoamingModeSetting(int subId)3698     public int getVoWiFiRoamingModeSetting(int subId) {
3699         enforceReadPrivilegedPermission("getVoWiFiRoamingModeSetting");
3700         final long identity = Binder.clearCallingIdentity();
3701         try {
3702             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3703             return ImsManager.getInstance(mApp,
3704                     getSlotIndexOrException(subId)).getWfcMode(true /*isRoaming*/);
3705         } catch (ImsException e) {
3706             throw new ServiceSpecificException(e.getCode());
3707         } finally {
3708             Binder.restoreCallingIdentity(identity);
3709         }
3710     }
3711 
3712     @Override
setVoWiFiRoamingModeSetting(int subId, int mode)3713     public void setVoWiFiRoamingModeSetting(int subId, int mode) {
3714         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3715                 "setVoWiFiRoamingModeSetting");
3716         final long identity = Binder.clearCallingIdentity();
3717         try {
3718             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3719             ImsManager.getInstance(mApp,
3720                     getSlotIndexOrException(subId)).setWfcMode(mode, true /*isRoaming*/);
3721         } catch (ImsException e) {
3722             throw new ServiceSpecificException(e.getCode());
3723         } finally {
3724             Binder.restoreCallingIdentity(identity);
3725         }
3726     }
3727 
3728     @Override
setRttCapabilitySetting(int subId, boolean isEnabled)3729     public void setRttCapabilitySetting(int subId, boolean isEnabled) {
3730         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3731                 "setRttCapabilityEnabled");
3732         final long identity = Binder.clearCallingIdentity();
3733         try {
3734             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3735             ImsManager.getInstance(mApp, getSlotIndexOrException(subId)).setRttEnabled(isEnabled);
3736         } catch (ImsException e) {
3737             throw new ServiceSpecificException(e.getCode());
3738         } finally {
3739             Binder.restoreCallingIdentity(identity);
3740         }
3741     }
3742 
3743     /**
3744      * Requires carrier privileges or READ_PRECISE_PHONE_STATE permission.
3745      * @param subId The subscription to use to check the configuration.
3746      */
3747     @Override
isTtyOverVolteEnabled(int subId)3748     public boolean isTtyOverVolteEnabled(int subId) {
3749         TelephonyPermissions.enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
3750                 mApp, subId, "isTtyOverVolteEnabled");
3751         final long identity = Binder.clearCallingIdentity();
3752         try {
3753             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3754             return ImsManager.getInstance(mApp,
3755                     getSlotIndexOrException(subId)).isTtyOnVoLteCapable();
3756         } catch (ImsException e) {
3757             throw new ServiceSpecificException(e.getCode());
3758         } finally {
3759             Binder.restoreCallingIdentity(identity);
3760         }
3761     }
3762 
3763     @Override
registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback)3764     public void registerImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
3765         enforceReadPrivilegedPermission("registerImsProvisioningChangedCallback");
3766         final long identity = Binder.clearCallingIdentity();
3767         try {
3768             if (!isImsAvailableOnDevice()) {
3769                 throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
3770                         "IMS not available on device.");
3771             }
3772             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3773             ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3774                     .addProvisioningCallbackForSubscription(callback, subId);
3775         } catch (ImsException e) {
3776             throw new ServiceSpecificException(e.getCode());
3777         } finally {
3778             Binder.restoreCallingIdentity(identity);
3779         }
3780     }
3781 
3782     @Override
unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback)3783     public void unregisterImsProvisioningChangedCallback(int subId, IImsConfigCallback callback) {
3784         enforceReadPrivilegedPermission("unregisterImsProvisioningChangedCallback");
3785         final long identity = Binder.clearCallingIdentity();
3786         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3787             throw new IllegalArgumentException("Invalid Subscription ID: " + subId);
3788         }
3789         try {
3790             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3791             ImsManager.getInstance(mApp, getSlotIndexOrException(subId))
3792                     .removeProvisioningCallbackForSubscription(callback, subId);
3793         } catch (ImsException e) {
3794             Log.i(LOG_TAG, "unregisterImsProvisioningChangedCallback: " + subId
3795                     + "is inactive, ignoring unregister.");
3796             // If the subscription is no longer active, just return, since the callback will already
3797             // have been removed internally.
3798         } finally {
3799             Binder.restoreCallingIdentity(identity);
3800         }
3801     }
3802 
3803 
checkModifyPhoneStatePermission(int subId, String message)3804     private void checkModifyPhoneStatePermission(int subId, String message) {
3805         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
3806                 message);
3807     }
3808 
isImsProvisioningRequired(int subId, int capability, boolean isMmtelCapability)3809     private boolean isImsProvisioningRequired(int subId, int capability,
3810             boolean isMmtelCapability) {
3811         Phone phone = getPhone(subId);
3812         if (phone == null) {
3813             loge("phone instance null for subid " + subId);
3814             return false;
3815         }
3816         if (isMmtelCapability) {
3817             if (!doesImsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
3818                 return false;
3819             }
3820         } else {
3821             if (!doesRcsCapabilityRequireProvisioning(phone.getContext(), subId, capability)) {
3822                 return false;
3823             }
3824         }
3825         return true;
3826     }
3827 
3828     @Override
setRcsProvisioningStatusForCapability(int subId, int capability, boolean isProvisioned)3829     public void setRcsProvisioningStatusForCapability(int subId, int capability,
3830             boolean isProvisioned) {
3831         checkModifyPhoneStatePermission(subId, "setRcsProvisioningStatusForCapability");
3832 
3833         final long identity = Binder.clearCallingIdentity();
3834         try {
3835             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3836             if (!isImsProvisioningRequired(subId, capability, false)) {
3837                 return;
3838             }
3839 
3840             // this capability requires provisioning, route to the correct API.
3841             ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3842             switch (capability) {
3843                 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
3844                 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
3845                     ims.setEabProvisioned(isProvisioned);
3846                     break;
3847                 default: {
3848                     throw new IllegalArgumentException("Tried to set provisioning for "
3849                             + "rcs capability '" + capability + "', which does not require "
3850                             + "provisioning.");
3851                 }
3852             }
3853         } finally {
3854             Binder.restoreCallingIdentity(identity);
3855         }
3856 
3857     }
3858 
3859 
3860     @Override
getRcsProvisioningStatusForCapability(int subId, int capability)3861     public boolean getRcsProvisioningStatusForCapability(int subId, int capability) {
3862         enforceReadPrivilegedPermission("getRcsProvisioningStatusForCapability");
3863         final long identity = Binder.clearCallingIdentity();
3864         try {
3865             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3866             if (!isImsProvisioningRequired(subId, capability, false)) {
3867                 return true;
3868             }
3869 
3870             ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3871             switch (capability) {
3872                 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE:
3873                 case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
3874                     return ims.isEabProvisionedOnDevice();
3875 
3876                 default: {
3877                     throw new IllegalArgumentException("Tried to get rcs provisioning for "
3878                             + "capability '" + capability + "', which does not require "
3879                             + "provisioning.");
3880                 }
3881             }
3882 
3883         } finally {
3884             Binder.restoreCallingIdentity(identity);
3885         }
3886     }
3887 
3888     @Override
setImsProvisioningStatusForCapability(int subId, int capability, int tech, boolean isProvisioned)3889     public void setImsProvisioningStatusForCapability(int subId, int capability, int tech,
3890             boolean isProvisioned) {
3891         if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3892                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3893             throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3894         }
3895         checkModifyPhoneStatePermission(subId, "setImsProvisioningStatusForCapability");
3896         final long identity = Binder.clearCallingIdentity();
3897         try {
3898             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3899             if (!isImsProvisioningRequired(subId, capability, true)) {
3900                 return;
3901             }
3902 
3903             // this capability requires provisioning, route to the correct API.
3904             ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3905             switch (capability) {
3906                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
3907                     if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3908                         ims.setVolteProvisioned(isProvisioned);
3909                     } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
3910                         ims.setWfcProvisioned(isProvisioned);
3911                     }
3912                     break;
3913                 }
3914                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3915                     // There is currently no difference in VT provisioning type.
3916                     ims.setVtProvisioned(isProvisioned);
3917                     break;
3918                 }
3919                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3920                     // There is no "deprecated" UT provisioning mechanism through ImsConfig, so
3921                     // change the capability of the feature instead if needed.
3922                     if (isMmTelCapabilityProvisionedInCache(subId, capability, tech)
3923                             == isProvisioned) {
3924                         // No change in provisioning.
3925                         return;
3926                     }
3927                     cacheMmTelCapabilityProvisioning(subId, capability, tech, isProvisioned);
3928                     try {
3929                         ims.changeMmTelCapability(capability, tech, isProvisioned);
3930                     } catch (com.android.ims.ImsException e) {
3931                         loge("setImsProvisioningStatusForCapability: couldn't change UT capability"
3932                                 + ", Exception" + e.getMessage());
3933                     }
3934                     break;
3935                 }
3936                 default: {
3937                     throw new IllegalArgumentException("Tried to set provisioning for "
3938                             + "MmTel capability '" + capability + "', which does not require "
3939                             + "provisioning. ");
3940                 }
3941             }
3942 
3943         } finally {
3944             Binder.restoreCallingIdentity(identity);
3945         }
3946     }
3947 
3948     @Override
getImsProvisioningStatusForCapability(int subId, int capability, int tech)3949     public boolean getImsProvisioningStatusForCapability(int subId, int capability, int tech) {
3950         if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3951                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3952             throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
3953         }
3954         enforceReadPrivilegedPermission("getProvisioningStatusForCapability");
3955         final long identity = Binder.clearCallingIdentity();
3956         try {
3957             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
3958             if (!isImsProvisioningRequired(subId, capability, true)) {
3959                 return true;
3960             }
3961 
3962             ImsManager ims = ImsManager.getInstance(mApp, getSlotIndex(subId));
3963             switch (capability) {
3964                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE: {
3965                     if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3966                         return ims.isVolteProvisionedOnDevice();
3967                     } else if (tech == ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN) {
3968                         return ims.isWfcProvisionedOnDevice();
3969                     }
3970                     // This should never happen, since we are checking tech above to make sure it
3971                     // is either LTE or IWLAN.
3972                     throw new IllegalArgumentException("Invalid radio technology for voice "
3973                             + "capability.");
3974                 }
3975                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
3976                     // There is currently no difference in VT provisioning type.
3977                     return ims.isVtProvisionedOnDevice();
3978                 }
3979                 case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
3980                     // There is no "deprecated" UT provisioning mechanism, so get from shared prefs.
3981                     return isMmTelCapabilityProvisionedInCache(subId, capability, tech);
3982                 }
3983                 default: {
3984                     throw new IllegalArgumentException(
3985                             "Tried to get provisioning for MmTel capability '" + capability
3986                                     + "', which does not require provisioning.");
3987                 }
3988             }
3989 
3990         } finally {
3991             Binder.restoreCallingIdentity(identity);
3992         }
3993     }
3994 
3995     @Override
isMmTelCapabilityProvisionedInCache(int subId, int capability, int tech)3996     public boolean isMmTelCapabilityProvisionedInCache(int subId, int capability, int tech) {
3997         if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
3998                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
3999             throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4000         }
4001         enforceReadPrivilegedPermission("isMmTelCapabilityProvisionedInCache");
4002         int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
4003         return (provisionedBits & capability) > 0;
4004     }
4005 
4006     @Override
cacheMmTelCapabilityProvisioning(int subId, int capability, int tech, boolean isProvisioned)4007     public void cacheMmTelCapabilityProvisioning(int subId, int capability, int tech,
4008             boolean isProvisioned) {
4009         if (tech != ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN
4010                 && tech != ImsRegistrationImplBase.REGISTRATION_TECH_LTE) {
4011             throw new IllegalArgumentException("Registration technology '" + tech + "' is invalid");
4012         }
4013         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4014                 "setProvisioningStatusForCapability");
4015         int provisionedBits = getMmTelCapabilityProvisioningBitfield(subId, tech);
4016         // If the current provisioning status for capability already matches isProvisioned,
4017         // do nothing.
4018         if (((provisionedBits & capability) > 0) == isProvisioned) {
4019             return;
4020         }
4021         if (isProvisioned) {
4022             setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits | capability));
4023         } else {
4024             setMmTelCapabilityProvisioningBitfield(subId, tech, (provisionedBits & ~capability));
4025         }
4026     }
4027 
4028     /**
4029      * @return the bitfield containing the MmTel provisioning for the provided subscription and
4030      * technology. The bitfield should mirror the bitfield defined by
4031      * {@link MmTelFeature.MmTelCapabilities.MmTelCapability}.
4032      */
getMmTelCapabilityProvisioningBitfield(int subId, int tech)4033     private int getMmTelCapabilityProvisioningBitfield(int subId, int tech) {
4034         String key = getMmTelProvisioningKey(subId, tech);
4035         // Default is no capabilities are provisioned.
4036         return mTelephonySharedPreferences.getInt(key, 0 /*default*/);
4037     }
4038 
4039     /**
4040      * Sets the MmTel capability provisioning bitfield (defined by
4041      *     {@link MmTelFeature.MmTelCapabilities.MmTelCapability}) for the subscription and
4042      *     technology specified.
4043      *
4044      * Note: This is a synchronous command and should not be called on UI thread.
4045      */
setMmTelCapabilityProvisioningBitfield(int subId, int tech, int newField)4046     private void setMmTelCapabilityProvisioningBitfield(int subId, int tech, int newField) {
4047         final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
4048         String key = getMmTelProvisioningKey(subId, tech);
4049         editor.putInt(key, newField);
4050         editor.commit();
4051     }
4052 
getMmTelProvisioningKey(int subId, int tech)4053     private static String getMmTelProvisioningKey(int subId, int tech) {
4054         // resulting key is provision_ims_mmtel_{subId}_{tech}
4055         return PREF_PROVISION_IMS_MMTEL_PREFIX + subId + "_" + tech;
4056     }
4057 
4058     /**
4059      * Query CarrierConfig to see if the specified capability requires provisioning for the
4060      * carrier associated with the subscription id.
4061      */
doesImsCapabilityRequireProvisioning(Context context, int subId, int capability)4062     private boolean doesImsCapabilityRequireProvisioning(Context context, int subId,
4063             int capability) {
4064         CarrierConfigManager configManager = new CarrierConfigManager(context);
4065         PersistableBundle c = configManager.getConfigForSubId(subId);
4066         boolean requireUtProvisioning = c.getBoolean(
4067                 CarrierConfigManager.KEY_CARRIER_SUPPORTS_SS_OVER_UT_BOOL, false)
4068                 && c.getBoolean(CarrierConfigManager.KEY_CARRIER_UT_PROVISIONING_REQUIRED_BOOL,
4069                 false);
4070         boolean requireVoiceVtProvisioning = c.getBoolean(
4071                 CarrierConfigManager.KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false);
4072 
4073         // First check to make sure that the capability requires provisioning.
4074         switch (capability) {
4075             case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE:
4076                 // intentional fallthrough
4077             case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO: {
4078                 if (requireVoiceVtProvisioning) {
4079                     // Voice and Video requires provisioning
4080                     return true;
4081                 }
4082                 break;
4083             }
4084             case MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_UT: {
4085                 if (requireUtProvisioning) {
4086                     // UT requires provisioning
4087                     return true;
4088                 }
4089                 break;
4090             }
4091         }
4092         return false;
4093     }
4094 
doesRcsCapabilityRequireProvisioning(Context context, int subId, int capability)4095     private boolean doesRcsCapabilityRequireProvisioning(Context context, int subId,
4096             int capability) {
4097         CarrierConfigManager configManager = new CarrierConfigManager(context);
4098         PersistableBundle c = configManager.getConfigForSubId(subId);
4099 
4100         boolean requireRcsProvisioning = c.getBoolean(
4101                 CarrierConfigManager.KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL, false);
4102 
4103         // First check to make sure that the capability requires provisioning.
4104         switch (capability) {
4105             case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_PRESENCE_UCE:
4106                 // intentional fallthrough
4107             case RcsFeature.RcsImsCapabilities.CAPABILITY_TYPE_OPTIONS_UCE: {
4108                 if (requireRcsProvisioning) {
4109                     // OPTION or PRESENCE requires provisioning
4110                     return true;
4111                 }
4112                 break;
4113             }
4114         }
4115         return false;
4116     }
4117 
4118     @Override
getImsProvisioningInt(int subId, int key)4119     public int getImsProvisioningInt(int subId, int key) {
4120         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4121             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4122         }
4123         enforceReadPrivilegedPermission("getImsProvisioningInt");
4124         final long identity = Binder.clearCallingIdentity();
4125         try {
4126             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4127             int slotId = getSlotIndex(subId);
4128             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4129                 Log.w(LOG_TAG, "getImsProvisioningInt: called with an inactive subscription '"
4130                         + subId + "' for key:" + key);
4131                 return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
4132             }
4133             return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigInt(key);
4134         } catch (com.android.ims.ImsException e) {
4135             Log.w(LOG_TAG, "getImsProvisioningInt: ImsService is not available for subscription '"
4136                     + subId + "' for key:" + key);
4137             return ImsConfigImplBase.CONFIG_RESULT_UNKNOWN;
4138         } finally {
4139             Binder.restoreCallingIdentity(identity);
4140         }
4141     }
4142 
4143     @Override
getImsProvisioningString(int subId, int key)4144     public String getImsProvisioningString(int subId, int key) {
4145         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4146             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4147         }
4148         enforceReadPrivilegedPermission("getImsProvisioningString");
4149         final long identity = Binder.clearCallingIdentity();
4150         try {
4151             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4152             int slotId = getSlotIndex(subId);
4153             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4154                 Log.w(LOG_TAG, "getImsProvisioningString: called for an inactive subscription id '"
4155                         + subId + "' for key:" + key);
4156                 return ProvisioningManager.STRING_QUERY_RESULT_ERROR_GENERIC;
4157             }
4158             return ImsManager.getInstance(mApp, slotId).getConfigInterface().getConfigString(key);
4159         } catch (com.android.ims.ImsException e) {
4160             Log.w(LOG_TAG, "getImsProvisioningString: ImsService is not available for sub '"
4161                     + subId + "' for key:" + key);
4162             return ProvisioningManager.STRING_QUERY_RESULT_ERROR_NOT_READY;
4163         } finally {
4164             Binder.restoreCallingIdentity(identity);
4165         }
4166     }
4167 
4168     @Override
setImsProvisioningInt(int subId, int key, int value)4169     public int setImsProvisioningInt(int subId, int key, int value) {
4170         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4171             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4172         }
4173         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4174                 "setImsProvisioningInt");
4175         final long identity = Binder.clearCallingIdentity();
4176         try {
4177             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4178             int slotId = getSlotIndex(subId);
4179             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4180                 Log.w(LOG_TAG, "setImsProvisioningInt: called with an inactive subscription id '"
4181                         + subId + "' for key:" + key);
4182                 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4183             }
4184             return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
4185         } catch (com.android.ims.ImsException e) {
4186             Log.w(LOG_TAG, "setImsProvisioningInt: ImsService unavailable for sub '" + subId
4187                     + "' for key:" + key);
4188             return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4189         } finally {
4190             Binder.restoreCallingIdentity(identity);
4191         }
4192     }
4193 
4194     @Override
setImsProvisioningString(int subId, int key, String value)4195     public int setImsProvisioningString(int subId, int key, String value) {
4196         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
4197             throw new IllegalArgumentException("Invalid Subscription id '" + subId + "'");
4198         }
4199         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp, subId,
4200                 "setImsProvisioningString");
4201         final long identity = Binder.clearCallingIdentity();
4202         try {
4203             // TODO: Refactor to remove ImsManager dependence and query through ImsPhone directly.
4204             int slotId = getSlotIndex(subId);
4205             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
4206                 Log.w(LOG_TAG, "setImsProvisioningString: called with an inactive subscription id '"
4207                         + subId + "' for key:" + key);
4208                 return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4209             }
4210             return ImsManager.getInstance(mApp, slotId).getConfigInterface().setConfig(key, value);
4211         } catch (com.android.ims.ImsException e) {
4212             Log.w(LOG_TAG, "setImsProvisioningString: ImsService unavailable for sub '" + subId
4213                     + "' for key:" + key);
4214             return ImsConfigImplBase.CONFIG_RESULT_FAILED;
4215         } finally {
4216             Binder.restoreCallingIdentity(identity);
4217         }
4218     }
4219 
getSlotIndexOrException(int subId)4220     private int getSlotIndexOrException(int subId) throws ImsException {
4221         int slotId = SubscriptionManager.getSlotIndex(subId);
4222         if (!SubscriptionManager.isValidSlotIndex(slotId)) {
4223             throw new ImsException("Invalid Subscription Id, subId=" + subId,
4224                     ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
4225         }
4226         return slotId;
4227     }
4228 
getSlotIndex(int subId)4229     private int getSlotIndex(int subId) {
4230         int slotId = SubscriptionManager.getSlotIndex(subId);
4231         if (!SubscriptionManager.isValidSlotIndex(slotId)) {
4232             return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
4233         }
4234         return slotId;
4235     }
4236 
4237     /**
4238      * Returns the data network type for a subId; does not throw SecurityException.
4239      */
4240     @Override
getNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId)4241     public int getNetworkTypeForSubscriber(int subId, String callingPackage,
4242             String callingFeatureId) {
4243         final int targetSdk = getTargetSdk(callingPackage);
4244         if (targetSdk > android.os.Build.VERSION_CODES.Q) {
4245             return getDataNetworkTypeForSubscriber(subId, callingPackage, callingFeatureId);
4246         } else if (targetSdk == android.os.Build.VERSION_CODES.Q
4247                 && !TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
4248                         mApp, subId, callingPackage, callingFeatureId,
4249                 "getNetworkTypeForSubscriber")) {
4250             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4251         }
4252 
4253         final long identity = Binder.clearCallingIdentity();
4254         try {
4255             final Phone phone = getPhone(subId);
4256             if (phone != null) {
4257                 return phone.getServiceState().getDataNetworkType();
4258             } else {
4259                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4260             }
4261         } finally {
4262             Binder.restoreCallingIdentity(identity);
4263         }
4264     }
4265 
4266     /**
4267      * Returns the data network type
4268      */
4269     @Override
getDataNetworkType(String callingPackage, String callingFeatureId)4270     public int getDataNetworkType(String callingPackage, String callingFeatureId) {
4271         return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage,
4272                 callingFeatureId);
4273     }
4274 
4275     /**
4276      * Returns the data network type for a subId
4277      */
4278     @Override
getDataNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId)4279     public int getDataNetworkTypeForSubscriber(int subId, String callingPackage,
4280             String callingFeatureId) {
4281         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4282                 mApp, subId, callingPackage, callingFeatureId,
4283                 "getDataNetworkTypeForSubscriber")) {
4284             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4285         }
4286 
4287         final long identity = Binder.clearCallingIdentity();
4288         try {
4289             final Phone phone = getPhone(subId);
4290             if (phone != null) {
4291                 return phone.getServiceState().getDataNetworkType();
4292             } else {
4293                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4294             }
4295         } finally {
4296             Binder.restoreCallingIdentity(identity);
4297         }
4298     }
4299 
4300     /**
4301      * Returns the Voice network type for a subId
4302      */
4303     @Override
getVoiceNetworkTypeForSubscriber(int subId, String callingPackage, String callingFeatureId)4304     public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage,
4305             String callingFeatureId) {
4306         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4307                 mApp, subId, callingPackage, callingFeatureId,
4308                 "getDataNetworkTypeForSubscriber")) {
4309             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4310         }
4311 
4312         final long identity = Binder.clearCallingIdentity();
4313         try {
4314             final Phone phone = getPhone(subId);
4315             if (phone != null) {
4316                 return phone.getServiceState().getVoiceNetworkType();
4317             } else {
4318                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
4319             }
4320         } finally {
4321             Binder.restoreCallingIdentity(identity);
4322         }
4323     }
4324 
4325     /**
4326      * @return true if a ICC card is present
4327      */
hasIccCard()4328     public boolean hasIccCard() {
4329         // FIXME Make changes to pass defaultSimId of type int
4330         return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
4331                 getDefaultSubscription()));
4332     }
4333 
4334     /**
4335      * @return true if a ICC card is present for a slotIndex
4336      */
4337     @Override
hasIccCardUsingSlotIndex(int slotIndex)4338     public boolean hasIccCardUsingSlotIndex(int slotIndex) {
4339         final long identity = Binder.clearCallingIdentity();
4340         try {
4341             final Phone phone = PhoneFactory.getPhone(slotIndex);
4342             if (phone != null) {
4343                 return phone.getIccCard().hasIccCard();
4344             } else {
4345                 return false;
4346             }
4347         } finally {
4348             Binder.restoreCallingIdentity(identity);
4349         }
4350     }
4351 
4352     /**
4353      * Return if the current radio is LTE on CDMA. This
4354      * is a tri-state return value as for a period of time
4355      * the mode may be unknown.
4356      *
4357      * @param callingPackage the name of the package making the call.
4358      * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
4359      * or {@link Phone#LTE_ON_CDMA_TRUE}
4360      */
4361     @Override
getLteOnCdmaMode(String callingPackage, String callingFeatureId)4362     public int getLteOnCdmaMode(String callingPackage, String callingFeatureId) {
4363         return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage,
4364                 callingFeatureId);
4365     }
4366 
4367     @Override
getLteOnCdmaModeForSubscriber(int subId, String callingPackage, String callingFeatureId)4368     public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage,
4369             String callingFeatureId) {
4370         try {
4371             enforceReadPrivilegedPermission("getLteOnCdmaModeForSubscriber");
4372         } catch (SecurityException e) {
4373             return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
4374         }
4375 
4376         final long identity = Binder.clearCallingIdentity();
4377         try {
4378             final Phone phone = getPhone(subId);
4379             if (phone == null) {
4380                 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
4381             } else {
4382                 return phone.getLteOnCdmaMode();
4383             }
4384         } finally {
4385             Binder.restoreCallingIdentity(identity);
4386         }
4387     }
4388 
4389     /**
4390      * {@hide}
4391      * Returns Default subId, 0 in the case of single standby.
4392      */
getDefaultSubscription()4393     private int getDefaultSubscription() {
4394         return mSubscriptionController.getDefaultSubId();
4395     }
4396 
getSlotForDefaultSubscription()4397     private int getSlotForDefaultSubscription() {
4398         return mSubscriptionController.getPhoneId(getDefaultSubscription());
4399     }
4400 
getPreferredVoiceSubscription()4401     private int getPreferredVoiceSubscription() {
4402         return mSubscriptionController.getDefaultVoiceSubId();
4403     }
4404 
isActiveSubscription(int subId)4405     private boolean isActiveSubscription(int subId) {
4406         return mSubscriptionController.isActiveSubId(subId);
4407     }
4408 
4409     /**
4410      * @see android.telephony.TelephonyManager.WifiCallingChoices
4411      */
getWhenToMakeWifiCalls()4412     public int getWhenToMakeWifiCalls() {
4413         final long identity = Binder.clearCallingIdentity();
4414         try {
4415             return Settings.System.getInt(mApp.getContentResolver(),
4416                     Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
4417                     getWhenToMakeWifiCallsDefaultPreference());
4418         } finally {
4419             Binder.restoreCallingIdentity(identity);
4420         }
4421     }
4422 
4423     /**
4424      * @see android.telephony.TelephonyManager.WifiCallingChoices
4425      */
setWhenToMakeWifiCalls(int preference)4426     public void setWhenToMakeWifiCalls(int preference) {
4427         final long identity = Binder.clearCallingIdentity();
4428         try {
4429             if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
4430             Settings.System.putInt(mApp.getContentResolver(),
4431                     Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
4432         } finally {
4433             Binder.restoreCallingIdentity(identity);
4434         }
4435     }
4436 
getWhenToMakeWifiCallsDefaultPreference()4437     private static int getWhenToMakeWifiCallsDefaultPreference() {
4438         // TODO: Use a build property to choose this value.
4439         return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
4440     }
4441 
getPhoneFromSlotIdOrThrowException(int slotIndex)4442     private Phone getPhoneFromSlotIdOrThrowException(int slotIndex) {
4443         int phoneId = UiccController.getInstance().getPhoneIdFromSlotId(slotIndex);
4444         if (phoneId == -1) {
4445             throw new IllegalArgumentException("Given slot index: " + slotIndex
4446                     + " does not correspond to an active phone");
4447         }
4448         return PhoneFactory.getPhone(phoneId);
4449     }
4450 
4451     @Override
iccOpenLogicalChannel( int subId, String callingPackage, String aid, int p2)4452     public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
4453             int subId, String callingPackage, String aid, int p2) {
4454         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4455                 mApp, subId, "iccOpenLogicalChannel");
4456         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4457         if (DBG) {
4458             log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
4459         }
4460         return iccOpenLogicalChannelWithPermission(getPhoneFromSubId(subId), callingPackage, aid,
4461                 p2);
4462     }
4463 
4464 
4465     @Override
iccOpenLogicalChannelBySlot( int slotIndex, String callingPackage, String aid, int p2)4466     public IccOpenLogicalChannelResponse iccOpenLogicalChannelBySlot(
4467             int slotIndex, String callingPackage, String aid, int p2) {
4468         enforceModifyPermission();
4469         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4470         if (DBG) {
4471             log("iccOpenLogicalChannelBySlot: slot=" + slotIndex + " aid=" + aid + " p2=" + p2);
4472         }
4473         return iccOpenLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
4474                 callingPackage, aid, p2);
4475     }
4476 
iccOpenLogicalChannelWithPermission(Phone phone, String callingPackage, String aid, int p2)4477     private IccOpenLogicalChannelResponse iccOpenLogicalChannelWithPermission(Phone phone,
4478             String callingPackage, String aid, int p2) {
4479         final long identity = Binder.clearCallingIdentity();
4480         try {
4481             if (TextUtils.equals(ISDR_AID, aid)) {
4482                 // Only allows LPA to open logical channel to ISD-R.
4483                 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
4484                         .getContext().getPackageManager());
4485                 if (bestComponent == null
4486                         || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
4487                     loge("The calling package is not allowed to access ISD-R.");
4488                     throw new SecurityException(
4489                             "The calling package is not allowed to access ISD-R.");
4490                 }
4491             }
4492 
4493             IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
4494                     CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), phone,
4495                     null /* workSource */);
4496             if (DBG) log("iccOpenLogicalChannelWithPermission: " + response);
4497             return response;
4498         } finally {
4499             Binder.restoreCallingIdentity(identity);
4500         }
4501     }
4502 
4503     @Override
iccCloseLogicalChannel(int subId, int channel)4504     public boolean iccCloseLogicalChannel(int subId, int channel) {
4505         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4506                 mApp, subId, "iccCloseLogicalChannel");
4507         if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
4508         return iccCloseLogicalChannelWithPermission(getPhoneFromSubId(subId), channel);
4509     }
4510 
4511     @Override
iccCloseLogicalChannelBySlot(int slotIndex, int channel)4512     public boolean iccCloseLogicalChannelBySlot(int slotIndex, int channel) {
4513         enforceModifyPermission();
4514         if (DBG) log("iccCloseLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel);
4515         return iccCloseLogicalChannelWithPermission(getPhoneFromSlotIdOrThrowException(slotIndex),
4516                 channel);
4517     }
4518 
iccCloseLogicalChannelWithPermission(Phone phone, int channel)4519     private boolean iccCloseLogicalChannelWithPermission(Phone phone, int channel) {
4520         final long identity = Binder.clearCallingIdentity();
4521         try {
4522             if (channel < 0) {
4523                 return false;
4524             }
4525             Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, channel, phone,
4526                     null /* workSource */);
4527             if (DBG) log("iccCloseLogicalChannelWithPermission: " + success);
4528             return success;
4529         } finally {
4530             Binder.restoreCallingIdentity(identity);
4531         }
4532     }
4533 
4534     @Override
iccTransmitApduLogicalChannel(int subId, int channel, int cla, int command, int p1, int p2, int p3, String data)4535     public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
4536             int command, int p1, int p2, int p3, String data) {
4537         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4538                 mApp, subId, "iccTransmitApduLogicalChannel");
4539         if (DBG) {
4540             log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
4541                     + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
4542                     + p3 + " data=" + data);
4543         }
4544         return iccTransmitApduLogicalChannelWithPermission(getPhoneFromSubId(subId), channel, cla,
4545                 command, p1, p2, p3, data);
4546     }
4547 
4548     @Override
iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla, int command, int p1, int p2, int p3, String data)4549     public String iccTransmitApduLogicalChannelBySlot(int slotIndex, int channel, int cla,
4550             int command, int p1, int p2, int p3, String data) {
4551         enforceModifyPermission();
4552         if (DBG) {
4553             log("iccTransmitApduLogicalChannelBySlot: slotIndex=" + slotIndex + " chnl=" + channel
4554                     + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
4555                     + p3 + " data=" + data);
4556         }
4557         return iccTransmitApduLogicalChannelWithPermission(
4558                 getPhoneFromSlotIdOrThrowException(slotIndex), channel, cla, command, p1, p2, p3,
4559                 data);
4560     }
4561 
iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla, int command, int p1, int p2, int p3, String data)4562     private String iccTransmitApduLogicalChannelWithPermission(Phone phone, int channel, int cla,
4563             int command, int p1, int p2, int p3, String data) {
4564         final long identity = Binder.clearCallingIdentity();
4565         try {
4566             if (channel <= 0) {
4567                 return "";
4568             }
4569 
4570             IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
4571                     new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), phone,
4572                     null /* workSource */);
4573             if (DBG) log("iccTransmitApduLogicalChannelWithPermission: " + response);
4574 
4575             // Append the returned status code to the end of the response payload.
4576             String s = Integer.toHexString(
4577                     (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
4578             if (response.payload != null) {
4579                 s = IccUtils.bytesToHexString(response.payload) + s;
4580             }
4581             return s;
4582         } finally {
4583             Binder.restoreCallingIdentity(identity);
4584         }
4585     }
4586 
4587     @Override
iccTransmitApduBasicChannel(int subId, String callingPackage, int cla, int command, int p1, int p2, int p3, String data)4588     public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
4589             int command, int p1, int p2, int p3, String data) {
4590         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4591                 mApp, subId, "iccTransmitApduBasicChannel");
4592         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4593         if (DBG) {
4594             log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
4595                     + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
4596         }
4597         return iccTransmitApduBasicChannelWithPermission(getPhoneFromSubId(subId), callingPackage,
4598                 cla, command, p1, p2, p3, data);
4599     }
4600 
4601     @Override
iccTransmitApduBasicChannelBySlot(int slotIndex, String callingPackage, int cla, int command, int p1, int p2, int p3, String data)4602     public String iccTransmitApduBasicChannelBySlot(int slotIndex, String callingPackage, int cla,
4603             int command, int p1, int p2, int p3, String data) {
4604         enforceModifyPermission();
4605         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4606         if (DBG) {
4607             log("iccTransmitApduBasicChannelBySlot: slotIndex=" + slotIndex + " cla=" + cla
4608                     + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3
4609                     + " data=" + data);
4610         }
4611 
4612         return iccTransmitApduBasicChannelWithPermission(
4613                 getPhoneFromSlotIdOrThrowException(slotIndex), callingPackage, cla, command, p1,
4614                 p2, p3, data);
4615     }
4616 
4617     // 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)4618     private String iccTransmitApduBasicChannelWithPermission(Phone phone, String callingPackage,
4619             int cla, int command, int p1, int p2, int p3, String data) {
4620         final long identity = Binder.clearCallingIdentity();
4621         try {
4622             if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
4623                     && TextUtils.equals(ISDR_AID, data)) {
4624                 // Only allows LPA to select ISD-R.
4625                 ComponentInfo bestComponent = EuiccConnector.findBestComponent(getDefaultPhone()
4626                         .getContext().getPackageManager());
4627                 if (bestComponent == null
4628                         || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
4629                     loge("The calling package is not allowed to select ISD-R.");
4630                     throw new SecurityException(
4631                             "The calling package is not allowed to select ISD-R.");
4632                 }
4633             }
4634 
4635             IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
4636                     new IccAPDUArgument(0, cla, command, p1, p2, p3, data), phone,
4637                     null /* workSource */);
4638             if (DBG) log("iccTransmitApduBasicChannelWithPermission: " + response);
4639 
4640             // Append the returned status code to the end of the response payload.
4641             String s = Integer.toHexString(
4642                     (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
4643             if (response.payload != null) {
4644                 s = IccUtils.bytesToHexString(response.payload) + s;
4645             }
4646             return s;
4647         } finally {
4648             Binder.restoreCallingIdentity(identity);
4649         }
4650     }
4651 
4652     @Override
iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3, String filePath)4653     public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
4654             String filePath) {
4655         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4656                 mApp, subId, "iccExchangeSimIO");
4657 
4658         final long identity = Binder.clearCallingIdentity();
4659         try {
4660             if (DBG) {
4661                 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
4662                         + p1 + " " + p2 + " " + p3 + ":" + filePath);
4663             }
4664 
4665             IccIoResult response =
4666                     (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
4667                             new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
4668                             subId);
4669 
4670             if (DBG) {
4671                 log("Exchange SIM_IO [R]" + response);
4672             }
4673 
4674             byte[] result = null;
4675             int length = 2;
4676             if (response.payload != null) {
4677                 length = 2 + response.payload.length;
4678                 result = new byte[length];
4679                 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
4680             } else {
4681                 result = new byte[length];
4682             }
4683 
4684             result[length - 1] = (byte) response.sw2;
4685             result[length - 2] = (byte) response.sw1;
4686             return result;
4687         } finally {
4688             Binder.restoreCallingIdentity(identity);
4689         }
4690     }
4691 
4692     /**
4693      * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
4694      * on a particular subscription
4695      */
getForbiddenPlmns(int subId, int appType, String callingPackage, String callingFeatureId)4696     public String[] getForbiddenPlmns(int subId, int appType, String callingPackage,
4697             String callingFeatureId) {
4698         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4699                 mApp, subId, callingPackage, callingFeatureId, "getForbiddenPlmns")) {
4700             return null;
4701         }
4702 
4703         final long identity = Binder.clearCallingIdentity();
4704         try {
4705             if (appType != TelephonyManager.APPTYPE_USIM
4706                     && appType != TelephonyManager.APPTYPE_SIM) {
4707                 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
4708                 return null;
4709             }
4710             Object response = sendRequest(
4711                     CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
4712             if (response instanceof String[]) {
4713                 return (String[]) response;
4714             }
4715             // Response is an Exception of some kind
4716             // which is signalled to the user as a NULL retval
4717             return null;
4718         } finally {
4719             Binder.restoreCallingIdentity(identity);
4720         }
4721     }
4722 
4723     /**
4724      * Set the forbidden PLMN list from the given app type (ex APPTYPE_USIM) on a particular
4725      * subscription.
4726      *
4727      * @param subId the id of the subscription.
4728      * @param appType the uicc app type, must be USIM or SIM.
4729      * @param fplmns the Forbiden plmns list that needed to be written to the SIM.
4730      * @param callingPackage the op Package name.
4731      * @param callingFeatureId the feature in the package.
4732      * @return number of fplmns that is successfully written to the SIM.
4733      */
setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage, String callingFeatureId)4734     public int setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage,
4735             String callingFeatureId) {
4736         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
4737                 callingFeatureId, "setForbiddenPlmns")) {
4738             if (DBG) logv("no permissions for setForbiddenplmns");
4739             throw new IllegalStateException("No Permissions for setForbiddenPlmns");
4740         }
4741         if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
4742             loge("setForbiddenPlmnList(): App Type must be USIM or SIM");
4743             throw new IllegalArgumentException("Invalid appType: App Type must be USIM or SIM");
4744         }
4745         if (fplmns == null) {
4746             throw new IllegalArgumentException("Fplmn List provided is null");
4747         }
4748         for (String fplmn : fplmns) {
4749             if (!CellIdentity.isValidPlmn(fplmn)) {
4750                 throw new IllegalArgumentException("Invalid fplmn provided: " + fplmn);
4751             }
4752         }
4753         final long identity = Binder.clearCallingIdentity();
4754         try {
4755             Object response = sendRequest(
4756                     CMD_SET_FORBIDDEN_PLMNS,
4757                     new Pair<Integer, List<String>>(new Integer(appType), fplmns),
4758                     subId);
4759             return (int) response;
4760         } finally {
4761             Binder.restoreCallingIdentity(identity);
4762         }
4763     }
4764 
4765     @Override
sendEnvelopeWithStatus(int subId, String content)4766     public String sendEnvelopeWithStatus(int subId, String content) {
4767         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4768                 mApp, subId, "sendEnvelopeWithStatus");
4769 
4770         final long identity = Binder.clearCallingIdentity();
4771         try {
4772             IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
4773             if (response.payload == null) {
4774                 return "";
4775             }
4776 
4777             // Append the returned status code to the end of the response payload.
4778             String s = Integer.toHexString(
4779                     (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
4780             s = IccUtils.bytesToHexString(response.payload) + s;
4781             return s;
4782         } finally {
4783             Binder.restoreCallingIdentity(identity);
4784         }
4785     }
4786 
4787     /**
4788      * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
4789      * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
4790      *
4791      * @param itemID the ID of the item to read
4792      * @return the NV item as a String, or null on error.
4793      */
4794     @Override
nvReadItem(int itemID)4795     public String nvReadItem(int itemID) {
4796         WorkSource workSource = getWorkSource(Binder.getCallingUid());
4797         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4798                 mApp, getDefaultSubscription(), "nvReadItem");
4799 
4800         final long identity = Binder.clearCallingIdentity();
4801         try {
4802             if (DBG) log("nvReadItem: item " + itemID);
4803             String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID, workSource);
4804             if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
4805             return value;
4806         } finally {
4807             Binder.restoreCallingIdentity(identity);
4808         }
4809     }
4810 
4811     /**
4812      * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
4813      * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
4814      *
4815      * @param itemID the ID of the item to read
4816      * @param itemValue the value to write, as a String
4817      * @return true on success; false on any failure
4818      */
4819     @Override
nvWriteItem(int itemID, String itemValue)4820     public boolean nvWriteItem(int itemID, String itemValue) {
4821         WorkSource workSource = getWorkSource(Binder.getCallingUid());
4822         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4823                 mApp, getDefaultSubscription(), "nvWriteItem");
4824 
4825         final long identity = Binder.clearCallingIdentity();
4826         try {
4827             if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
4828             Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
4829                     new Pair<Integer, String>(itemID, itemValue), workSource);
4830             if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
4831             return success;
4832         } finally {
4833             Binder.restoreCallingIdentity(identity);
4834         }
4835     }
4836 
4837     /**
4838      * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
4839      * Used for device configuration by some CDMA operators.
4840      *
4841      * @param preferredRoamingList byte array containing the new PRL
4842      * @return true on success; false on any failure
4843      */
4844     @Override
nvWriteCdmaPrl(byte[] preferredRoamingList)4845     public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
4846         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4847                 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
4848 
4849         final long identity = Binder.clearCallingIdentity();
4850         try {
4851             if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
4852             Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
4853             if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
4854             return success;
4855         } finally {
4856             Binder.restoreCallingIdentity(identity);
4857         }
4858     }
4859 
4860     /**
4861      * Rollback modem configurations to factory default except some config which are in whitelist.
4862      * Used for device configuration by some CDMA operators.
4863      *
4864      * @param slotIndex - device slot.
4865      *
4866      * @return true on success; false on any failure
4867      */
4868     @Override
resetModemConfig(int slotIndex)4869     public boolean resetModemConfig(int slotIndex) {
4870         Phone phone = PhoneFactory.getPhone(slotIndex);
4871         if (phone != null) {
4872             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4873                     mApp, phone.getSubId(), "resetModemConfig");
4874 
4875             final long identity = Binder.clearCallingIdentity();
4876             try {
4877                 Boolean success = (Boolean) sendRequest(CMD_RESET_MODEM_CONFIG, null);
4878                 if (DBG) log("resetModemConfig:" + ' ' + (success ? "ok" : "fail"));
4879                 return success;
4880             } finally {
4881                 Binder.restoreCallingIdentity(identity);
4882             }
4883         }
4884         return false;
4885     }
4886 
4887     /**
4888      * Generate a radio modem reset. Used for device configuration by some CDMA operators.
4889      *
4890      * @param slotIndex - device slot.
4891      *
4892      * @return true on success; false on any failure
4893      */
4894     @Override
rebootModem(int slotIndex)4895     public boolean rebootModem(int slotIndex) {
4896         Phone phone = PhoneFactory.getPhone(slotIndex);
4897         if (phone != null) {
4898             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4899                     mApp, phone.getSubId(), "rebootModem");
4900 
4901             final long identity = Binder.clearCallingIdentity();
4902             try {
4903                 Boolean success = (Boolean) sendRequest(CMD_MODEM_REBOOT, null);
4904                 if (DBG) log("rebootModem:" + ' ' + (success ? "ok" : "fail"));
4905                 return success;
4906             } finally {
4907                 Binder.restoreCallingIdentity(identity);
4908             }
4909         }
4910         return false;
4911     }
4912 
getPcscfAddress(String apnType, String callingPackage, String callingFeatureId)4913     public String[] getPcscfAddress(String apnType, String callingPackage,
4914             String callingFeatureId) {
4915         final Phone defaultPhone = getDefaultPhone();
4916         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
4917                 callingPackage, callingFeatureId, "getPcscfAddress")) {
4918             return new String[0];
4919         }
4920 
4921         final long identity = Binder.clearCallingIdentity();
4922         try {
4923             return defaultPhone.getPcscfAddress(apnType);
4924         } finally {
4925             Binder.restoreCallingIdentity(identity);
4926         }
4927     }
4928 
4929     /**
4930      * Toggle IMS disable and enable for the framework to reset it. See {@link #enableIms(int)} and
4931      * {@link #disableIms(int)}.
4932      * @param slotIndex device slot.
4933      */
resetIms(int slotIndex)4934     public void resetIms(int slotIndex) {
4935         enforceModifyPermission();
4936 
4937         final long identity = Binder.clearCallingIdentity();
4938         try {
4939             if (mImsResolver == null) {
4940                 // may happen if the does not support IMS.
4941                 return;
4942             }
4943             mImsResolver.disableIms(slotIndex);
4944             mImsResolver.enableIms(slotIndex);
4945         } finally {
4946             Binder.restoreCallingIdentity(identity);
4947         }
4948     }
4949 
4950     /**
4951      * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
4952      * status updates, if not already enabled.
4953      */
enableIms(int slotId)4954     public void enableIms(int slotId) {
4955         enforceModifyPermission();
4956 
4957         final long identity = Binder.clearCallingIdentity();
4958         try {
4959             if (mImsResolver == null) {
4960                 // may happen if the device does not support IMS.
4961                 return;
4962             }
4963             mImsResolver.enableIms(slotId);
4964         } finally {
4965             Binder.restoreCallingIdentity(identity);
4966         }
4967     }
4968 
4969     /**
4970      * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
4971      * status updates to disabled.
4972      */
disableIms(int slotId)4973     public void disableIms(int slotId) {
4974         enforceModifyPermission();
4975 
4976         final long identity = Binder.clearCallingIdentity();
4977         try {
4978             if (mImsResolver == null) {
4979                 // may happen if the device does not support IMS.
4980                 return;
4981             }
4982             mImsResolver.disableIms(slotId);
4983         } finally {
4984             Binder.restoreCallingIdentity(identity);
4985         }
4986     }
4987 
4988     /**
4989      * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id for the MMTel
4990      * feature or {@link null} if the service is not available. If the feature is available, the
4991      * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
4992      */
getMmTelFeatureAndListen(int slotId, IImsServiceFeatureCallback callback)4993     public IImsMmTelFeature getMmTelFeatureAndListen(int slotId,
4994             IImsServiceFeatureCallback callback) {
4995         enforceModifyPermission();
4996 
4997         final long identity = Binder.clearCallingIdentity();
4998         try {
4999             if (mImsResolver == null) {
5000                 // may happen if the device does not support IMS.
5001                 return null;
5002             }
5003             return mImsResolver.getMmTelFeatureAndListen(slotId, callback);
5004         } finally {
5005             Binder.restoreCallingIdentity(identity);
5006         }
5007     }
5008 
5009     /**
5010      * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id for the RCS
5011      * feature during emergency calling or {@link null} if the service is not available. If the
5012      * feature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
5013      * listener for feature updates.
5014      */
getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback)5015     public IImsRcsFeature getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback) {
5016         enforceModifyPermission();
5017 
5018         final long identity = Binder.clearCallingIdentity();
5019         try {
5020             if (mImsResolver == null) {
5021                 // may happen if the device does not support IMS.
5022                 return null;
5023             }
5024             return mImsResolver.getRcsFeatureAndListen(slotId, callback);
5025         } finally {
5026             Binder.restoreCallingIdentity(identity);
5027         }
5028     }
5029 
5030     /**
5031      * Unregister a previously registered IImsServiceFeatureCallback associated with an ImsFeature.
5032      */
unregisterImsFeatureCallback(int slotId, int featureType, IImsServiceFeatureCallback callback)5033     public void unregisterImsFeatureCallback(int slotId, int featureType,
5034             IImsServiceFeatureCallback callback) {
5035         enforceModifyPermission();
5036 
5037         final long identity = Binder.clearCallingIdentity();
5038         try {
5039             if (mImsResolver == null) return;
5040             mImsResolver.unregisterImsFeatureCallback(slotId, featureType, callback);
5041         } finally {
5042             Binder.restoreCallingIdentity(identity);
5043         }
5044     }
5045 
5046     /**
5047      * Returns the {@link IImsRegistration} structure associated with the slotId and feature
5048      * specified or null if IMS is not supported on the slot specified.
5049      */
getImsRegistration(int slotId, int feature)5050     public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
5051         enforceModifyPermission();
5052 
5053         final long identity = Binder.clearCallingIdentity();
5054         try {
5055             if (mImsResolver == null) {
5056                 // may happen if the device does not support IMS.
5057                 return null;
5058             }
5059             return mImsResolver.getImsRegistration(slotId, feature);
5060         } finally {
5061             Binder.restoreCallingIdentity(identity);
5062         }
5063     }
5064 
5065     /**
5066      * Returns the {@link IImsConfig} structure associated with the slotId and feature
5067      * specified or null if IMS is not supported on the slot specified.
5068      */
getImsConfig(int slotId, int feature)5069     public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
5070         enforceModifyPermission();
5071 
5072         final long identity = Binder.clearCallingIdentity();
5073         try {
5074             if (mImsResolver == null) {
5075                 // may happen if the device does not support IMS.
5076                 return null;
5077             }
5078             return mImsResolver.getImsConfig(slotId, feature);
5079         } finally {
5080             Binder.restoreCallingIdentity(identity);
5081         }
5082     }
5083 
5084     /**
5085      * Sets the ImsService Package Name that Telephony will bind to.
5086      *
5087      * @param slotIndex the slot ID that the ImsService should bind for.
5088      * @param isCarrierService true if the ImsService is the carrier override, false if the
5089      *         ImsService is the device default ImsService.
5090      * @param featureTypes An integer array of feature types associated with a packageName.
5091      * @param packageName The name of the package that the current configuration will be replaced
5092      *                    with.
5093      * @return true if setting the ImsService to bind to succeeded, false if it did not.
5094      */
setBoundImsServiceOverride(int slotIndex, boolean isCarrierService, int[] featureTypes, String packageName)5095     public boolean setBoundImsServiceOverride(int slotIndex, boolean isCarrierService,
5096             int[] featureTypes, String packageName) {
5097         int[] subIds = SubscriptionManager.getSubId(slotIndex);
5098         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setBoundImsServiceOverride");
5099         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
5100                 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
5101                 "setBoundImsServiceOverride");
5102 
5103         final long identity = Binder.clearCallingIdentity();
5104         try {
5105             if (mImsResolver == null) {
5106                 // may happen if the device does not support IMS.
5107                 return false;
5108             }
5109             Map<Integer, String> featureConfig = new HashMap<>();
5110             for (int featureType : featureTypes) {
5111                 featureConfig.put(featureType, packageName);
5112             }
5113             return mImsResolver.overrideImsServiceConfiguration(slotIndex, isCarrierService,
5114                     featureConfig);
5115         } finally {
5116             Binder.restoreCallingIdentity(identity);
5117         }
5118     }
5119 
5120     /**
5121      * Return the package name of the currently bound ImsService.
5122      *
5123      * @param slotId The slot that the ImsService is associated with.
5124      * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
5125      *         the device default.
5126      * @param featureType The feature associated with the queried configuration.
5127      * @return the package name of the ImsService configuration.
5128      */
getBoundImsServicePackage(int slotId, boolean isCarrierImsService, @ImsFeature.FeatureType int featureType)5129     public String getBoundImsServicePackage(int slotId, boolean isCarrierImsService,
5130             @ImsFeature.FeatureType int featureType) {
5131         int[] subIds = SubscriptionManager.getSubId(slotId);
5132         TelephonyPermissions
5133                 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5134                 mApp, (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
5135                 "getBoundImsServicePackage");
5136 
5137         final long identity = Binder.clearCallingIdentity();
5138         try {
5139             if (mImsResolver == null) {
5140                 // may happen if the device does not support IMS.
5141                 return "";
5142             }
5143             // TODO: change API to query RCS separately.
5144             return mImsResolver.getImsServiceConfiguration(slotId, isCarrierImsService,
5145                     featureType);
5146         } finally {
5147             Binder.restoreCallingIdentity(identity);
5148         }
5149     }
5150 
5151     /**
5152      * Get the MmTelFeature state associated with the requested subscription id.
5153      * @param subId The subscription that the MmTelFeature is associated with.
5154      * @param callback A callback with an integer containing the
5155      * {@link android.telephony.ims.feature.ImsFeature.ImsState} associated with the MmTelFeature.
5156      */
5157     @Override
getImsMmTelFeatureState(int subId, IIntegerConsumer callback)5158     public void getImsMmTelFeatureState(int subId, IIntegerConsumer callback) {
5159         enforceReadPrivilegedPermission("getImsMmTelFeatureState");
5160         if (!ImsManager.isImsSupportedOnDevice(mApp)) {
5161             throw new ServiceSpecificException(ImsException.CODE_ERROR_UNSUPPORTED_OPERATION,
5162                     "IMS not available on device.");
5163         }
5164         final long token = Binder.clearCallingIdentity();
5165         try {
5166             int slotId = getSlotIndex(subId);
5167             if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
5168                 Log.w(LOG_TAG, "getImsMmTelFeatureState: called with an inactive subscription '"
5169                         + subId + "'");
5170                 throw new ServiceSpecificException(ImsException.CODE_ERROR_INVALID_SUBSCRIPTION);
5171             }
5172             ImsManager.getInstance(mApp, slotId).getImsServiceState(anInteger -> {
5173                 try {
5174                     callback.accept(anInteger == null ? ImsFeature.STATE_UNAVAILABLE : anInteger);
5175                 } catch (RemoteException e) {
5176                     Log.w(LOG_TAG, "getImsMmTelFeatureState: remote caller is no longer running. "
5177                             + "Ignore");
5178                 }
5179             });
5180         } finally {
5181             Binder.restoreCallingIdentity(token);
5182         }
5183     }
5184 
setImsRegistrationState(boolean registered)5185     public void setImsRegistrationState(boolean registered) {
5186         enforceModifyPermission();
5187 
5188         final long identity = Binder.clearCallingIdentity();
5189         try {
5190             getDefaultPhone().setImsRegistrationState(registered);
5191         } finally {
5192             Binder.restoreCallingIdentity(identity);
5193         }
5194     }
5195 
5196     /**
5197      * Set the network selection mode to automatic.
5198      *
5199      */
5200     @Override
setNetworkSelectionModeAutomatic(int subId)5201     public void setNetworkSelectionModeAutomatic(int subId) {
5202         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5203                 mApp, subId, "setNetworkSelectionModeAutomatic");
5204 
5205         final long identity = Binder.clearCallingIdentity();
5206         try {
5207             if (!isActiveSubscription(subId)) {
5208                 return;
5209             }
5210             if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
5211             sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
5212         } finally {
5213             Binder.restoreCallingIdentity(identity);
5214         }
5215     }
5216 
5217    /**
5218      * Ask the radio to connect to the input network and change selection mode to manual.
5219      *
5220      * @param subId the id of the subscription.
5221      * @param operatorInfo the operator information, included the PLMN, long name and short name of
5222      * the operator to attach to.
5223      * @param persistSelection whether the selection will persist until reboot. If true, only allows
5224      * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
5225      * normal network selection next time.
5226      * @return {@code true} on success; {@code true} on any failure.
5227      */
5228     @Override
setNetworkSelectionModeManual( int subId, OperatorInfo operatorInfo, boolean persistSelection)5229     public boolean setNetworkSelectionModeManual(
5230             int subId, OperatorInfo operatorInfo, boolean persistSelection) {
5231         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5232                 mApp, subId, "setNetworkSelectionModeManual");
5233 
5234         if (!isActiveSubscription(subId)) {
5235             return false;
5236         }
5237 
5238         final long identity = Binder.clearCallingIdentity();
5239         try {
5240             ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operatorInfo,
5241                     persistSelection);
5242             if (DBG) {
5243                 log("setNetworkSelectionModeManual: subId: " + subId
5244                         + " operator: " + operatorInfo);
5245             }
5246             return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
5247         } finally {
5248             Binder.restoreCallingIdentity(identity);
5249         }
5250     }
5251      /**
5252      * Get the manual network selection
5253      *
5254      * @param subId the id of the subscription.
5255      *
5256      * @return the previously saved user selected PLMN
5257      */
5258     @Override
getManualNetworkSelectionPlmn(int subId)5259     public String getManualNetworkSelectionPlmn(int subId) {
5260         TelephonyPermissions
5261                     .enforeceCallingOrSelfReadPrecisePhoneStatePermissionOrCarrierPrivilege(
5262                     mApp, subId, "getManualNetworkSelectionPlmn");
5263 
5264         final long identity = Binder.clearCallingIdentity();
5265         try {
5266             if (!isActiveSubscription(subId)) {
5267                 return "";
5268             }
5269 
5270             final Phone phone = getPhone(subId);
5271             if (phone == null) {
5272                 return "";
5273             }
5274             OperatorInfo networkSelection = phone.getSavedNetworkSelection();
5275             return TextUtils.isEmpty(networkSelection.getOperatorNumeric())
5276                 ? phone.getManualNetworkSelectionPlmn() : networkSelection.getOperatorNumeric();
5277         } finally {
5278             Binder.restoreCallingIdentity(identity);
5279         }
5280     }
5281 
5282     /**
5283      * Scans for available networks.
5284      */
5285     @Override
getCellNetworkScanResults(int subId, String callingPackage, String callingFeatureId)5286     public CellNetworkScanResult getCellNetworkScanResults(int subId, String callingPackage,
5287             String callingFeatureId) {
5288         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5289                 mApp, subId, "getCellNetworkScanResults");
5290         LocationAccessPolicy.LocationPermissionResult locationResult =
5291                 LocationAccessPolicy.checkLocationPermission(mApp,
5292                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
5293                                 .setCallingPackage(callingPackage)
5294                                 .setCallingFeatureId(callingFeatureId)
5295                                 .setCallingPid(Binder.getCallingPid())
5296                                 .setCallingUid(Binder.getCallingUid())
5297                                 .setMethod("getCellNetworkScanResults")
5298                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
5299                                 .build());
5300         switch (locationResult) {
5301             case DENIED_HARD:
5302                 throw new SecurityException("Not allowed to access scan results -- location");
5303             case DENIED_SOFT:
5304                 return null;
5305         }
5306 
5307         long identity = Binder.clearCallingIdentity();
5308         try {
5309             if (DBG) log("getCellNetworkScanResults: subId " + subId);
5310             return (CellNetworkScanResult) sendRequest(
5311                     CMD_PERFORM_NETWORK_SCAN, null, subId);
5312         } finally {
5313             Binder.restoreCallingIdentity(identity);
5314         }
5315     }
5316 
5317     /**
5318      * Get the call forwarding info, given the call forwarding reason.
5319      */
5320     @Override
getCallForwarding(int subId, int callForwardingReason)5321     public CallForwardingInfo getCallForwarding(int subId, int callForwardingReason) {
5322         enforceReadPrivilegedPermission("getCallForwarding");
5323         long identity = Binder.clearCallingIdentity();
5324         try {
5325             if (DBG) {
5326                 log("getCallForwarding: subId " + subId
5327                         + " callForwardingReason" + callForwardingReason);
5328             }
5329             return (CallForwardingInfo) sendRequest(
5330                     CMD_GET_CALL_FORWARDING, callForwardingReason, subId);
5331         } finally {
5332             Binder.restoreCallingIdentity(identity);
5333         }
5334     }
5335 
5336     /**
5337      * Sets the voice call forwarding info including status (enable/disable), call forwarding
5338      * reason, the number to forward, and the timeout before the forwarding is attempted.
5339      */
5340     @Override
setCallForwarding(int subId, CallForwardingInfo callForwardingInfo)5341     public boolean setCallForwarding(int subId, CallForwardingInfo callForwardingInfo) {
5342         enforceModifyPermission();
5343         long identity = Binder.clearCallingIdentity();
5344         try {
5345             if (DBG) {
5346                 log("setCallForwarding: subId " + subId
5347                         + " callForwardingInfo" + callForwardingInfo);
5348             }
5349             return (Boolean) sendRequest(CMD_SET_CALL_FORWARDING, callForwardingInfo, subId);
5350         } finally {
5351             Binder.restoreCallingIdentity(identity);
5352         }
5353     }
5354 
5355     /**
5356      * Get the call forwarding info, given the call forwarding reason.
5357      */
5358     @Override
getCallWaitingStatus(int subId)5359     public int getCallWaitingStatus(int subId) {
5360         enforceReadPrivilegedPermission("getCallForwarding");
5361         long identity = Binder.clearCallingIdentity();
5362         try {
5363             if (DBG) log("getCallWaitingStatus: subId " + subId);
5364             return (Integer) sendRequest(CMD_GET_CALL_WAITING, null, subId);
5365         } finally {
5366             Binder.restoreCallingIdentity(identity);
5367         }
5368     }
5369 
5370     /**
5371      * Sets the voice call forwarding info including status (enable/disable), call forwarding
5372      * reason, the number to forward, and the timeout before the forwarding is attempted.
5373      */
5374     @Override
setCallWaitingStatus(int subId, boolean isEnable)5375     public boolean setCallWaitingStatus(int subId, boolean isEnable) {
5376         enforceModifyPermission();
5377         long identity = Binder.clearCallingIdentity();
5378         try {
5379             if (DBG) log("setCallWaitingStatus: subId " + subId + " isEnable: " + isEnable);
5380             return (Boolean) sendRequest(CMD_SET_CALL_WAITING, isEnable, subId);
5381         } finally {
5382             Binder.restoreCallingIdentity(identity);
5383         }
5384     }
5385 
5386     /**
5387      * Starts a new network scan and returns the id of this scan.
5388      *
5389      * @param subId id of the subscription
5390      * @param request contains the radio access networks with bands/channels to scan
5391      * @param messenger callback messenger for scan results or errors
5392      * @param binder for the purpose of auto clean when the user thread crashes
5393      * @return the id of the requested scan which can be used to stop the scan.
5394      */
5395     @Override
requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger, IBinder binder, String callingPackage, String callingFeatureId)5396     public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
5397             IBinder binder, String callingPackage, String callingFeatureId) {
5398         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5399                 mApp, subId, "requestNetworkScan");
5400         LocationAccessPolicy.LocationPermissionResult locationResult =
5401                 LocationAccessPolicy.checkLocationPermission(mApp,
5402                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
5403                                 .setCallingPackage(callingPackage)
5404                                 .setCallingFeatureId(callingFeatureId)
5405                                 .setCallingPid(Binder.getCallingPid())
5406                                 .setCallingUid(Binder.getCallingUid())
5407                                 .setMethod("requestNetworkScan")
5408                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
5409                                 .build());
5410         if (locationResult != LocationAccessPolicy.LocationPermissionResult.ALLOWED) {
5411             SecurityException e = checkNetworkRequestForSanitizedLocationAccess(
5412                     request, subId, callingPackage);
5413             if (e != null) {
5414                 if (locationResult == LocationAccessPolicy.LocationPermissionResult.DENIED_HARD) {
5415                     throw e;
5416                 } else {
5417                     loge(e.getMessage());
5418                     return TelephonyScanManager.INVALID_SCAN_ID;
5419                 }
5420             }
5421         }
5422         int callingUid = Binder.getCallingUid();
5423         int callingPid = Binder.getCallingPid();
5424         final long identity = Binder.clearCallingIdentity();
5425         try {
5426             return mNetworkScanRequestTracker.startNetworkScan(
5427                     request, messenger, binder, getPhone(subId),
5428                     callingUid, callingPid, callingPackage);
5429         } finally {
5430             Binder.restoreCallingIdentity(identity);
5431         }
5432     }
5433 
checkNetworkRequestForSanitizedLocationAccess( NetworkScanRequest request, int subId, String callingPackage)5434     private SecurityException checkNetworkRequestForSanitizedLocationAccess(
5435             NetworkScanRequest request, int subId, String callingPackage) {
5436         boolean hasCarrierPriv = checkCarrierPrivilegesForPackage(subId, callingPackage)
5437                 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
5438         boolean hasNetworkScanPermission =
5439                 mApp.checkCallingOrSelfPermission(android.Manifest.permission.NETWORK_SCAN)
5440                 == PERMISSION_GRANTED;
5441 
5442         if (!hasCarrierPriv && !hasNetworkScanPermission) {
5443             return new SecurityException("permission.NETWORK_SCAN or carrier privileges is needed"
5444                     + " for network scans without location access.");
5445         }
5446 
5447         if (request.getSpecifiers() != null && request.getSpecifiers().length > 0) {
5448             for (RadioAccessSpecifier ras : request.getSpecifiers()) {
5449                 if (ras.getChannels() != null && ras.getChannels().length > 0) {
5450                     return new SecurityException("Specific channels must not be"
5451                             + " scanned without location access.");
5452                 }
5453             }
5454         }
5455 
5456         return null;
5457     }
5458 
5459     /**
5460      * Stops an existing network scan with the given scanId.
5461      *
5462      * @param subId id of the subscription
5463      * @param scanId id of the scan that needs to be stopped
5464      */
5465     @Override
stopNetworkScan(int subId, int scanId)5466     public void stopNetworkScan(int subId, int scanId) {
5467         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5468                 mApp, subId, "stopNetworkScan");
5469 
5470         int callingUid = Binder.getCallingUid();
5471         final long identity = Binder.clearCallingIdentity();
5472         try {
5473             mNetworkScanRequestTracker.stopNetworkScan(scanId, callingUid);
5474         } finally {
5475             Binder.restoreCallingIdentity(identity);
5476         }
5477     }
5478 
5479     /**
5480      * Get the calculated preferred network type.
5481      * Used for debugging incorrect network type.
5482      *
5483      * @return the preferred network type, defined in RILConstants.java.
5484      */
5485     @Override
getCalculatedPreferredNetworkType(String callingPackage, String callingFeatureId)5486     public int getCalculatedPreferredNetworkType(String callingPackage, String callingFeatureId) {
5487         final Phone defaultPhone = getDefaultPhone();
5488         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
5489                 callingPackage, callingFeatureId, "getCalculatedPreferredNetworkType")) {
5490             return RILConstants.PREFERRED_NETWORK_MODE;
5491         }
5492 
5493         final long identity = Binder.clearCallingIdentity();
5494         try {
5495             // FIXME: need to get SubId from somewhere.
5496             return PhoneFactory.calculatePreferredNetworkType(defaultPhone.getContext(), 0);
5497         } finally {
5498             Binder.restoreCallingIdentity(identity);
5499         }
5500     }
5501 
5502     /**
5503      * Get the preferred network type.
5504      * Used for device configuration by some CDMA operators.
5505      *
5506      * @return the preferred network type, defined in RILConstants.java.
5507      */
5508     @Override
getPreferredNetworkType(int subId)5509     public int getPreferredNetworkType(int subId) {
5510         TelephonyPermissions
5511                 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5512                         mApp, subId, "getPreferredNetworkType");
5513 
5514         final long identity = Binder.clearCallingIdentity();
5515         try {
5516             if (DBG) log("getPreferredNetworkType");
5517             int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
5518             int networkType = (result != null ? result[0] : -1);
5519             if (DBG) log("getPreferredNetworkType: " + networkType);
5520             return networkType;
5521         } finally {
5522             Binder.restoreCallingIdentity(identity);
5523         }
5524     }
5525 
5526     /**
5527      * Set the preferred network type.
5528      *
5529      * @param networkType the preferred network type, defined in RILConstants.java.
5530      * @return true on success; false on any failure.
5531      */
5532     @Override
setPreferredNetworkType(int subId, int networkType)5533     public boolean setPreferredNetworkType(int subId, int networkType) {
5534         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5535                 mApp, subId, "setPreferredNetworkType");
5536 
5537         final long identity = Binder.clearCallingIdentity();
5538         try {
5539             Boolean success = (Boolean) sendRequest(
5540                     CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
5541 
5542             if (success) {
5543                 Settings.Global.putInt(mApp.getContentResolver(),
5544                         Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
5545             }
5546             if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
5547             return success;
5548         } finally {
5549             Binder.restoreCallingIdentity(identity);
5550         }
5551     }
5552 
5553     /**
5554      * Get the allowed network types that store in the telephony provider.
5555      *
5556      * @param subId the id of the subscription.
5557      * @return allowedNetworkTypes the allowed network types.
5558      */
5559     @Override
getAllowedNetworkTypes(int subId)5560     public long getAllowedNetworkTypes(int subId) {
5561         TelephonyPermissions
5562                 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5563                     mApp, subId, "getAllowedNetworkTypes");
5564 
5565         final long identity = Binder.clearCallingIdentity();
5566         try {
5567             return SubscriptionManager.getLongSubscriptionProperty(
5568                     subId, SubscriptionManager.ALLOWED_NETWORK_TYPES, -1, mApp);
5569         } finally {
5570             Binder.restoreCallingIdentity(identity);
5571         }
5572     }
5573 
5574     /**
5575      * Set the allowed network types.
5576      *
5577      * @param subId the id of the subscription.
5578      * @param allowedNetworkTypes the allowed network types.
5579      * @return true on success; false on any failure.
5580      */
5581     @Override
setAllowedNetworkTypes(int subId, long allowedNetworkTypes)5582     public boolean setAllowedNetworkTypes(int subId, long allowedNetworkTypes) {
5583         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5584                 mApp, subId, "setAllowedNetworkTypes");
5585 
5586         SubscriptionManager.setSubscriptionProperty(subId,
5587                 SubscriptionManager.ALLOWED_NETWORK_TYPES,
5588                 String.valueOf(allowedNetworkTypes));
5589 
5590         int preferredNetworkMode = Settings.Global.getInt(mApp.getContentResolver(),
5591                 Settings.Global.PREFERRED_NETWORK_MODE + subId,
5592                 RILConstants.PREFERRED_NETWORK_MODE);
5593         return setPreferredNetworkType(subId, preferredNetworkMode);
5594     }
5595 
5596     /**
5597      * Get the allowed network types for certain reason.
5598      *
5599      * @param subId the id of the subscription.
5600      * @param reason the reason the allowed network type change is taking place
5601      * @return the allowed network types.
5602      */
5603     @Override
getAllowedNetworkTypesForReason(int subId, @TelephonyManager.AllowedNetworkTypesReason int reason)5604     public long getAllowedNetworkTypesForReason(int subId,
5605             @TelephonyManager.AllowedNetworkTypesReason int reason) {
5606         TelephonyPermissions
5607                 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5608                         mApp, subId, "getAllowedNetworkTypesForReason");
5609         final long identity = Binder.clearCallingIdentity();
5610         try {
5611             return getPhoneFromSubId(subId).getAllowedNetworkTypes(reason);
5612         } finally {
5613             Binder.restoreCallingIdentity(identity);
5614         }
5615     }
5616 
5617     /**
5618      * Get the effective allowed network types on the device.
5619      * This API will return an intersection of allowed network types for all reasons,
5620      * including the configuration done through setAllowedNetworkTypes
5621      *
5622      * @param subId the id of the subscription.
5623      * @return the allowed network types
5624      */
5625     @Override
getEffectiveAllowedNetworkTypes(int subId)5626     public long getEffectiveAllowedNetworkTypes(int subId) {
5627         TelephonyPermissions
5628                 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
5629                         mApp, subId, "getEffectiveAllowedNetworkTypes");
5630         final long identity = Binder.clearCallingIdentity();
5631         try {
5632             return getPhoneFromSubId(subId).getEffectiveAllowedNetworkTypes();
5633         } finally {
5634             Binder.restoreCallingIdentity(identity);
5635         }
5636     }
5637 
5638     /**
5639      * Set the allowed network types of the device and
5640      * provide the reason triggering the allowed network change.
5641      *
5642      * @param subId the id of the subscription.
5643      * @param reason the reason the allowed network type change is taking place
5644      * @param allowedNetworkTypes the allowed network types.
5645      * @return true on success; false on any failure.
5646      */
5647     @Override
setAllowedNetworkTypesForReason(int subId, @TelephonyManager.AllowedNetworkTypesReason int reason, long allowedNetworkTypes)5648     public boolean setAllowedNetworkTypesForReason(int subId,
5649             @TelephonyManager.AllowedNetworkTypesReason int reason, long allowedNetworkTypes) {
5650         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5651                 mApp, subId, "setAllowedNetworkTypesForReason");
5652         final long identity = Binder.clearCallingIdentity();
5653         try {
5654             getPhoneFromSubId(subId).setAllowedNetworkTypes(reason, allowedNetworkTypes);
5655             int preferredNetworkMode = Settings.Global.getInt(mApp.getContentResolver(),
5656                     Settings.Global.PREFERRED_NETWORK_MODE + subId,
5657                     RILConstants.PREFERRED_NETWORK_MODE);
5658             return setPreferredNetworkType(subId, preferredNetworkMode);
5659         } finally {
5660             Binder.restoreCallingIdentity(identity);
5661         }
5662     }
5663 
5664     /**
5665      * Check whether DUN APN is required for tethering with subId.
5666      *
5667      * @param subId the id of the subscription to require tethering.
5668      * @return {@code true} if DUN APN is required for tethering.
5669      * @hide
5670      */
5671     @Override
isTetheringApnRequiredForSubscriber(int subId)5672     public boolean isTetheringApnRequiredForSubscriber(int subId) {
5673         enforceModifyPermission();
5674         final long identity = Binder.clearCallingIdentity();
5675         final Phone phone = getPhone(subId);
5676         try {
5677             if (phone != null) {
5678                 return phone.hasMatchedTetherApnSetting();
5679             } else {
5680                 return false;
5681             }
5682         } finally {
5683             Binder.restoreCallingIdentity(identity);
5684         }
5685     }
5686 
5687     /**
5688      * Set mobile data enabled
5689      * Used by the user through settings etc to turn on/off mobile data
5690      *
5691      * @param enable {@code true} turn turn data on, else {@code false}
5692      */
5693     @Override
setUserDataEnabled(int subId, boolean enable)5694     public void setUserDataEnabled(int subId, boolean enable) {
5695         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5696                 mApp, subId, "setUserDataEnabled");
5697 
5698         final long identity = Binder.clearCallingIdentity();
5699         try {
5700             int phoneId = mSubscriptionController.getPhoneId(subId);
5701             if (DBG) log("setUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
5702             Phone phone = PhoneFactory.getPhone(phoneId);
5703             if (phone != null) {
5704                 if (DBG) log("setUserDataEnabled: subId=" + subId + " enable=" + enable);
5705                 phone.getDataEnabledSettings().setUserDataEnabled(enable);
5706             } else {
5707                 loge("setUserDataEnabled: no phone found. Invalid subId=" + subId);
5708             }
5709         } finally {
5710             Binder.restoreCallingIdentity(identity);
5711         }
5712     }
5713 
5714     /**
5715      * Enable or disable always reporting signal strength changes from radio.
5716      *
5717      * @param isEnable {@code true} for enabling; {@code false} for disabling.
5718      */
5719     @Override
setAlwaysReportSignalStrength(int subId, boolean isEnable)5720     public void setAlwaysReportSignalStrength(int subId, boolean isEnable) {
5721         enforceModifyPermission();
5722         enforceSystemCaller();
5723 
5724         final long identity = Binder.clearCallingIdentity();
5725         final Phone phone = getPhone(subId);
5726         try {
5727             if (phone != null) {
5728                 if (DBG) {
5729                     log("setAlwaysReportSignalStrength: subId=" + subId
5730                             + " isEnable=" + isEnable);
5731                 }
5732                 phone.setAlwaysReportSignalStrength(isEnable);
5733             } else {
5734                 loge("setAlwaysReportSignalStrength: no phone found for subId="
5735                         + subId);
5736             }
5737         } finally {
5738             Binder.restoreCallingIdentity(identity);
5739         }
5740     }
5741 
5742     /**
5743      * Get the user enabled state of Mobile Data.
5744      *
5745      * TODO: remove and use isUserDataEnabled.
5746      * This can't be removed now because some vendor codes
5747      * calls through ITelephony directly while they should
5748      * use TelephonyManager.
5749      *
5750      * @return true on enabled
5751      */
5752     @Override
getDataEnabled(int subId)5753     public boolean getDataEnabled(int subId) {
5754         return isUserDataEnabled(subId);
5755     }
5756 
5757     /**
5758      * Get whether mobile data is enabled per user setting.
5759      *
5760      * There are other factors deciding whether mobile data is actually enabled, but they are
5761      * not considered here. See {@link #isDataEnabled(int)} for more details.
5762      *
5763      * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
5764      *
5765      * @return {@code true} if data is enabled else {@code false}
5766      */
5767     @Override
isUserDataEnabled(int subId)5768     public boolean isUserDataEnabled(int subId) {
5769         try {
5770             mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
5771                     null);
5772         } catch (Exception e) {
5773             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
5774                     mApp, subId, "isUserDataEnabled");
5775         }
5776 
5777         final long identity = Binder.clearCallingIdentity();
5778         try {
5779             int phoneId = mSubscriptionController.getPhoneId(subId);
5780             if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
5781             Phone phone = PhoneFactory.getPhone(phoneId);
5782             if (phone != null) {
5783                 boolean retVal = phone.isUserDataEnabled();
5784                 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
5785                 return retVal;
5786             } else {
5787                 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
5788                 return false;
5789             }
5790         } finally {
5791             Binder.restoreCallingIdentity(identity);
5792         }
5793     }
5794 
5795     /**
5796      * Checks if the device is capable of mobile data by considering whether whether the
5797      * user has enabled mobile data, whether the carrier has enabled mobile data, and
5798      * whether the network policy allows data connections.
5799      *
5800      * @return {@code true} if the overall data connection is capable; {@code false} if not.
5801      */
5802     @Override
isDataEnabled(int subId)5803     public boolean isDataEnabled(int subId) {
5804         enforceReadPrivilegedPermission("isDataEnabled");
5805 
5806         final long identity = Binder.clearCallingIdentity();
5807         try {
5808             int phoneId = mSubscriptionController.getPhoneId(subId);
5809             if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
5810             Phone phone = PhoneFactory.getPhone(phoneId);
5811             if (phone != null) {
5812                 boolean retVal = phone.getDataEnabledSettings().isDataEnabled();
5813                 if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
5814                 return retVal;
5815             } else {
5816                 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
5817                 return false;
5818             }
5819         } finally {
5820             Binder.restoreCallingIdentity(identity);
5821         }
5822     }
5823 
getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, int uid, Phone phone)5824     private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, int uid,
5825             Phone phone) {
5826         if (uid == Process.PHONE_UID) {
5827             // Skip the check if it's the phone UID (system UID removed in b/184713596)
5828             // TODO (b/184954344): Check for system/phone UID at call site instead of here
5829             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
5830         }
5831 
5832         //load access rules from carrier configs, and check those as well: b/139133814
5833         SubscriptionController subController = SubscriptionController.getInstance();
5834         if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
5835                 || subController == null) return privilegeFromSim;
5836 
5837         PackageManager pkgMgr = phone.getContext().getPackageManager();
5838         String[] packages = pkgMgr.getPackagesForUid(uid);
5839 
5840         final long identity = Binder.clearCallingIdentity();
5841         try {
5842             SubscriptionInfo subInfo = subController.getSubscriptionInfo(phone.getSubId());
5843             SubscriptionManager subManager = (SubscriptionManager)
5844                     phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
5845             for (String pkg : packages) {
5846                 if (subManager.canManageSubscription(subInfo, pkg)) {
5847                     return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
5848                 }
5849             }
5850             return privilegeFromSim;
5851         } finally {
5852             Binder.restoreCallingIdentity(identity);
5853         }
5854     }
5855 
getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, Phone phone, String pkgName)5856     private int getCarrierPrivilegeStatusFromCarrierConfigRules(int privilegeFromSim, Phone phone,
5857             String pkgName) {
5858         //load access rules from carrier configs, and check those as well: b/139133814
5859         SubscriptionController subController = SubscriptionController.getInstance();
5860         if (privilegeFromSim == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
5861                 || subController == null) return privilegeFromSim;
5862 
5863         final long identity = Binder.clearCallingIdentity();
5864         try {
5865             SubscriptionInfo subInfo = subController.getSubscriptionInfo(phone.getSubId());
5866             SubscriptionManager subManager = (SubscriptionManager)
5867                     phone.getContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
5868             return subManager.canManageSubscription(subInfo, pkgName)
5869                 ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS : privilegeFromSim;
5870         } finally {
5871             Binder.restoreCallingIdentity(identity);
5872         }
5873     }
5874 
5875     @Override
getCarrierPrivilegeStatus(int subId)5876     public int getCarrierPrivilegeStatus(int subId) {
5877         final Phone phone = getPhone(subId);
5878         if (phone == null) {
5879             loge("getCarrierPrivilegeStatus: Invalid subId");
5880             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
5881         }
5882         UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
5883         if (card == null) {
5884             loge("getCarrierPrivilegeStatus: No UICC");
5885             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
5886         }
5887 
5888         return getCarrierPrivilegeStatusFromCarrierConfigRules(
5889             card.getCarrierPrivilegeStatusForCurrentTransaction(
5890                 phone.getContext().getPackageManager()), Binder.getCallingUid(), phone);
5891     }
5892 
5893     @Override
getCarrierPrivilegeStatusForUid(int subId, int uid)5894     public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
5895         enforceReadPrivilegedPermission("getCarrierPrivilegeStatusForUid");
5896         final Phone phone = getPhone(subId);
5897         if (phone == null) {
5898             loge("getCarrierPrivilegeStatusForUid: Invalid subId");
5899             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
5900         }
5901         UiccProfile profile =
5902                 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
5903         if (profile == null) {
5904             loge("getCarrierPrivilegeStatusForUid: No UICC");
5905             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
5906         }
5907         return getCarrierPrivilegeStatusFromCarrierConfigRules(
5908                 profile.getCarrierPrivilegeStatusForUid(
5909                         phone.getContext().getPackageManager(), uid), uid, phone);
5910     }
5911 
5912     @Override
checkCarrierPrivilegesForPackage(int subId, String pkgName)5913     public int checkCarrierPrivilegesForPackage(int subId, String pkgName) {
5914         if (TextUtils.isEmpty(pkgName)) {
5915             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
5916         }
5917 
5918         int phoneId = SubscriptionManager.getPhoneId(subId);
5919         UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
5920         if (card == null) {
5921             loge("checkCarrierPrivilegesForPackage: No UICC on subId " + subId);
5922             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
5923         }
5924         return getCarrierPrivilegeStatusFromCarrierConfigRules(
5925             card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
5926             getPhone(phoneId), pkgName);
5927     }
5928 
5929     @Override
checkCarrierPrivilegesForPackageAnyPhone(String pkgName)5930     public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
5931         if (TextUtils.isEmpty(pkgName))
5932             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
5933         int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
5934         for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
5935             UiccCard card = UiccController.getInstance().getUiccCard(i);
5936             if (card == null) {
5937               // No UICC in that slot.
5938               continue;
5939             }
5940 
5941             result = getCarrierPrivilegeStatusFromCarrierConfigRules(
5942                 card.getCarrierPrivilegeStatus(mApp.getPackageManager(), pkgName),
5943                 getPhone(i), pkgName);
5944             if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
5945                 break;
5946             }
5947         }
5948 
5949         return result;
5950     }
5951 
5952     @Override
getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId)5953     public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
5954         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
5955             loge("phoneId " + phoneId + " is not valid.");
5956             return null;
5957         }
5958         UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
5959         if (card == null) {
5960             loge("getCarrierPackageNamesForIntentAndPhone: No UICC");
5961             return null ;
5962         }
5963         return card.getCarrierPackageNamesForIntent(mApp.getPackageManager(), intent);
5964     }
5965 
5966     @Override
getPackagesWithCarrierPrivileges(int phoneId)5967     public List<String> getPackagesWithCarrierPrivileges(int phoneId) {
5968         PackageManager pm = mApp.getPackageManager();
5969         List<String> privilegedPackages = new ArrayList<>();
5970         List<PackageInfo> packages = null;
5971         UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
5972         // has UICC in that slot.
5973         if (card != null) {
5974             if (card.hasCarrierPrivilegeRules()) {
5975                 if (packages == null) {
5976                     // Only check packages in user 0 for now
5977                     packages = pm.getInstalledPackagesAsUser(
5978                         PackageManager.MATCH_DISABLED_COMPONENTS
5979                             | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
5980                             | PackageManager.GET_SIGNING_CERTIFICATES,
5981                             UserHandle.SYSTEM.getIdentifier());
5982                 }
5983                 for (int p = packages.size() - 1; p >= 0; p--) {
5984                     PackageInfo pkgInfo = packages.get(p);
5985                     if (pkgInfo != null && pkgInfo.packageName != null
5986                             && card.getCarrierPrivilegeStatus(pkgInfo)
5987                             == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
5988                         privilegedPackages.add(pkgInfo.packageName);
5989                     }
5990                 }
5991             }
5992         }
5993         return privilegedPackages;
5994     }
5995 
5996     @Override
getPackagesWithCarrierPrivilegesForAllPhones()5997     public List<String> getPackagesWithCarrierPrivilegesForAllPhones() {
5998         enforceReadPrivilegedPermission("getPackagesWithCarrierPrivilegesForAllPhones");
5999 
6000         final long identity = Binder.clearCallingIdentity();
6001 
6002         List<String> privilegedPackages = new ArrayList<>();
6003         try {
6004             for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
6005                 privilegedPackages.addAll(getPackagesWithCarrierPrivileges(i));
6006             }
6007         } finally {
6008             Binder.restoreCallingIdentity(identity);
6009         }
6010         return privilegedPackages;
6011     }
6012 
getIccId(int subId)6013     private String getIccId(int subId) {
6014         final Phone phone = getPhone(subId);
6015         UiccCard card = phone == null ? null : phone.getUiccCard();
6016         if (card == null) {
6017             loge("getIccId: No UICC");
6018             return null;
6019         }
6020         String iccId = card.getIccId();
6021         if (TextUtils.isEmpty(iccId)) {
6022             loge("getIccId: ICC ID is null or empty.");
6023             return null;
6024         }
6025         return iccId;
6026     }
6027 
6028     @Override
setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, String number)6029     public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
6030             String number) {
6031         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
6032                 subId, "setLine1NumberForDisplayForSubscriber");
6033 
6034         final long identity = Binder.clearCallingIdentity();
6035         try {
6036             final String iccId = getIccId(subId);
6037             final Phone phone = getPhone(subId);
6038             if (phone == null) {
6039                 return false;
6040             }
6041             final String subscriberId = phone.getSubscriberId();
6042 
6043             if (DBG_MERGE) {
6044                 Rlog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
6045                         + subscriberId + " to " + number);
6046             }
6047 
6048             if (TextUtils.isEmpty(iccId)) {
6049                 return false;
6050             }
6051 
6052             final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
6053 
6054             final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
6055             if (alphaTag == null) {
6056                 editor.remove(alphaTagPrefKey);
6057             } else {
6058                 editor.putString(alphaTagPrefKey, alphaTag);
6059             }
6060 
6061             // Record both the line number and IMSI for this ICCID, since we need to
6062             // track all merged IMSIs based on line number
6063             final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
6064             final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
6065             if (number == null) {
6066                 editor.remove(numberPrefKey);
6067                 editor.remove(subscriberPrefKey);
6068             } else {
6069                 editor.putString(numberPrefKey, number);
6070                 editor.putString(subscriberPrefKey, subscriberId);
6071             }
6072 
6073             editor.commit();
6074             return true;
6075         } finally {
6076             Binder.restoreCallingIdentity(identity);
6077         }
6078     }
6079 
6080     @Override
getLine1NumberForDisplay(int subId, String callingPackage, String callingFeatureId)6081     public String getLine1NumberForDisplay(int subId, String callingPackage,
6082             String callingFeatureId) {
6083         // This is open to apps with WRITE_SMS.
6084         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
6085                 mApp, subId, callingPackage, callingFeatureId, "getLine1NumberForDisplay")) {
6086             if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
6087             return null;
6088         }
6089 
6090         final long identity = Binder.clearCallingIdentity();
6091         try {
6092             String iccId = getIccId(subId);
6093             if (iccId != null) {
6094                 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
6095                 if (DBG_MERGE) {
6096                     log("getLine1NumberForDisplay returning "
6097                             + mTelephonySharedPreferences.getString(numberPrefKey, null));
6098                 }
6099                 return mTelephonySharedPreferences.getString(numberPrefKey, null);
6100             }
6101             if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
6102             return null;
6103         } finally {
6104             Binder.restoreCallingIdentity(identity);
6105         }
6106     }
6107 
6108     @Override
getLine1AlphaTagForDisplay(int subId, String callingPackage, String callingFeatureId)6109     public String getLine1AlphaTagForDisplay(int subId, String callingPackage,
6110             String callingFeatureId) {
6111         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6112                 mApp, subId, callingPackage, callingFeatureId, "getLine1AlphaTagForDisplay")) {
6113             return null;
6114         }
6115 
6116         final long identity = Binder.clearCallingIdentity();
6117         try {
6118             String iccId = getIccId(subId);
6119             if (iccId != null) {
6120                 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
6121                 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
6122             }
6123             return null;
6124         } finally {
6125             Binder.restoreCallingIdentity(identity);
6126         }
6127     }
6128 
6129     @Override
getMergedSubscriberIds(int subId, String callingPackage, String callingFeatureId)6130     public String[] getMergedSubscriberIds(int subId, String callingPackage,
6131             String callingFeatureId) {
6132         // This API isn't public, so no need to provide a valid subscription ID - we're not worried
6133         // about carrier-privileged callers not having access.
6134         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6135                 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
6136                 callingFeatureId, "getMergedSubscriberIds")) {
6137             return null;
6138         }
6139 
6140         // Clear calling identity, when calling TelephonyManager, because callerUid must be
6141         // the process, where TelephonyManager was instantiated.
6142         // Otherwise AppOps check will fail.
6143         final long identity  = Binder.clearCallingIdentity();
6144         try {
6145             final Context context = mApp;
6146             final TelephonyManager tele = TelephonyManager.from(context);
6147             final SubscriptionManager sub = SubscriptionManager.from(context);
6148 
6149             // Figure out what subscribers are currently active
6150             final ArraySet<String> activeSubscriberIds = new ArraySet<>();
6151 
6152             // Only consider subs which match the current subId
6153             // This logic can be simplified. See b/131189269 for progress.
6154             if (isActiveSubscription(subId)) {
6155                 activeSubscriberIds.add(tele.getSubscriberId(subId));
6156             }
6157 
6158             // First pass, find a number override for an active subscriber
6159             String mergeNumber = null;
6160             final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
6161             for (String key : prefs.keySet()) {
6162                 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
6163                     final String subscriberId = (String) prefs.get(key);
6164                     if (activeSubscriberIds.contains(subscriberId)) {
6165                         final String iccId = key.substring(
6166                                 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
6167                         final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
6168                         mergeNumber = (String) prefs.get(numberKey);
6169                         if (DBG_MERGE) {
6170                             Rlog.d(LOG_TAG, "Found line number " + mergeNumber
6171                                     + " for active subscriber " + subscriberId);
6172                         }
6173                         if (!TextUtils.isEmpty(mergeNumber)) {
6174                             break;
6175                         }
6176                     }
6177                 }
6178             }
6179 
6180             // Shortcut when no active merged subscribers
6181             if (TextUtils.isEmpty(mergeNumber)) {
6182                 return null;
6183             }
6184 
6185             // Second pass, find all subscribers under that line override
6186             final ArraySet<String> result = new ArraySet<>();
6187             for (String key : prefs.keySet()) {
6188                 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
6189                     final String number = (String) prefs.get(key);
6190                     if (mergeNumber.equals(number)) {
6191                         final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
6192                         final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
6193                         final String subscriberId = (String) prefs.get(subscriberKey);
6194                         if (!TextUtils.isEmpty(subscriberId)) {
6195                             result.add(subscriberId);
6196                         }
6197                     }
6198                 }
6199             }
6200 
6201             final String[] resultArray = result.toArray(new String[result.size()]);
6202             Arrays.sort(resultArray);
6203             if (DBG_MERGE) {
6204                 Rlog.d(LOG_TAG,
6205                         "Found subscribers " + Arrays.toString(resultArray) + " after merge");
6206             }
6207             return resultArray;
6208         } finally {
6209             Binder.restoreCallingIdentity(identity);
6210         }
6211     }
6212 
6213     @Override
getMergedImsisFromGroup(int subId, String callingPackage)6214     public String[] getMergedImsisFromGroup(int subId, String callingPackage) {
6215         enforceReadPrivilegedPermission("getMergedImsisFromGroup");
6216 
6217         final long identity = Binder.clearCallingIdentity();
6218         try {
6219             final TelephonyManager telephonyManager = mApp.getSystemService(
6220                     TelephonyManager.class);
6221             String subscriberId = telephonyManager.getSubscriberId(subId);
6222             if (subscriberId == null) {
6223                 if (DBG) {
6224                     log("getMergedImsisFromGroup can't find subscriberId for subId "
6225                             + subId);
6226                 }
6227                 return null;
6228             }
6229 
6230             final SubscriptionInfo info = SubscriptionController.getInstance()
6231                     .getSubscriptionInfo(subId);
6232             final ParcelUuid groupUuid = info.getGroupUuid();
6233             // If it doesn't belong to any group, return just subscriberId of itself.
6234             if (groupUuid == null) {
6235                 return new String[]{subscriberId};
6236             }
6237 
6238             // Get all subscriberIds from the group.
6239             final List<String> mergedSubscriberIds = new ArrayList<>();
6240             final List<SubscriptionInfo> groupInfos = SubscriptionController.getInstance()
6241                     .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
6242                             mApp.getAttributionTag());
6243             for (SubscriptionInfo subInfo : groupInfos) {
6244                 subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
6245                 if (subscriberId != null) {
6246                     mergedSubscriberIds.add(subscriberId);
6247                 }
6248             }
6249 
6250             return mergedSubscriberIds.toArray(new String[mergedSubscriberIds.size()]);
6251         } finally {
6252             Binder.restoreCallingIdentity(identity);
6253 
6254         }
6255     }
6256 
6257     @Override
setOperatorBrandOverride(int subId, String brand)6258     public boolean setOperatorBrandOverride(int subId, String brand) {
6259         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,
6260                 subId, "setOperatorBrandOverride");
6261 
6262         final long identity = Binder.clearCallingIdentity();
6263         try {
6264             final Phone phone = getPhone(subId);
6265             return phone == null ? false : phone.setOperatorBrandOverride(brand);
6266         } finally {
6267             Binder.restoreCallingIdentity(identity);
6268         }
6269     }
6270 
6271     @Override
setRoamingOverride(int subId, List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList)6272     public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
6273             List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
6274             List<String> cdmaNonRoamingList) {
6275         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
6276                 mApp, subId, "setRoamingOverride");
6277 
6278         final long identity = Binder.clearCallingIdentity();
6279         try {
6280             final Phone phone = getPhone(subId);
6281             if (phone == null) {
6282                 return false;
6283             }
6284             return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
6285                     cdmaNonRoamingList);
6286         } finally {
6287             Binder.restoreCallingIdentity(identity);
6288         }
6289     }
6290 
6291     @Override
6292     @Deprecated
invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp)6293     public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
6294         enforceModifyPermission();
6295 
6296         int returnValue = 0;
6297         try {
6298             AsyncResult result = (AsyncResult) sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
6299             if(result.exception == null) {
6300                 if (result.result != null) {
6301                     byte[] responseData = (byte[])(result.result);
6302                     if(responseData.length > oemResp.length) {
6303                         Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
6304                                 responseData.length +  "bytes. Buffer Size is " +
6305                                 oemResp.length + "bytes.");
6306                     }
6307                     System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
6308                     returnValue = responseData.length;
6309                 }
6310             } else {
6311                 CommandException ex = (CommandException) result.exception;
6312                 returnValue = ex.getCommandError().ordinal();
6313                 if(returnValue > 0) returnValue *= -1;
6314             }
6315         } catch (RuntimeException e) {
6316             Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
6317             returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
6318             if(returnValue > 0) returnValue *= -1;
6319         }
6320 
6321         return returnValue;
6322     }
6323 
6324     @Override
setRadioCapability(RadioAccessFamily[] rafs)6325     public void setRadioCapability(RadioAccessFamily[] rafs) {
6326         try {
6327             ProxyController.getInstance().setRadioCapability(rafs);
6328         } catch (RuntimeException e) {
6329             Log.w(LOG_TAG, "setRadioCapability: Runtime Exception");
6330         }
6331     }
6332 
6333     @Override
getRadioAccessFamily(int phoneId, String callingPackage)6334     public int getRadioAccessFamily(int phoneId, String callingPackage) {
6335         Phone phone = PhoneFactory.getPhone(phoneId);
6336         try {
6337             TelephonyPermissions
6338                     .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6339                             mApp, phone.getSubId(), "getRadioAccessFamily");
6340         } catch (SecurityException e) {
6341             EventLog.writeEvent(0x534e4554, "150857259", -1, "Missing Permission");
6342             throw e;
6343         }
6344         int raf = RadioAccessFamily.RAF_UNKNOWN;
6345         if (phone == null) {
6346             return raf;
6347         }
6348         final long identity = Binder.clearCallingIdentity();
6349         try {
6350             TelephonyPermissions
6351                     .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
6352                             mApp, phone.getSubId(), "getRadioAccessFamily");
6353             raf = ProxyController.getInstance().getRadioAccessFamily(phoneId);
6354         } finally {
6355             Binder.restoreCallingIdentity(identity);
6356         }
6357         return raf;
6358     }
6359 
6360     @Override
enableVideoCalling(boolean enable)6361     public void enableVideoCalling(boolean enable) {
6362         final Phone defaultPhone = getDefaultPhone();
6363         enforceModifyPermission();
6364 
6365         final long identity = Binder.clearCallingIdentity();
6366         try {
6367             ImsManager.getInstance(defaultPhone.getContext(),
6368                     defaultPhone.getPhoneId()).setVtSetting(enable);
6369         } finally {
6370             Binder.restoreCallingIdentity(identity);
6371         }
6372     }
6373 
6374     @Override
isVideoCallingEnabled(String callingPackage, String callingFeatureId)6375     public boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId) {
6376         final Phone defaultPhone = getDefaultPhone();
6377         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
6378                 callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
6379             return false;
6380         }
6381 
6382         final long identity = Binder.clearCallingIdentity();
6383         try {
6384             // Check the user preference and the  system-level IMS setting. Even if the user has
6385             // enabled video calling, if IMS is disabled we aren't able to support video calling.
6386             // In the long run, we may instead need to check if there exists a connection service
6387             // which can support video calling.
6388             ImsManager imsManager =
6389                     ImsManager.getInstance(defaultPhone.getContext(), defaultPhone.getPhoneId());
6390             return imsManager.isVtEnabledByPlatform()
6391                     && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
6392                     && imsManager.isVtEnabledByUser();
6393         } finally {
6394             Binder.restoreCallingIdentity(identity);
6395         }
6396     }
6397 
6398     @Override
canChangeDtmfToneLength(int subId, String callingPackage, String callingFeatureId)6399     public boolean canChangeDtmfToneLength(int subId, String callingPackage,
6400             String callingFeatureId) {
6401         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6402                 mApp, subId, callingPackage, callingFeatureId,
6403                 "isVideoCallingEnabled")) {
6404             return false;
6405         }
6406 
6407         final long identity = Binder.clearCallingIdentity();
6408         try {
6409             CarrierConfigManager configManager =
6410                     (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
6411             return configManager.getConfigForSubId(subId)
6412                     .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
6413         } finally {
6414             Binder.restoreCallingIdentity(identity);
6415         }
6416     }
6417 
6418     @Override
isWorldPhone(int subId, String callingPackage, String callingFeatureId)6419     public boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId) {
6420         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6421                 mApp, subId, callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
6422             return false;
6423         }
6424 
6425         final long identity = Binder.clearCallingIdentity();
6426         try {
6427             CarrierConfigManager configManager =
6428                     (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
6429             return configManager.getConfigForSubId(subId)
6430                     .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
6431         } finally {
6432             Binder.restoreCallingIdentity(identity);
6433         }
6434     }
6435 
6436     @Override
isTtyModeSupported()6437     public boolean isTtyModeSupported() {
6438         TelecomManager telecomManager = mApp.getSystemService(TelecomManager.class);
6439         return telecomManager.isTtySupported();
6440     }
6441 
6442     @Override
isHearingAidCompatibilitySupported()6443     public boolean isHearingAidCompatibilitySupported() {
6444         final long identity = Binder.clearCallingIdentity();
6445         try {
6446             return mApp.getResources().getBoolean(R.bool.hac_enabled);
6447         } finally {
6448             Binder.restoreCallingIdentity(identity);
6449         }
6450     }
6451 
6452     /**
6453      * Determines whether the device currently supports RTT (Real-time text). Based both on carrier
6454      * support for the feature and device firmware support.
6455      *
6456      * @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
6457      */
6458     @Override
isRttSupported(int subscriptionId)6459     public boolean isRttSupported(int subscriptionId) {
6460         final long identity = Binder.clearCallingIdentity();
6461         final Phone phone = getPhone(subscriptionId);
6462         if (phone == null) {
6463             loge("isRttSupported: no Phone found. Invalid subId:" + subscriptionId);
6464             return false;
6465         }
6466         try {
6467             boolean isCarrierSupported = mApp.getCarrierConfigForSubId(subscriptionId).getBoolean(
6468                     CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
6469             boolean isDeviceSupported =
6470                     phone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
6471             return isCarrierSupported && isDeviceSupported;
6472         } finally {
6473             Binder.restoreCallingIdentity(identity);
6474         }
6475     }
6476 
6477     /**
6478      * Determines whether the user has turned on RTT. If the carrier wants to ignore the user-set
6479      * RTT setting, will return true if the device and carrier both support RTT.
6480      * Otherwise. only returns true if the device and carrier both also support RTT.
6481      */
isRttEnabled(int subscriptionId)6482     public boolean isRttEnabled(int subscriptionId) {
6483         final long identity = Binder.clearCallingIdentity();
6484         try {
6485             boolean isRttSupported = isRttSupported(subscriptionId);
6486             boolean isUserRttSettingOn = Settings.Secure.getInt(
6487                     mApp.getContentResolver(), Settings.Secure.RTT_CALLING_MODE, 0) != 0;
6488             boolean shouldIgnoreUserRttSetting = mApp.getCarrierConfigForSubId(subscriptionId)
6489                     .getBoolean(CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL);
6490             return isRttSupported && (isUserRttSettingOn || shouldIgnoreUserRttSetting);
6491         } finally {
6492             Binder.restoreCallingIdentity(identity);
6493         }
6494     }
6495 
6496     @Deprecated
6497     @Override
getDeviceId(String callingPackage)6498     public String getDeviceId(String callingPackage) {
6499         return getDeviceIdWithFeature(callingPackage, null);
6500     }
6501 
6502     /**
6503      * Returns the unique device ID of phone, for example, the IMEI for
6504      * GSM and the MEID for CDMA phones. Return null if device ID is not available.
6505      *
6506      * <p>Requires Permission:
6507      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
6508      */
6509     @Override
getDeviceIdWithFeature(String callingPackage, String callingFeatureId)6510     public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
6511         final Phone phone = PhoneFactory.getPhone(0);
6512         if (phone == null) {
6513             return null;
6514         }
6515         int subId = phone.getSubId();
6516         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
6517                 callingPackage, callingFeatureId, "getDeviceId")) {
6518             return null;
6519         }
6520 
6521         final long identity = Binder.clearCallingIdentity();
6522         try {
6523             return phone.getDeviceId();
6524         } finally {
6525             Binder.restoreCallingIdentity(identity);
6526         }
6527     }
6528 
6529     /**
6530      * {@hide}
6531      * Returns the IMS Registration Status on a particular subid
6532      *
6533      * @param subId
6534      */
isImsRegistered(int subId)6535     public boolean isImsRegistered(int subId) {
6536         Phone phone = getPhone(subId);
6537         if (phone != null) {
6538             return phone.isImsRegistered();
6539         } else {
6540             return false;
6541         }
6542     }
6543 
6544     @Override
getSubIdForPhoneAccount(PhoneAccount phoneAccount)6545     public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
6546         final long identity = Binder.clearCallingIdentity();
6547         try {
6548             return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
6549         } finally {
6550             Binder.restoreCallingIdentity(identity);
6551         }
6552     }
6553 
6554     @Override
getSubIdForPhoneAccountHandle( PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId)6555     public int getSubIdForPhoneAccountHandle(
6556             PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId) {
6557         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, getDefaultSubscription(),
6558                 callingPackage, callingFeatureId, "getSubIdForPhoneAccountHandle")) {
6559             throw new SecurityException("Requires READ_PHONE_STATE permission.");
6560         }
6561         final long identity = Binder.clearCallingIdentity();
6562         try {
6563             return PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle);
6564         } finally {
6565             Binder.restoreCallingIdentity(identity);
6566         }
6567     }
6568 
6569     @Override
getPhoneAccountHandleForSubscriptionId(int subscriptionId)6570     public @Nullable PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId) {
6571         final long identity = Binder.clearCallingIdentity();
6572         try {
6573             Phone phone = getPhone(subscriptionId);
6574             if (phone == null) {
6575                 return null;
6576             }
6577             return PhoneUtils.makePstnPhoneAccountHandle(phone);
6578         } finally {
6579             Binder.restoreCallingIdentity(identity);
6580         }
6581     }
6582 
6583     /**
6584      * @return the VoWiFi calling availability.
6585      */
isWifiCallingAvailable(int subId)6586     public boolean isWifiCallingAvailable(int subId) {
6587         final long identity = Binder.clearCallingIdentity();
6588         try {
6589             Phone phone = getPhone(subId);
6590             if (phone != null) {
6591                 return phone.isWifiCallingEnabled();
6592             } else {
6593                 return false;
6594             }
6595         } finally {
6596             Binder.restoreCallingIdentity(identity);
6597         }
6598     }
6599 
6600     /**
6601      * @return the VT calling availability.
6602      */
isVideoTelephonyAvailable(int subId)6603     public boolean isVideoTelephonyAvailable(int subId) {
6604         final long identity = Binder.clearCallingIdentity();
6605         try {
6606             Phone phone = getPhone(subId);
6607             if (phone != null) {
6608                 return phone.isVideoEnabled();
6609             } else {
6610                 return false;
6611             }
6612         } finally {
6613             Binder.restoreCallingIdentity(identity);
6614         }
6615     }
6616 
6617     /**
6618      * @return the IMS registration technology for the MMTEL feature. Valid return values are
6619      * defined in {@link ImsRegistrationImplBase}.
6620      */
getImsRegTechnologyForMmTel(int subId)6621     public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
6622         final long identity = Binder.clearCallingIdentity();
6623         try {
6624             Phone phone = getPhone(subId);
6625             if (phone != null) {
6626                 return phone.getImsRegistrationTech();
6627             } else {
6628                 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
6629             }
6630         } finally {
6631             Binder.restoreCallingIdentity(identity);
6632         }
6633     }
6634 
6635     @Override
factoryReset(int subId)6636     public void factoryReset(int subId) {
6637         enforceSettingsPermission();
6638         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
6639             return;
6640         }
6641 
6642         final long identity = Binder.clearCallingIdentity();
6643 
6644         try {
6645             if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
6646                     UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
6647                 setUserDataEnabled(subId, getDefaultDataEnabled());
6648                 setNetworkSelectionModeAutomatic(subId);
6649                 setPreferredNetworkType(subId, getDefaultNetworkType(subId));
6650                 setDataRoamingEnabled(subId, getDefaultDataRoamingEnabled(subId));
6651                 CarrierInfoManager.deleteAllCarrierKeysForImsiEncryption(mApp);
6652             }
6653             // There has been issues when Sms raw table somehow stores orphan
6654             // fragments. They lead to garbled message when new fragments come
6655             // in and combined with those stale ones. In case this happens again,
6656             // user can reset all network settings which will clean up this table.
6657             cleanUpSmsRawTable(getDefaultPhone().getContext());
6658             // Clean up IMS settings as well here.
6659             int slotId = getSlotIndex(subId);
6660             if (slotId > SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
6661                 ImsManager.getInstance(mApp, slotId).factoryReset();
6662             }
6663 
6664             // Erase modem config if erase modem on network setting is enabled.
6665             String configValue = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_TELEPHONY,
6666                     RESET_NETWORK_ERASE_MODEM_CONFIG_ENABLED);
6667             if (configValue != null && Boolean.parseBoolean(configValue)) {
6668               sendEraseModemConfig(getDefaultPhone());
6669             }
6670         } finally {
6671             Binder.restoreCallingIdentity(identity);
6672         }
6673     }
6674 
cleanUpSmsRawTable(Context context)6675     private void cleanUpSmsRawTable(Context context) {
6676         ContentResolver resolver = context.getContentResolver();
6677         Uri uri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, "raw/permanentDelete");
6678         resolver.delete(uri, null, null);
6679     }
6680 
6681     @Override
getSimLocaleForSubscriber(int subId)6682     public String getSimLocaleForSubscriber(int subId) {
6683         enforceReadPrivilegedPermission("getSimLocaleForSubscriber, subId: " + subId);
6684         final Phone phone = getPhone(subId);
6685         if (phone == null) {
6686             log("getSimLocaleForSubscriber, invalid subId");
6687             return null;
6688         }
6689         final long identity = Binder.clearCallingIdentity();
6690         try {
6691             final SubscriptionInfo info = mSubscriptionController.getActiveSubscriptionInfo(subId,
6692                     phone.getContext().getOpPackageName(), phone.getContext().getAttributionTag());
6693             if (info == null) {
6694                 log("getSimLocaleForSubscriber, inactive subId: " + subId);
6695                 return null;
6696             }
6697             // Try and fetch the locale from the carrier properties or from the SIM language
6698             // preferences (EF-PL and EF-LI)...
6699             final int mcc = info.getMcc();
6700             String simLanguage = null;
6701             final Locale localeFromDefaultSim = phone.getLocaleFromSimAndCarrierPrefs();
6702             if (localeFromDefaultSim != null) {
6703                 if (!localeFromDefaultSim.getCountry().isEmpty()) {
6704                     if (DBG) log("Using locale from subId: " + subId + " locale: "
6705                             + localeFromDefaultSim);
6706                     return localeFromDefaultSim.toLanguageTag();
6707                 } else {
6708                     simLanguage = localeFromDefaultSim.getLanguage();
6709                 }
6710             }
6711 
6712             // The SIM language preferences only store a language (e.g. fr = French), not an
6713             // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
6714             // the SIM and carrier preferences does not include a country we add the country
6715             // determined from the SIM MCC to provide an exact locale.
6716             final Locale mccLocale = LocaleUtils.getLocaleFromMcc(mApp, mcc, simLanguage);
6717             if (mccLocale != null) {
6718                 if (DBG) log("No locale from SIM, using mcc locale:" + mccLocale);
6719                 return mccLocale.toLanguageTag();
6720             }
6721 
6722             if (DBG) log("No locale found - returning null");
6723             return null;
6724         } finally {
6725             Binder.restoreCallingIdentity(identity);
6726         }
6727     }
6728 
getAllSubscriptionInfoList()6729     private List<SubscriptionInfo> getAllSubscriptionInfoList() {
6730         return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName(),
6731                 mApp.getAttributionTag());
6732     }
6733 
6734     /**
6735      * NOTE: this method assumes permission checks are done and caller identity has been cleared.
6736      */
getActiveSubscriptionInfoListPrivileged()6737     private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
6738         return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName(),
6739                 mApp.getAttributionTag());
6740     }
6741 
6742     private final ModemActivityInfo mLastModemActivityInfo =
6743             new ModemActivityInfo(0, 0, 0, new int[0], 0);
6744 
6745     /**
6746      * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
6747      * representing the state of the modem.
6748      *
6749      * NOTE: The underlying implementation clears the modem state, so there should only ever be one
6750      * caller to it. Everyone should call this class to get cumulative data.
6751      * @hide
6752      */
6753     @Override
requestModemActivityInfo(ResultReceiver result)6754     public void requestModemActivityInfo(ResultReceiver result) {
6755         enforceModifyPermission();
6756         WorkSource workSource = getWorkSource(Binder.getCallingUid());
6757 
6758         final long identity = Binder.clearCallingIdentity();
6759         try {
6760             sendRequestAsync(CMD_GET_MODEM_ACTIVITY_INFO, result, null, workSource);
6761         } finally {
6762             Binder.restoreCallingIdentity(identity);
6763         }
6764     }
6765 
6766     // Checks that ModemActivityInfo is valid. Sleep time, Idle time, Rx time and Tx time should be
6767     // less than total activity duration.
isModemActivityInfoValid(ModemActivityInfo info)6768     private boolean isModemActivityInfoValid(ModemActivityInfo info) {
6769         if (info == null) {
6770             return false;
6771         }
6772         int activityDurationMs =
6773             (int) (info.getTimestamp() - mLastModemActivityInfo.getTimestamp());
6774         int totalTxTimeMs = 0;
6775         int[] txTimeMs = info.getTransmitTimeMillis();
6776         for (int i = 0; i < info.getTransmitPowerInfo().size(); i++) {
6777             totalTxTimeMs += txTimeMs[i];
6778         }
6779         return (info.isValid()
6780             && (info.getSleepTimeMillis() <= activityDurationMs)
6781             && (info.getIdleTimeMillis() <= activityDurationMs)
6782             && (info.getReceiveTimeMillis() <= activityDurationMs)
6783             && (totalTxTimeMs <= activityDurationMs));
6784     }
6785 
6786     /**
6787      * {@hide}
6788      * Returns the service state information on specified subscription.
6789      */
6790     @Override
getServiceStateForSubscriber(int subId, String callingPackage, String callingFeatureId)6791     public ServiceState getServiceStateForSubscriber(int subId, String callingPackage,
6792             String callingFeatureId) {
6793         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
6794                 mApp, subId, callingPackage, callingFeatureId, "getServiceStateForSubscriber")) {
6795             return null;
6796         }
6797 
6798         LocationAccessPolicy.LocationPermissionResult fineLocationResult =
6799                 LocationAccessPolicy.checkLocationPermission(mApp,
6800                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
6801                                 .setCallingPackage(callingPackage)
6802                                 .setCallingFeatureId(callingFeatureId)
6803                                 .setCallingPid(Binder.getCallingPid())
6804                                 .setCallingUid(Binder.getCallingUid())
6805                                 .setMethod("getServiceStateForSubscriber")
6806                                 .setLogAsInfo(true)
6807                                 .setMinSdkVersionForFine(Build.VERSION_CODES.Q)
6808                                 .build());
6809 
6810         LocationAccessPolicy.LocationPermissionResult coarseLocationResult =
6811                 LocationAccessPolicy.checkLocationPermission(mApp,
6812                         new LocationAccessPolicy.LocationPermissionQuery.Builder()
6813                                 .setCallingPackage(callingPackage)
6814                                 .setCallingFeatureId(callingFeatureId)
6815                                 .setCallingPid(Binder.getCallingPid())
6816                                 .setCallingUid(Binder.getCallingUid())
6817                                 .setMethod("getServiceStateForSubscriber")
6818                                 .setLogAsInfo(true)
6819                                 .setMinSdkVersionForCoarse(Build.VERSION_CODES.Q)
6820                                 .build());
6821         // We don't care about hard or soft here -- all we need to know is how much info to scrub.
6822         boolean hasFinePermission =
6823                 fineLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
6824         boolean hasCoarsePermission =
6825                 coarseLocationResult == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
6826 
6827         final long identity = Binder.clearCallingIdentity();
6828         try {
6829             // isActiveSubId requires READ_PHONE_STATE, which we already check for above
6830             if (!mSubscriptionController.isActiveSubId(subId, callingPackage, callingFeatureId)) {
6831                 Rlog.d(LOG_TAG,
6832                         "getServiceStateForSubscriber returning null for inactive subId=" + subId);
6833                 return null;
6834             }
6835 
6836             final Phone phone = getPhone(subId);
6837             if (phone == null) {
6838                 return null;
6839             }
6840 
6841             ServiceState ss = phone.getServiceState();
6842 
6843             // Scrub out the location info in ServiceState depending on what level of access
6844             // the caller has.
6845             if (hasFinePermission) return ss;
6846             if (hasCoarsePermission) return ss.createLocationInfoSanitizedCopy(false);
6847             return ss.createLocationInfoSanitizedCopy(true);
6848         } finally {
6849             Binder.restoreCallingIdentity(identity);
6850         }
6851     }
6852 
6853     /**
6854      * Returns the URI for the per-account voicemail ringtone set in Phone settings.
6855      *
6856      * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
6857      * voicemail ringtone.
6858      * @return The URI for the ringtone to play when receiving a voicemail from a specific
6859      * PhoneAccount.
6860      */
6861     @Override
getVoicemailRingtoneUri(PhoneAccountHandle accountHandle)6862     public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
6863         final long identity = Binder.clearCallingIdentity();
6864         try {
6865             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
6866             if (phone == null) {
6867                 phone = getDefaultPhone();
6868             }
6869 
6870             return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
6871         } finally {
6872             Binder.restoreCallingIdentity(identity);
6873         }
6874     }
6875 
6876     /**
6877      * Sets the per-account voicemail ringtone.
6878      *
6879      * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
6880      * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
6881      *
6882      * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
6883      * voicemail ringtone.
6884      * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
6885      * PhoneAccount.
6886      */
6887     @Override
setVoicemailRingtoneUri(String callingPackage, PhoneAccountHandle phoneAccountHandle, Uri uri)6888     public void setVoicemailRingtoneUri(String callingPackage,
6889             PhoneAccountHandle phoneAccountHandle, Uri uri) {
6890         final Phone defaultPhone = getDefaultPhone();
6891         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
6892         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
6893         if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
6894             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6895                     mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
6896                     "setVoicemailRingtoneUri");
6897         }
6898 
6899         final long identity = Binder.clearCallingIdentity();
6900         try {
6901             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
6902             if (phone == null) {
6903                 phone = defaultPhone;
6904             }
6905             VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
6906         } finally {
6907             Binder.restoreCallingIdentity(identity);
6908         }
6909     }
6910 
6911     /**
6912      * Returns whether vibration is set for voicemail notification in Phone settings.
6913      *
6914      * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
6915      * voicemail vibration setting.
6916      * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
6917      */
6918     @Override
isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle)6919     public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
6920         final long identity = Binder.clearCallingIdentity();
6921         try {
6922             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
6923             if (phone == null) {
6924                 phone = getDefaultPhone();
6925             }
6926 
6927             return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
6928         } finally {
6929             Binder.restoreCallingIdentity(identity);
6930         }
6931     }
6932 
6933     /**
6934      * Sets the per-account voicemail vibration.
6935      *
6936      * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
6937      * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
6938      *
6939      * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
6940      * voicemail vibration setting.
6941      * @param enabled Whether to enable or disable vibration for voicemail notifications from a
6942      * specific PhoneAccount.
6943      */
6944     @Override
setVoicemailVibrationEnabled(String callingPackage, PhoneAccountHandle phoneAccountHandle, boolean enabled)6945     public void setVoicemailVibrationEnabled(String callingPackage,
6946             PhoneAccountHandle phoneAccountHandle, boolean enabled) {
6947         final Phone defaultPhone = getDefaultPhone();
6948         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
6949         TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);
6950         if (!TextUtils.equals(callingPackage, tm.getDefaultDialerPackage())) {
6951             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
6952                     mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
6953                     "setVoicemailVibrationEnabled");
6954         }
6955 
6956         final long identity = Binder.clearCallingIdentity();
6957         try {
6958             Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
6959             if (phone == null) {
6960                 phone = defaultPhone;
6961             }
6962             VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
6963         } finally {
6964             Binder.restoreCallingIdentity(identity);
6965         }
6966     }
6967 
6968     /**
6969      * Make sure either called from same process as self (phone) or IPC caller has read privilege.
6970      *
6971      * @throws SecurityException if the caller does not have the required permission
6972      */
enforceReadPrivilegedPermission(String message)6973     private void enforceReadPrivilegedPermission(String message) {
6974         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
6975                 message);
6976     }
6977 
6978     /**
6979      * Make sure either called from same process as self (phone) or IPC caller has send SMS
6980      * permission.
6981      *
6982      * @throws SecurityException if the caller does not have the required permission
6983      */
enforceSendSmsPermission()6984     private void enforceSendSmsPermission() {
6985         mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
6986     }
6987 
6988     /**
6989      * Make sure called from the package in charge of visual voicemail.
6990      *
6991      * @throws SecurityException if the caller is not the visual voicemail package.
6992      */
enforceVisualVoicemailPackage(String callingPackage, int subId)6993     private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
6994         final long identity = Binder.clearCallingIdentity();
6995         try {
6996             ComponentName componentName =
6997                     RemoteVvmTaskManager.getRemotePackage(mApp, subId);
6998             if (componentName == null) {
6999                 throw new SecurityException(
7000                         "Caller not current active visual voicemail package[null]");
7001             }
7002             String vvmPackage = componentName.getPackageName();
7003             if (!callingPackage.equals(vvmPackage)) {
7004                 throw new SecurityException("Caller not current active visual voicemail package["
7005                         + vvmPackage + "]");
7006             }
7007         } finally {
7008             Binder.restoreCallingIdentity(identity);
7009         }
7010     }
7011 
7012     /**
7013      * Return the application ID for the app type.
7014      *
7015      * @param subId the subscription ID that this request applies to.
7016      * @param appType the uicc app type.
7017      * @return Application ID for specificied app type, or null if no uicc.
7018      */
7019     @Override
getAidForAppType(int subId, int appType)7020     public String getAidForAppType(int subId, int appType) {
7021         enforceReadPrivilegedPermission("getAidForAppType");
7022         Phone phone = getPhone(subId);
7023 
7024         final long identity = Binder.clearCallingIdentity();
7025         try {
7026             if (phone == null) {
7027                 return null;
7028             }
7029             String aid = null;
7030             try {
7031                 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
7032                         .getApplicationByType(appType).getAid();
7033             } catch (Exception e) {
7034                 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
7035             }
7036             return aid;
7037         } finally {
7038             Binder.restoreCallingIdentity(identity);
7039         }
7040     }
7041 
7042     /**
7043      * Return the Electronic Serial Number.
7044      *
7045      * @param subId the subscription ID that this request applies to.
7046      * @return ESN or null if error.
7047      */
7048     @Override
getEsn(int subId)7049     public String getEsn(int subId) {
7050         enforceReadPrivilegedPermission("getEsn");
7051         Phone phone = getPhone(subId);
7052 
7053         final long identity = Binder.clearCallingIdentity();
7054         try {
7055             if (phone == null) {
7056                 return null;
7057             }
7058             String esn = null;
7059             try {
7060                 esn = phone.getEsn();
7061             } catch (Exception e) {
7062                 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
7063             }
7064             return esn;
7065         } finally {
7066             Binder.restoreCallingIdentity(identity);
7067         }
7068     }
7069 
7070     /**
7071      * Return the Preferred Roaming List Version.
7072      *
7073      * @param subId the subscription ID that this request applies to.
7074      * @return PRLVersion or null if error.
7075      */
7076     @Override
getCdmaPrlVersion(int subId)7077     public String getCdmaPrlVersion(int subId) {
7078         enforceReadPrivilegedPermission("getCdmaPrlVersion");
7079         Phone phone = getPhone(subId);
7080 
7081         final long identity = Binder.clearCallingIdentity();
7082         try {
7083             if (phone == null) {
7084                 return null;
7085             }
7086             String cdmaPrlVersion = null;
7087             try {
7088                 cdmaPrlVersion = phone.getCdmaPrlVersion();
7089             } catch (Exception e) {
7090                 Log.e(LOG_TAG, "Not getting PRLVersion", e);
7091             }
7092             return cdmaPrlVersion;
7093         } finally {
7094             Binder.restoreCallingIdentity(identity);
7095         }
7096     }
7097 
7098     /**
7099      * Get snapshot of Telephony histograms
7100      * @return List of Telephony histograms
7101      * @hide
7102      */
7103     @Override
getTelephonyHistograms()7104     public List<TelephonyHistogram> getTelephonyHistograms() {
7105         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7106                 mApp, getDefaultSubscription(), "getTelephonyHistograms");
7107 
7108         final long identity = Binder.clearCallingIdentity();
7109         try {
7110             return RIL.getTelephonyRILTimingHistograms();
7111         } finally {
7112             Binder.restoreCallingIdentity(identity);
7113         }
7114     }
7115 
7116     /**
7117      * {@hide}
7118      * Set the allowed carrier list and the excluded carrier list, indicating the priority between
7119      * the two lists.
7120      * Require system privileges. In the future we may add this to carrier APIs.
7121      *
7122      * @return Integer with the result of the operation, as defined in {@link TelephonyManager}.
7123      */
7124     @Override
7125     @TelephonyManager.SetCarrierRestrictionResult
setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules)7126     public int setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules) {
7127         enforceModifyPermission();
7128         WorkSource workSource = getWorkSource(Binder.getCallingUid());
7129 
7130         if (carrierRestrictionRules == null) {
7131             throw new NullPointerException("carrier restriction cannot be null");
7132         }
7133 
7134         final long identity = Binder.clearCallingIdentity();
7135         try {
7136             return (int) sendRequest(CMD_SET_ALLOWED_CARRIERS, carrierRestrictionRules,
7137                     workSource);
7138         } finally {
7139             Binder.restoreCallingIdentity(identity);
7140         }
7141     }
7142 
7143     /**
7144      * {@hide}
7145      * Get the allowed carrier list and the excluded carrier list, including the priority between
7146      * the two lists.
7147      * Require system privileges. In the future we may add this to carrier APIs.
7148      *
7149      * @return {@link android.telephony.CarrierRestrictionRules}
7150      */
7151     @Override
getAllowedCarriers()7152     public CarrierRestrictionRules getAllowedCarriers() {
7153         enforceReadPrivilegedPermission("getAllowedCarriers");
7154         WorkSource workSource = getWorkSource(Binder.getCallingUid());
7155 
7156         final long identity = Binder.clearCallingIdentity();
7157         try {
7158             Object response = sendRequest(CMD_GET_ALLOWED_CARRIERS, null, workSource);
7159             if (response instanceof CarrierRestrictionRules) {
7160                 return (CarrierRestrictionRules) response;
7161             }
7162             // Response is an Exception of some kind,
7163             // which is signalled to the user as a NULL retval
7164             return null;
7165         } catch (Exception e) {
7166             Log.e(LOG_TAG, "getAllowedCarriers. Exception ex=" + e);
7167             return null;
7168         } finally {
7169             Binder.restoreCallingIdentity(identity);
7170         }
7171     }
7172 
7173     /**
7174      * Action set from carrier signalling broadcast receivers to enable/disable metered apns
7175      * @param subId the subscription ID that this action applies to.
7176      * @param enabled control enable or disable metered apns.
7177      * {@hide}
7178      */
7179     @Override
carrierActionSetMeteredApnsEnabled(int subId, boolean enabled)7180     public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
7181         enforceModifyPermission();
7182         final Phone phone = getPhone(subId);
7183 
7184         final long identity = Binder.clearCallingIdentity();
7185         if (phone == null) {
7186             loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId);
7187             return;
7188         }
7189         try {
7190             phone.carrierActionSetMeteredApnsEnabled(enabled);
7191         } catch (Exception e) {
7192             Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e);
7193         } finally {
7194             Binder.restoreCallingIdentity(identity);
7195         }
7196     }
7197 
7198     /**
7199      * Action set from carrier signalling broadcast receivers to enable/disable radio
7200      * @param subId the subscription ID that this action applies to.
7201      * @param enabled control enable or disable radio.
7202      * {@hide}
7203      */
7204     @Override
carrierActionSetRadioEnabled(int subId, boolean enabled)7205     public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
7206         enforceModifyPermission();
7207         final Phone phone = getPhone(subId);
7208 
7209         final long identity = Binder.clearCallingIdentity();
7210         if (phone == null) {
7211             loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
7212             return;
7213         }
7214         try {
7215             phone.carrierActionSetRadioEnabled(enabled);
7216         } catch (Exception e) {
7217             Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
7218         } finally {
7219             Binder.restoreCallingIdentity(identity);
7220         }
7221     }
7222 
7223     /**
7224      * Action set from carrier signalling broadcast receivers to start/stop reporting the default
7225      * network status based on which carrier apps could apply actions accordingly,
7226      * enable/disable default url handler for example.
7227      *
7228      * @param subId the subscription ID that this action applies to.
7229      * @param report control start/stop reporting the default network status.
7230      * {@hide}
7231      */
7232     @Override
carrierActionReportDefaultNetworkStatus(int subId, boolean report)7233     public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
7234         enforceModifyPermission();
7235         final Phone phone = getPhone(subId);
7236 
7237         final long identity = Binder.clearCallingIdentity();
7238         if (phone == null) {
7239             loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
7240             return;
7241         }
7242         try {
7243             phone.carrierActionReportDefaultNetworkStatus(report);
7244         } catch (Exception e) {
7245             Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
7246         } finally {
7247             Binder.restoreCallingIdentity(identity);
7248         }
7249     }
7250 
7251     /**
7252      * Action set from carrier signalling broadcast receivers to reset all carrier actions
7253      * @param subId the subscription ID that this action applies to.
7254      * {@hide}
7255      */
7256     @Override
carrierActionResetAll(int subId)7257     public void carrierActionResetAll(int subId) {
7258         enforceModifyPermission();
7259         final Phone phone = getPhone(subId);
7260         if (phone == null) {
7261             loge("carrierAction: ResetAll fails with invalid sibId: " + subId);
7262             return;
7263         }
7264         try {
7265             phone.carrierActionResetAll();
7266         } catch (Exception e) {
7267             Log.e(LOG_TAG, "carrierAction: ResetAll fails. Exception ex=" + e);
7268         }
7269     }
7270 
7271     /**
7272      * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
7273      * bug report is being generated.
7274      */
7275     @Override
dump(FileDescriptor fd, PrintWriter writer, String[] args)7276     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
7277         if (mApp.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
7278                 != PackageManager.PERMISSION_GRANTED) {
7279             writer.println("Permission Denial: can't dump Phone from pid="
7280                     + Binder.getCallingPid()
7281                     + ", uid=" + Binder.getCallingUid()
7282                     + "without permission "
7283                     + android.Manifest.permission.DUMP);
7284             return;
7285         }
7286         DumpsysHandler.dump(mApp, fd, writer, args);
7287     }
7288 
7289     @Override
handleShellCommand(@onNull ParcelFileDescriptor in, @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, @NonNull String[] args)7290     public int handleShellCommand(@NonNull ParcelFileDescriptor in,
7291             @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
7292             @NonNull String[] args) {
7293         return new TelephonyShellCommand(this, getDefaultPhone().getContext()).exec(
7294                 this, in.getFileDescriptor(), out.getFileDescriptor(),
7295                         err.getFileDescriptor(), args);
7296     }
7297 
7298     /**
7299      * Policy control of data connection. Usually used when data limit is passed.
7300      * @param enabled True if enabling the data, otherwise disabling.
7301      * @param subId Subscription index
7302      * {@hide}
7303      */
7304     @Override
setPolicyDataEnabled(boolean enabled, int subId)7305     public void setPolicyDataEnabled(boolean enabled, int subId) {
7306         enforceModifyPermission();
7307 
7308         final long identity = Binder.clearCallingIdentity();
7309         try {
7310             Phone phone = getPhone(subId);
7311             if (phone != null) {
7312                 phone.getDataEnabledSettings().setPolicyDataEnabled(enabled);
7313             }
7314         } finally {
7315             Binder.restoreCallingIdentity(identity);
7316         }
7317     }
7318 
7319     /**
7320      * Get Client request stats
7321      * @return List of Client Request Stats
7322      * @hide
7323      */
7324     @Override
getClientRequestStats(String callingPackage, String callingFeatureId, int subId)7325     public List<ClientRequestStats> getClientRequestStats(String callingPackage,
7326             String callingFeatureId, int subId) {
7327         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
7328                 mApp, subId, callingPackage, callingFeatureId, "getClientRequestStats")) {
7329             return null;
7330         }
7331         Phone phone = getPhone(subId);
7332 
7333         final long identity = Binder.clearCallingIdentity();
7334         try {
7335             if (phone != null) {
7336                 return phone.getClientRequestStats();
7337             }
7338 
7339             return null;
7340         } finally {
7341             Binder.restoreCallingIdentity(identity);
7342         }
7343     }
7344 
getWorkSource(int uid)7345     private WorkSource getWorkSource(int uid) {
7346         String packageName = mApp.getPackageManager().getNameForUid(uid);
7347         return new WorkSource(uid, packageName);
7348     }
7349 
7350     /**
7351      * Set SIM card power state.
7352      *
7353      * @param slotIndex SIM slot id.
7354      * @param state  State of SIM (power down, power up, pass through)
7355      * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
7356      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
7357      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
7358      *
7359      **/
7360     @Override
setSimPowerStateForSlot(int slotIndex, int state)7361     public void setSimPowerStateForSlot(int slotIndex, int state) {
7362         enforceModifyPermission();
7363         Phone phone = PhoneFactory.getPhone(slotIndex);
7364 
7365         WorkSource workSource = getWorkSource(Binder.getCallingUid());
7366 
7367         final long identity = Binder.clearCallingIdentity();
7368         try {
7369             if (phone != null) {
7370                 phone.setSimPowerState(state, workSource);
7371             }
7372         } finally {
7373             Binder.restoreCallingIdentity(identity);
7374         }
7375     }
7376 
isUssdApiAllowed(int subId)7377     private boolean isUssdApiAllowed(int subId) {
7378         CarrierConfigManager configManager =
7379                 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
7380         if (configManager == null) {
7381             return false;
7382         }
7383         PersistableBundle pb = configManager.getConfigForSubId(subId);
7384         if (pb == null) {
7385             return false;
7386         }
7387         return pb.getBoolean(
7388                 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
7389     }
7390 
7391     /**
7392      * Check if phone is in emergency callback mode
7393      * @return true if phone is in emergency callback mode
7394      * @param subId sub id
7395      */
7396     @Override
getEmergencyCallbackMode(int subId)7397     public boolean getEmergencyCallbackMode(int subId) {
7398         enforceReadPrivilegedPermission("getEmergencyCallbackMode");
7399         final Phone phone = getPhone(subId);
7400 
7401         final long identity = Binder.clearCallingIdentity();
7402         try {
7403             if (phone != null) {
7404                 return phone.isInEcm();
7405             } else {
7406                 return false;
7407             }
7408         } finally {
7409             Binder.restoreCallingIdentity(identity);
7410         }
7411     }
7412 
7413     /**
7414      * Get the current signal strength information for the given subscription.
7415      * Because this information is not updated when the device is in a low power state
7416      * it should not be relied-upon to be current.
7417      * @param subId Subscription index
7418      * @return the most recent cached signal strength info from the modem
7419      */
7420     @Override
getSignalStrength(int subId)7421     public SignalStrength getSignalStrength(int subId) {
7422         final long identity = Binder.clearCallingIdentity();
7423         try {
7424             Phone p = getPhone(subId);
7425             if (p == null) {
7426                 return null;
7427             }
7428 
7429             return p.getSignalStrength();
7430         } finally {
7431             Binder.restoreCallingIdentity(identity);
7432         }
7433     }
7434 
7435     /**
7436      * Get the current modem radio state for the given slot.
7437      * @param slotIndex slot index.
7438      * @param callingPackage the name of the package making the call.
7439      * @param callingFeatureId The feature in the package.
7440      * @return the current radio power state from the modem
7441      */
7442     @Override
getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId)7443     public int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId) {
7444         Phone phone = PhoneFactory.getPhone(slotIndex);
7445         if (phone != null) {
7446             if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, phone.getSubId(),
7447                     callingPackage, callingFeatureId, "getRadioPowerState")) {
7448                 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
7449             }
7450 
7451             final long identity = Binder.clearCallingIdentity();
7452             try {
7453                 return phone.getRadioPowerState();
7454             } finally {
7455                 Binder.restoreCallingIdentity(identity);
7456             }
7457         }
7458         return TelephonyManager.RADIO_POWER_UNAVAILABLE;
7459     }
7460 
7461     /**
7462      * Checks if data roaming is enabled on the subscription with id {@code subId}.
7463      *
7464      * <p>Requires one of the following permissions:
7465      * {@link android.Manifest.permission#ACCESS_NETWORK_STATE},
7466      * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling app has carrier
7467      * privileges.
7468      *
7469      * @param subId subscription id
7470      * @return {@code true} if data roaming is enabled on this subscription, otherwise return
7471      * {@code false}.
7472      */
7473     @Override
isDataRoamingEnabled(int subId)7474     public boolean isDataRoamingEnabled(int subId) {
7475         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
7476                 null /* message */);
7477 
7478         boolean isEnabled = false;
7479         final long identity = Binder.clearCallingIdentity();
7480         try {
7481             Phone phone = getPhone(subId);
7482             isEnabled =  phone != null ? phone.getDataRoamingEnabled() : false;
7483         } catch (Exception e) {
7484             TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
7485                     mApp, subId, "isDataRoamingEnabled");
7486         } finally {
7487             Binder.restoreCallingIdentity(identity);
7488         }
7489         return isEnabled;
7490     }
7491 
7492 
7493     /**
7494      * Enables/Disables the data roaming on the subscription with id {@code subId}.
7495      *
7496      * <p> Requires permission:
7497      * {@link android.Manifest.permission#MODIFY_PHONE_STATE} or that the calling app has carrier
7498      * privileges.
7499      *
7500      * @param subId subscription id
7501      * @param isEnabled {@code true} means enable, {@code false} means disable.
7502      */
7503     @Override
setDataRoamingEnabled(int subId, boolean isEnabled)7504     public void setDataRoamingEnabled(int subId, boolean isEnabled) {
7505         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7506                 mApp, subId, "setDataRoamingEnabled");
7507 
7508         final long identity = Binder.clearCallingIdentity();
7509         try {
7510             Phone phone = getPhone(subId);
7511             if (phone != null) {
7512                 phone.setDataRoamingEnabled(isEnabled);
7513             }
7514         } finally {
7515             Binder.restoreCallingIdentity(identity);
7516         }
7517     }
7518 
7519     @Override
isManualNetworkSelectionAllowed(int subId)7520     public boolean isManualNetworkSelectionAllowed(int subId) {
7521         TelephonyPermissions
7522                 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
7523                 mApp, subId, "isManualNetworkSelectionAllowed");
7524 
7525         boolean isAllowed = true;
7526         final long identity = Binder.clearCallingIdentity();
7527         try {
7528             Phone phone = getPhone(subId);
7529             if (phone != null) {
7530                 isAllowed = phone.isCspPlmnEnabled();
7531             }
7532         } finally {
7533             Binder.restoreCallingIdentity(identity);
7534         }
7535         return isAllowed;
7536     }
7537 
7538     @Override
getUiccCardsInfo(String callingPackage)7539     public List<UiccCardInfo> getUiccCardsInfo(String callingPackage) {
7540         // Verify that tha callingPackage belongs to the calling UID
7541         mApp.getSystemService(AppOpsManager.class)
7542                 .checkPackage(Binder.getCallingUid(), callingPackage);
7543 
7544         boolean hasReadPermission = false;
7545         try {
7546             enforceReadPrivilegedPermission("getUiccCardsInfo");
7547             hasReadPermission = true;
7548         } catch (SecurityException e) {
7549             // even without READ_PRIVILEGED_PHONE_STATE, we allow the call to continue if the caller
7550             // has carrier privileges on an active UICC
7551             if (checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
7552                         != TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
7553                 throw new SecurityException("Caller does not have permission.");
7554             }
7555         }
7556 
7557         final long identity = Binder.clearCallingIdentity();
7558         try {
7559             UiccController uiccController = UiccController.getInstance();
7560             ArrayList<UiccCardInfo> cardInfos = uiccController.getAllUiccCardInfos();
7561             if (hasReadPermission) {
7562                 return cardInfos;
7563             }
7564 
7565             // Remove private info if the caller doesn't have access
7566             ArrayList<UiccCardInfo> filteredInfos = new ArrayList<>();
7567             for (UiccCardInfo cardInfo : cardInfos) {
7568                 // For an inactive eUICC, the UiccCard will be null even though the UiccCardInfo
7569                 // is available
7570                 UiccCard card = uiccController.getUiccCardForSlot(cardInfo.getSlotIndex());
7571                 if (card == null || card.getUiccProfile() == null) {
7572                     // assume no access if the card or profile is unavailable
7573                     filteredInfos.add(cardInfo.getUnprivileged());
7574                     continue;
7575                 }
7576                 UiccProfile profile = card.getUiccProfile();
7577                 if (profile.getCarrierPrivilegeStatus(mApp.getPackageManager(), callingPackage)
7578                         == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
7579                     filteredInfos.add(cardInfo);
7580                 } else {
7581                     filteredInfos.add(cardInfo.getUnprivileged());
7582                 }
7583             }
7584             return filteredInfos;
7585         } finally {
7586             Binder.restoreCallingIdentity(identity);
7587         }
7588     }
7589 
7590     @Override
getUiccSlotsInfo()7591     public UiccSlotInfo[] getUiccSlotsInfo() {
7592         enforceReadPrivilegedPermission("getUiccSlotsInfo");
7593 
7594         final long identity = Binder.clearCallingIdentity();
7595         try {
7596             UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
7597             if (slots == null) {
7598                 Rlog.i(LOG_TAG, "slots is null.");
7599                 return null;
7600             }
7601 
7602             UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
7603             for (int i = 0; i < slots.length; i++) {
7604                 UiccSlot slot = slots[i];
7605                 if (slot == null) {
7606                     continue;
7607                 }
7608 
7609                 String cardId;
7610                 UiccCard card = slot.getUiccCard();
7611                 if (card != null) {
7612                     cardId = card.getCardId();
7613                 } else {
7614                     cardId = slot.getEid();
7615                     if (TextUtils.isEmpty(cardId)) {
7616                         cardId = slot.getIccId();
7617                     }
7618                 }
7619 
7620                 if (cardId != null) {
7621                     // if cardId is an ICCID, strip off trailing Fs before exposing to user
7622                     // if cardId is an EID, it's all digits so this is fine
7623                     cardId = IccUtils.stripTrailingFs(cardId);
7624                 }
7625 
7626                 int cardState = 0;
7627                 switch (slot.getCardState()) {
7628                     case CARDSTATE_ABSENT:
7629                         cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
7630                         break;
7631                     case CARDSTATE_PRESENT:
7632                         cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
7633                         break;
7634                     case CARDSTATE_ERROR:
7635                         cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
7636                         break;
7637                     case CARDSTATE_RESTRICTED:
7638                         cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
7639                         break;
7640                     default:
7641                         break;
7642 
7643                 }
7644 
7645                 infos[i] = new UiccSlotInfo(
7646                         slot.isActive(),
7647                         slot.isEuicc(),
7648                         cardId,
7649                         cardState,
7650                         slot.getPhoneId(),
7651                         slot.isExtendedApduSupported(),
7652                         slot.isRemovable());
7653             }
7654             return infos;
7655         } finally {
7656             Binder.restoreCallingIdentity(identity);
7657         }
7658     }
7659 
7660     @Override
switchSlots(int[] physicalSlots)7661     public boolean switchSlots(int[] physicalSlots) {
7662         enforceModifyPermission();
7663 
7664         final long identity = Binder.clearCallingIdentity();
7665         try {
7666             return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
7667         } finally {
7668             Binder.restoreCallingIdentity(identity);
7669         }
7670     }
7671 
7672     @Override
getCardIdForDefaultEuicc(int subId, String callingPackage)7673     public int getCardIdForDefaultEuicc(int subId, String callingPackage) {
7674         final long identity = Binder.clearCallingIdentity();
7675         try {
7676             return UiccController.getInstance().getCardIdForDefaultEuicc();
7677         } finally {
7678             Binder.restoreCallingIdentity(identity);
7679         }
7680     }
7681 
7682     /**
7683      * A test API to reload the UICC profile.
7684      *
7685      * <p>Requires that the calling app has permission
7686      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
7687      * @hide
7688      */
7689     @Override
refreshUiccProfile(int subId)7690     public void refreshUiccProfile(int subId) {
7691         enforceModifyPermission();
7692 
7693         final long identity = Binder.clearCallingIdentity();
7694         try {
7695             Phone phone = getPhone(subId);
7696             if (phone == null) {
7697                 return;
7698             }
7699             UiccCard uiccCard = phone.getUiccCard();
7700             if (uiccCard == null) {
7701                 return;
7702             }
7703             UiccProfile uiccProfile = uiccCard.getUiccProfile();
7704             if (uiccProfile == null) {
7705                 return;
7706             }
7707             uiccProfile.refresh();
7708         } finally {
7709             Binder.restoreCallingIdentity(identity);
7710         }
7711     }
7712 
7713     /**
7714      * Returns false if the mobile data is disabled by default, otherwise return true.
7715      */
getDefaultDataEnabled()7716     private boolean getDefaultDataEnabled() {
7717         return TelephonyProperties.mobile_data().orElse(true);
7718     }
7719 
7720     /**
7721      * Returns true if the data roaming is enabled by default, i.e the system property
7722      * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
7723      * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
7724      */
getDefaultDataRoamingEnabled(int subId)7725     private boolean getDefaultDataRoamingEnabled(int subId) {
7726         final CarrierConfigManager configMgr = (CarrierConfigManager)
7727                 mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
7728         boolean isDataRoamingEnabled = TelephonyProperties.data_roaming().orElse(false);
7729         isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
7730                 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
7731         return isDataRoamingEnabled;
7732     }
7733 
7734     /**
7735      * Returns the default network type for the given {@code subId}, if the default network type is
7736      * not set, return {@link Phone#PREFERRED_NT_MODE}.
7737      */
getDefaultNetworkType(int subId)7738     private int getDefaultNetworkType(int subId) {
7739         List<Integer> list = TelephonyProperties.default_network();
7740         int phoneId = mSubscriptionController.getPhoneId(subId);
7741         if (phoneId >= 0 && phoneId < list.size() && list.get(phoneId) != null) {
7742             return list.get(phoneId);
7743         }
7744         return Phone.PREFERRED_NT_MODE;
7745     }
7746 
7747     @Override
setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn)7748     public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
7749             gid1, String gid2, String plmn, String spn, String carrierPrivilegeRules, String apn) {
7750         enforceModifyPermission();
7751 
7752         final long identity = Binder.clearCallingIdentity();
7753         try {
7754             final Phone phone = getPhone(subId);
7755             if (phone == null) {
7756                 loge("setCarrierTestOverride fails with invalid subId: " + subId);
7757                 return;
7758             }
7759             phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn,
7760                     carrierPrivilegeRules, apn);
7761         } finally {
7762             Binder.restoreCallingIdentity(identity);
7763         }
7764     }
7765 
7766     @Override
getCarrierIdListVersion(int subId)7767     public int getCarrierIdListVersion(int subId) {
7768         enforceReadPrivilegedPermission("getCarrierIdListVersion");
7769 
7770         final long identity = Binder.clearCallingIdentity();
7771         try {
7772             final Phone phone = getPhone(subId);
7773             if (phone == null) {
7774                 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
7775                 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
7776             }
7777             return phone.getCarrierIdListVersion();
7778         } finally {
7779             Binder.restoreCallingIdentity(identity);
7780         }
7781     }
7782 
7783     @Override
getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage, String callingFeatureId)7784     public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage,
7785             String callingFeatureId) {
7786         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
7787                 mApp, subId, callingPackage, callingFeatureId,
7788                 "getNumberOfModemsWithSimultaneousDataConnections")) {
7789             return -1;
7790         }
7791 
7792         final long identity = Binder.clearCallingIdentity();
7793         try {
7794             return mPhoneConfigurationManager.getNumberOfModemsWithSimultaneousDataConnections();
7795         } finally {
7796             Binder.restoreCallingIdentity(identity);
7797         }
7798     }
7799 
7800     @Override
getCdmaRoamingMode(int subId)7801     public int getCdmaRoamingMode(int subId) {
7802         TelephonyPermissions
7803                 .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
7804                 mApp, subId, "getCdmaRoamingMode");
7805 
7806         final long identity = Binder.clearCallingIdentity();
7807         try {
7808             return (int) sendRequest(CMD_GET_CDMA_ROAMING_MODE, null /* argument */, subId);
7809         } finally {
7810             Binder.restoreCallingIdentity(identity);
7811         }
7812     }
7813 
7814     @Override
setCdmaRoamingMode(int subId, int mode)7815     public boolean setCdmaRoamingMode(int subId, int mode) {
7816         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7817                 mApp, subId, "setCdmaRoamingMode");
7818 
7819         final long identity = Binder.clearCallingIdentity();
7820         try {
7821             return (boolean) sendRequest(CMD_SET_CDMA_ROAMING_MODE, mode, subId);
7822         } finally {
7823             Binder.restoreCallingIdentity(identity);
7824         }
7825     }
7826 
7827     @Override
setCdmaSubscriptionMode(int subId, int mode)7828     public boolean setCdmaSubscriptionMode(int subId, int mode) {
7829         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
7830                 mApp, subId, "setCdmaSubscriptionMode");
7831 
7832         final long identity = Binder.clearCallingIdentity();
7833         try {
7834             return (boolean) sendRequest(CMD_SET_CDMA_SUBSCRIPTION_MODE, mode, subId);
7835         } finally {
7836             Binder.restoreCallingIdentity(identity);
7837         }
7838     }
7839 
7840     @Override
getEmergencyNumberList( String callingPackage, String callingFeatureId)7841     public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
7842             String callingPackage, String callingFeatureId) {
7843         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
7844                 mApp, getDefaultSubscription(), callingPackage, callingFeatureId,
7845                 "getEmergencyNumberList")) {
7846             throw new SecurityException("Requires READ_PHONE_STATE permission.");
7847         }
7848         final long identity = Binder.clearCallingIdentity();
7849         try {
7850             Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
7851             for (Phone phone: PhoneFactory.getPhones()) {
7852                 if (phone.getEmergencyNumberTracker() != null
7853                         && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
7854                     emergencyNumberListInternal.put(
7855                             phone.getSubId(),
7856                             phone.getEmergencyNumberTracker().getEmergencyNumberList());
7857                 }
7858             }
7859             return emergencyNumberListInternal;
7860         } finally {
7861             Binder.restoreCallingIdentity(identity);
7862         }
7863     }
7864 
7865     @Override
isEmergencyNumber(String number, boolean exactMatch)7866     public boolean isEmergencyNumber(String number, boolean exactMatch) {
7867         final Phone defaultPhone = getDefaultPhone();
7868         if (!exactMatch) {
7869             TelephonyPermissions
7870                     .enforeceCallingOrSelfReadPrivilegedPhoneStatePermissionOrCarrierPrivilege(
7871                             mApp, defaultPhone.getSubId(), "isEmergencyNumber(Potential)");
7872         }
7873         final long identity = Binder.clearCallingIdentity();
7874         try {
7875             for (Phone phone: PhoneFactory.getPhones()) {
7876                 if (phone.getEmergencyNumberTracker() != null
7877                         && phone.getEmergencyNumberTracker() != null) {
7878                     if (phone.getEmergencyNumberTracker().isEmergencyNumber(
7879                             number, exactMatch)) {
7880                         return true;
7881                     }
7882                 }
7883             }
7884             return false;
7885         } finally {
7886             Binder.restoreCallingIdentity(identity);
7887         }
7888     }
7889 
7890     /**
7891      * Start emergency callback mode for GsmCdmaPhone for testing.
7892      */
7893     @Override
startEmergencyCallbackMode()7894     public void startEmergencyCallbackMode() {
7895         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
7896                 "startEmergencyCallbackMode");
7897         enforceModifyPermission();
7898         final long identity = Binder.clearCallingIdentity();
7899         try {
7900             for (Phone phone : PhoneFactory.getPhones()) {
7901                 Rlog.d(LOG_TAG, "startEmergencyCallbackMode phone type: " + phone.getPhoneType());
7902                 if (phone != null && ((phone.getPhoneType() == PHONE_TYPE_GSM)
7903                         || (phone.getPhoneType() == PHONE_TYPE_CDMA))) {
7904                     GsmCdmaPhone gsmCdmaPhone = (GsmCdmaPhone) phone;
7905                     gsmCdmaPhone.obtainMessage(
7906                             GsmCdmaPhone.EVENT_EMERGENCY_CALLBACK_MODE_ENTER).sendToTarget();
7907                     Rlog.d(LOG_TAG, "startEmergencyCallbackMode: triggered");
7908                 }
7909             }
7910         } finally {
7911             Binder.restoreCallingIdentity(identity);
7912         }
7913     }
7914 
7915     /**
7916      * Update emergency number list for test mode.
7917      */
7918     @Override
updateEmergencyNumberListTestMode(int action, EmergencyNumber num)7919     public void updateEmergencyNumberListTestMode(int action, EmergencyNumber num) {
7920         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
7921                 "updateEmergencyNumberListTestMode");
7922 
7923         final long identity = Binder.clearCallingIdentity();
7924         try {
7925             for (Phone phone: PhoneFactory.getPhones()) {
7926                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
7927                 if (tracker != null) {
7928                     tracker.executeEmergencyNumberTestModeCommand(action, num);
7929                 }
7930             }
7931         } finally {
7932             Binder.restoreCallingIdentity(identity);
7933         }
7934     }
7935 
7936     /**
7937      * Get the full emergency number list for test mode.
7938      */
7939     @Override
getEmergencyNumberListTestMode()7940     public List<String> getEmergencyNumberListTestMode() {
7941         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
7942                 "getEmergencyNumberListTestMode");
7943 
7944         final long identity = Binder.clearCallingIdentity();
7945         try {
7946             Set<String> emergencyNumbers = new HashSet<>();
7947             for (Phone phone: PhoneFactory.getPhones()) {
7948                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
7949                 if (tracker != null) {
7950                     for (EmergencyNumber num : tracker.getEmergencyNumberList()) {
7951                         emergencyNumbers.add(num.getNumber());
7952                     }
7953                 }
7954             }
7955             return new ArrayList<>(emergencyNumbers);
7956         } finally {
7957             Binder.restoreCallingIdentity(identity);
7958         }
7959     }
7960 
7961     @Override
getEmergencyNumberDbVersion(int subId)7962     public int getEmergencyNumberDbVersion(int subId) {
7963         enforceReadPrivilegedPermission("getEmergencyNumberDbVersion");
7964 
7965         final long identity = Binder.clearCallingIdentity();
7966         try {
7967             final Phone phone = getPhone(subId);
7968             if (phone == null) {
7969                 loge("getEmergencyNumberDbVersion fails with invalid subId: " + subId);
7970                 return TelephonyManager.INVALID_EMERGENCY_NUMBER_DB_VERSION;
7971             }
7972             return phone.getEmergencyNumberDbVersion();
7973         } finally {
7974             Binder.restoreCallingIdentity(identity);
7975         }
7976     }
7977 
7978     @Override
notifyOtaEmergencyNumberDbInstalled()7979     public void notifyOtaEmergencyNumberDbInstalled() {
7980         enforceModifyPermission();
7981 
7982         final long identity = Binder.clearCallingIdentity();
7983         try {
7984             for (Phone phone: PhoneFactory.getPhones()) {
7985                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
7986                 if (tracker != null) {
7987                     tracker.updateOtaEmergencyNumberDatabase();
7988                 }
7989             }
7990         } finally {
7991             Binder.restoreCallingIdentity(identity);
7992         }
7993     }
7994 
7995     @Override
updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor)7996     public void updateOtaEmergencyNumberDbFilePath(ParcelFileDescriptor otaParcelFileDescriptor) {
7997         enforceActiveEmergencySessionPermission();
7998 
7999         final long identity = Binder.clearCallingIdentity();
8000         try {
8001             for (Phone phone: PhoneFactory.getPhones()) {
8002                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
8003                 if (tracker != null) {
8004                     tracker.updateOtaEmergencyNumberDbFilePath(otaParcelFileDescriptor);
8005                 }
8006             }
8007         } finally {
8008             Binder.restoreCallingIdentity(identity);
8009         }
8010     }
8011 
8012     @Override
resetOtaEmergencyNumberDbFilePath()8013     public void resetOtaEmergencyNumberDbFilePath() {
8014         enforceActiveEmergencySessionPermission();
8015 
8016         final long identity = Binder.clearCallingIdentity();
8017         try {
8018             for (Phone phone: PhoneFactory.getPhones()) {
8019                 EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
8020                 if (tracker != null) {
8021                     tracker.resetOtaEmergencyNumberDbFilePath();
8022                 }
8023             }
8024         } finally {
8025             Binder.restoreCallingIdentity(identity);
8026         }
8027     }
8028 
8029     @Override
getCertsFromCarrierPrivilegeAccessRules(int subId)8030     public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
8031         enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
8032         Phone phone = getPhone(subId);
8033         if (phone == null) {
8034             return null;
8035         }
8036         final long identity = Binder.clearCallingIdentity();
8037         try {
8038             UiccProfile profile = UiccController.getInstance()
8039                     .getUiccProfileForPhone(phone.getPhoneId());
8040             if (profile != null) {
8041                 return profile.getCertsFromCarrierPrivilegeAccessRules();
8042             }
8043         } finally {
8044             Binder.restoreCallingIdentity(identity);
8045         }
8046         return null;
8047     }
8048 
8049     /**
8050      * Enable or disable a modem stack.
8051      */
8052     @Override
enableModemForSlot(int slotIndex, boolean enable)8053     public boolean enableModemForSlot(int slotIndex, boolean enable) {
8054         enforceModifyPermission();
8055 
8056         final long identity = Binder.clearCallingIdentity();
8057         try {
8058             Phone phone = PhoneFactory.getPhone(slotIndex);
8059             if (phone == null) {
8060                 return false;
8061             } else {
8062                 return (Boolean) sendRequest(CMD_REQUEST_ENABLE_MODEM, enable, phone, null);
8063             }
8064         } finally {
8065             Binder.restoreCallingIdentity(identity);
8066         }
8067     }
8068 
8069     /**
8070      * Whether a modem stack is enabled or not.
8071      */
8072     @Override
isModemEnabledForSlot(int slotIndex, String callingPackage, String callingFeatureId)8073     public boolean isModemEnabledForSlot(int slotIndex, String callingPackage,
8074             String callingFeatureId) {
8075         Phone phone = PhoneFactory.getPhone(slotIndex);
8076         if (phone == null) return false;
8077 
8078         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
8079                 mApp, phone.getSubId(), callingPackage, callingFeatureId,
8080                 "isModemEnabledForSlot")) {
8081             throw new SecurityException("Requires READ_PHONE_STATE permission.");
8082         }
8083 
8084         final long identity = Binder.clearCallingIdentity();
8085         try {
8086             try {
8087                 return mPhoneConfigurationManager.getPhoneStatusFromCache(phone.getPhoneId());
8088             } catch (NoSuchElementException ex) {
8089                 return (Boolean) sendRequest(CMD_GET_MODEM_STATUS, null, phone, null);
8090             }
8091         } finally {
8092             Binder.restoreCallingIdentity(identity);
8093         }
8094     }
8095 
8096     @Override
setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted)8097     public void setMultiSimCarrierRestriction(boolean isMultiSimCarrierRestricted) {
8098         enforceModifyPermission();
8099 
8100         final long identity = Binder.clearCallingIdentity();
8101         try {
8102             mTelephonySharedPreferences.edit()
8103                     .putBoolean(PREF_MULTI_SIM_RESTRICTED, isMultiSimCarrierRestricted)
8104                     .commit();
8105         } finally {
8106             Binder.restoreCallingIdentity(identity);
8107         }
8108     }
8109 
8110     @Override
8111     @TelephonyManager.IsMultiSimSupportedResult
isMultiSimSupported(String callingPackage, String callingFeatureId)8112     public int isMultiSimSupported(String callingPackage, String callingFeatureId) {
8113         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
8114                 getDefaultPhone().getSubId(), callingPackage, callingFeatureId,
8115                 "isMultiSimSupported")) {
8116             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
8117         }
8118 
8119         final long identity = Binder.clearCallingIdentity();
8120         try {
8121             return isMultiSimSupportedInternal();
8122         } finally {
8123             Binder.restoreCallingIdentity(identity);
8124         }
8125     }
8126 
8127     @TelephonyManager.IsMultiSimSupportedResult
isMultiSimSupportedInternal()8128     private int isMultiSimSupportedInternal() {
8129         // If the device has less than 2 SIM cards, indicate that multisim is restricted.
8130         int numPhysicalSlots = UiccController.getInstance().getUiccSlots().length;
8131         if (numPhysicalSlots < 2) {
8132             loge("isMultiSimSupportedInternal: requires at least 2 cards");
8133             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
8134         }
8135         // Check if the hardware supports multisim functionality. If usage of multisim is not
8136         // supported by the modem, indicate that it is restricted.
8137         PhoneCapability staticCapability =
8138                 mPhoneConfigurationManager.getStaticPhoneCapability();
8139         if (staticCapability == null) {
8140             loge("isMultiSimSupportedInternal: no static configuration available");
8141             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
8142         }
8143         if (staticCapability.logicalModemList.size() < 2) {
8144             loge("isMultiSimSupportedInternal: maximum number of modem is < 2");
8145             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
8146         }
8147         // Check if support of multiple SIMs is restricted by carrier
8148         if (mTelephonySharedPreferences.getBoolean(PREF_MULTI_SIM_RESTRICTED, false)) {
8149             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_CARRIER;
8150         }
8151 
8152         return TelephonyManager.MULTISIM_ALLOWED;
8153     }
8154 
8155     /**
8156      * Switch configs to enable multi-sim or switch back to single-sim
8157      * Note: Switch from multi-sim to single-sim is only possible with MODIFY_PHONE_STATE
8158      * permission, but the other way around is possible with either MODIFY_PHONE_STATE
8159      * or carrier privileges
8160      * @param numOfSims number of active sims we want to switch to
8161      */
8162     @Override
switchMultiSimConfig(int numOfSims)8163     public void switchMultiSimConfig(int numOfSims) {
8164         if (numOfSims == 1) {
8165             enforceModifyPermission();
8166         } else {
8167             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8168                     mApp, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, "switchMultiSimConfig");
8169         }
8170         final long identity = Binder.clearCallingIdentity();
8171 
8172         try {
8173             //only proceed if multi-sim is not restricted
8174             if (isMultiSimSupportedInternal() != TelephonyManager.MULTISIM_ALLOWED) {
8175                 loge("switchMultiSimConfig not possible. It is restricted or not supported.");
8176                 return;
8177             }
8178             mPhoneConfigurationManager.switchMultiSimConfig(numOfSims);
8179         } finally {
8180             Binder.restoreCallingIdentity(identity);
8181         }
8182     }
8183 
8184     @Override
isApplicationOnUicc(int subId, int appType)8185     public boolean isApplicationOnUicc(int subId, int appType) {
8186         enforceReadPrivilegedPermission("isApplicationOnUicc");
8187         Phone phone = getPhone(subId);
8188         if (phone == null) {
8189             return false;
8190         }
8191         final long identity = Binder.clearCallingIdentity();
8192         try {
8193             UiccCard uiccCard = phone.getUiccCard();
8194             if (uiccCard == null) {
8195                 return false;
8196             }
8197             UiccProfile uiccProfile = uiccCard.getUiccProfile();
8198             if (uiccProfile == null) {
8199                 return false;
8200             }
8201             if (TelephonyManager.APPTYPE_SIM <= appType
8202                     && appType <= TelephonyManager.APPTYPE_ISIM) {
8203                 return uiccProfile.isApplicationOnIcc(AppType.values()[appType]);
8204             }
8205             return false;
8206         } finally {
8207             Binder.restoreCallingIdentity(identity);
8208         }
8209     }
8210 
8211     /**
8212      * Get whether making changes to modem configurations will trigger reboot.
8213      * Return value defaults to true.
8214      */
8215     @Override
doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage, String callingFeatureId)8216     public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage,
8217             String callingFeatureId) {
8218         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
8219                 mApp, subId, callingPackage, callingFeatureId,
8220                 "doesSwitchMultiSimConfigTriggerReboot")) {
8221             return false;
8222         }
8223         final long identity = Binder.clearCallingIdentity();
8224         try {
8225             return mPhoneConfigurationManager.isRebootRequiredForModemConfigChange();
8226         } finally {
8227             Binder.restoreCallingIdentity(identity);
8228         }
8229     }
8230 
updateModemStateMetrics()8231     private void updateModemStateMetrics() {
8232         TelephonyMetrics metrics = TelephonyMetrics.getInstance();
8233         // TODO: check the state for each modem if the api is ready.
8234         metrics.updateEnabledModemBitmap((1 << TelephonyManager.from(mApp).getPhoneCount()) - 1);
8235     }
8236 
8237     @Override
getSlotsMapping()8238     public int[] getSlotsMapping() {
8239         enforceReadPrivilegedPermission("getSlotsMapping");
8240 
8241         final long identity = Binder.clearCallingIdentity();
8242         try {
8243             int phoneCount = TelephonyManager.getDefault().getPhoneCount();
8244             // All logical slots should have a mapping to a physical slot.
8245             int[] logicalSlotsMapping = new int[phoneCount];
8246             UiccSlotInfo[] slotInfos = getUiccSlotsInfo();
8247             for (int i = 0; i < slotInfos.length; i++) {
8248                 if (SubscriptionManager.isValidPhoneId(slotInfos[i].getLogicalSlotIdx())) {
8249                     logicalSlotsMapping[slotInfos[i].getLogicalSlotIdx()] = i;
8250                 }
8251             }
8252             return logicalSlotsMapping;
8253         } finally {
8254             Binder.restoreCallingIdentity(identity);
8255         }
8256     }
8257 
8258     /**
8259      * Get the IRadio HAL Version
8260      */
8261     @Override
getRadioHalVersion()8262     public int getRadioHalVersion() {
8263         Phone phone = getDefaultPhone();
8264         if (phone == null) return -1;
8265         HalVersion hv = phone.getHalVersion();
8266         if (hv.equals(HalVersion.UNKNOWN)) return -1;
8267         return hv.major * 100 + hv.minor;
8268     }
8269 
8270     /**
8271      * Get the current calling package name.
8272      * @return the current calling package name
8273      */
8274     @Override
getCurrentPackageName()8275     public String getCurrentPackageName() {
8276         return mApp.getPackageManager().getPackagesForUid(Binder.getCallingUid())[0];
8277     }
8278 
8279     /**
8280      * Return whether data is enabled for certain APN type. This will tell if framework will accept
8281      * corresponding network requests on a subId.
8282      *
8283      *  Data is enabled if:
8284      *  1) user data is turned on, or
8285      *  2) APN is un-metered for this subscription, or
8286      *  3) APN type is whitelisted. E.g. MMS is whitelisted if
8287      *  {@link TelephonyManager#setAlwaysAllowMmsData} is turned on.
8288      *
8289      * @return whether data is allowed for a apn type.
8290      *
8291      * @hide
8292      */
8293     @Override
isDataEnabledForApn(int apnType, int subId, String callingPackage)8294     public boolean isDataEnabledForApn(int apnType, int subId, String callingPackage) {
8295         enforceReadPrivilegedPermission("Needs READ_PRIVILEGED_PHONE_STATE for "
8296                 + "isDataEnabledForApn");
8297 
8298         // Now that all security checks passes, perform the operation as ourselves.
8299         final long identity = Binder.clearCallingIdentity();
8300         try {
8301             Phone phone = getPhone(subId);
8302             if (phone == null) return false;
8303 
8304             boolean isMetered = ApnSettingUtils.isMeteredApnType(apnType, phone);
8305             return !isMetered || phone.getDataEnabledSettings().isDataEnabled(apnType);
8306         } finally {
8307             Binder.restoreCallingIdentity(identity);
8308         }
8309     }
8310 
8311     @Override
isApnMetered(@pnType int apnType, int subId)8312     public boolean isApnMetered(@ApnType int apnType, int subId) {
8313         enforceReadPrivilegedPermission("isApnMetered");
8314 
8315         // Now that all security checks passes, perform the operation as ourselves.
8316         final long identity = Binder.clearCallingIdentity();
8317         try {
8318             Phone phone = getPhone(subId);
8319             if (phone == null) return true; // By default return true.
8320 
8321             return ApnSettingUtils.isMeteredApnType(apnType, phone);
8322         } finally {
8323             Binder.restoreCallingIdentity(identity);
8324         }
8325     }
8326 
8327     @Override
setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers, int subscriptionId, IBooleanConsumer resultCallback)8328     public void setSystemSelectionChannels(List<RadioAccessSpecifier> specifiers,
8329             int subscriptionId, IBooleanConsumer resultCallback) {
8330         enforceModifyPermission();
8331         long token = Binder.clearCallingIdentity();
8332         try {
8333             Phone phone = getPhone(subscriptionId);
8334             if (phone == null) {
8335                 try {
8336                     if (resultCallback != null) {
8337                         resultCallback.accept(false);
8338                     }
8339                 } catch (RemoteException e) {
8340                     // ignore
8341                 }
8342                 return;
8343             }
8344             Pair<List<RadioAccessSpecifier>, Consumer<Boolean>> argument =
8345                     Pair.create(specifiers, (x) -> {
8346                         try {
8347                             if (resultCallback != null) {
8348                                 resultCallback.accept(x);
8349                             }
8350                         } catch (RemoteException e) {
8351                             // ignore
8352                         }
8353                     });
8354             sendRequestAsync(CMD_SET_SYSTEM_SELECTION_CHANNELS, argument, phone, null);
8355         } finally {
8356             Binder.restoreCallingIdentity(token);
8357         }
8358     }
8359 
8360     @Override
isMvnoMatched(int subId, int mvnoType, @NonNull String mvnoMatchData)8361     public boolean isMvnoMatched(int subId, int mvnoType, @NonNull String mvnoMatchData) {
8362         enforceReadPrivilegedPermission("isMvnoMatched");
8363         IccRecords iccRecords = UiccController.getInstance().getIccRecords(
8364                 SubscriptionManager.getPhoneId(subId), UiccController.APP_FAM_3GPP);
8365         if (iccRecords == null) {
8366             Log.d(LOG_TAG, "isMvnoMatched# IccRecords is null");
8367             return false;
8368         }
8369         return ApnSettingUtils.mvnoMatches(iccRecords, mvnoType, mvnoMatchData);
8370     }
8371 
8372     @Override
enqueueSmsPickResult(String callingPackage, String callingAttributionTag, IIntegerConsumer pendingSubIdResult)8373     public void enqueueSmsPickResult(String callingPackage, String callingAttributionTag,
8374             IIntegerConsumer pendingSubIdResult) {
8375         if (callingPackage == null) {
8376             callingPackage = getCurrentPackageName();
8377         }
8378         SmsPermissions permissions = new SmsPermissions(getDefaultPhone(), mApp,
8379                 (AppOpsManager) mApp.getSystemService(Context.APP_OPS_SERVICE));
8380         if (!permissions.checkCallingCanSendSms(callingPackage, callingAttributionTag,
8381                 "Sending message")) {
8382             throw new SecurityException("Requires SEND_SMS permission to perform this operation");
8383         }
8384         PickSmsSubscriptionActivity.addPendingResult(pendingSubIdResult);
8385         Intent intent = new Intent();
8386         intent.setClass(mApp, PickSmsSubscriptionActivity.class);
8387         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8388         // Bring up choose default SMS subscription dialog right now
8389         intent.putExtra(PickSmsSubscriptionActivity.DIALOG_TYPE_KEY,
8390                 PickSmsSubscriptionActivity.SMS_PICK_FOR_MESSAGE);
8391         mApp.startActivity(intent);
8392     }
8393 
8394     @Override
getMmsUAProfUrl(int subId)8395     public String getMmsUAProfUrl(int subId) {
8396         //TODO investigate if this API should require proper permission check in R b/133791609
8397         final long identity = Binder.clearCallingIdentity();
8398         try {
8399             return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
8400                     .getString(com.android.internal.R.string.config_mms_user_agent_profile_url);
8401         } finally {
8402             Binder.restoreCallingIdentity(identity);
8403         }
8404     }
8405 
8406     @Override
getMmsUserAgent(int subId)8407     public String getMmsUserAgent(int subId) {
8408         //TODO investigate if this API should require proper permission check in R b/133791609
8409         final long identity = Binder.clearCallingIdentity();
8410         try {
8411             return SubscriptionManager.getResourcesForSubId(getDefaultPhone().getContext(), subId)
8412                     .getString(com.android.internal.R.string.config_mms_user_agent);
8413         } finally {
8414             Binder.restoreCallingIdentity(identity);
8415         }
8416     }
8417 
8418     @Override
setDataAllowedDuringVoiceCall(int subId, boolean allow)8419     public boolean setDataAllowedDuringVoiceCall(int subId, boolean allow) {
8420         enforceModifyPermission();
8421 
8422         // Now that all security checks passes, perform the operation as ourselves.
8423         final long identity = Binder.clearCallingIdentity();
8424         try {
8425             Phone phone = getPhone(subId);
8426             if (phone == null) return false;
8427 
8428             return phone.getDataEnabledSettings().setAllowDataDuringVoiceCall(allow);
8429         } finally {
8430             Binder.restoreCallingIdentity(identity);
8431         }
8432     }
8433 
8434     @Override
isDataAllowedInVoiceCall(int subId)8435     public boolean isDataAllowedInVoiceCall(int subId) {
8436         enforceReadPrivilegedPermission("isDataAllowedInVoiceCall");
8437 
8438         // Now that all security checks passes, perform the operation as ourselves.
8439         final long identity = Binder.clearCallingIdentity();
8440         try {
8441             Phone phone = getPhone(subId);
8442             if (phone == null) return false;
8443 
8444             return phone.getDataEnabledSettings().isDataAllowedInVoiceCall();
8445         } finally {
8446             Binder.restoreCallingIdentity(identity);
8447         }
8448     }
8449 
8450     @Override
setAlwaysAllowMmsData(int subId, boolean alwaysAllow)8451     public boolean setAlwaysAllowMmsData(int subId, boolean alwaysAllow) {
8452         enforceModifyPermission();
8453 
8454         // Now that all security checks passes, perform the operation as ourselves.
8455         final long identity = Binder.clearCallingIdentity();
8456         try {
8457             Phone phone = getPhone(subId);
8458             if (phone == null) return false;
8459 
8460             return phone.getDataEnabledSettings().setAlwaysAllowMmsData(alwaysAllow);
8461         } finally {
8462             Binder.restoreCallingIdentity(identity);
8463         }
8464     }
8465 
8466     /**
8467      * Updates whether conference event pacakge handling is enabled.
8468      * @param isCepEnabled {@code true} if CEP handling is enabled (default), or {@code false}
8469      *                                 otherwise.
8470      */
8471     @Override
setCepEnabled(boolean isCepEnabled)8472     public void setCepEnabled(boolean isCepEnabled) {
8473         TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(), "setCepEnabled");
8474 
8475         final long identity = Binder.clearCallingIdentity();
8476         try {
8477             Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled);
8478             for (Phone phone : PhoneFactory.getPhones()) {
8479                 Phone defaultPhone = phone.getImsPhone();
8480                 if (defaultPhone != null && defaultPhone.getPhoneType() == PHONE_TYPE_IMS) {
8481                     ImsPhone imsPhone = (ImsPhone) defaultPhone;
8482                     ImsPhoneCallTracker imsPhoneCallTracker =
8483                             (ImsPhoneCallTracker) imsPhone.getCallTracker();
8484                     imsPhoneCallTracker.setConferenceEventPackageEnabled(isCepEnabled);
8485                     Rlog.i(LOG_TAG, "setCepEnabled isCepEnabled=" + isCepEnabled + ", for imsPhone "
8486                             + imsPhone.getMsisdn());
8487                 }
8488             }
8489         } finally {
8490             Binder.restoreCallingIdentity(identity);
8491         }
8492     }
8493 
8494     /**
8495      * Notify that an RCS autoconfiguration XML file has been received for provisioning.
8496      *
8497      * @param config       The XML file to be read. ASCII/UTF8 encoded text if not compressed.
8498      * @param isCompressed The XML file is compressed in gzip format and must be decompressed
8499      *                     before being read.
8500      */
8501     @Override
notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean isCompressed)8502     public void notifyRcsAutoConfigurationReceived(int subId, @NonNull byte[] config, boolean
8503             isCompressed) {
8504         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
8505                 mApp, subId, "notifyRcsAutoConfigurationReceived");
8506         try {
8507             IImsConfig configBinder = getImsConfig(getSlotIndex(subId), ImsFeature.FEATURE_RCS);
8508             if (configBinder == null) {
8509                 Rlog.e(LOG_TAG, "null result for getImsConfig");
8510             } else {
8511                 configBinder.notifyRcsAutoConfigurationReceived(config, isCompressed);
8512             }
8513         } catch (RemoteException e) {
8514             Rlog.e(LOG_TAG, "fail to getImsConfig " + e.getMessage());
8515         }
8516     }
8517 
8518     @Override
isIccLockEnabled(int subId)8519     public boolean isIccLockEnabled(int subId) {
8520         enforceReadPrivilegedPermission("isIccLockEnabled");
8521 
8522         // Now that all security checks passes, perform the operation as ourselves.
8523         final long identity = Binder.clearCallingIdentity();
8524         try {
8525             Phone phone = getPhone(subId);
8526             if (phone != null && phone.getIccCard() != null) {
8527                 return phone.getIccCard().getIccLockEnabled();
8528             } else {
8529                 return false;
8530             }
8531         } finally {
8532             Binder.restoreCallingIdentity(identity);
8533         }
8534     }
8535 
8536     /**
8537      * Set the ICC pin lock enabled or disabled.
8538      *
8539      * @return an integer representing the status of IccLock enabled or disabled in the following
8540      * three cases:
8541      *   - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if enabled or disabled IccLock
8542      *   successfully.
8543      *   - Positive number and zero for remaining password attempts.
8544      *   - Negative number for other failure cases (such like enabling/disabling PIN failed).
8545      *
8546      */
8547     @Override
setIccLockEnabled(int subId, boolean enabled, String password)8548     public int setIccLockEnabled(int subId, boolean enabled, String password) {
8549         enforceModifyPermission();
8550 
8551         Phone phone = getPhone(subId);
8552         if (phone == null) {
8553             return 0;
8554         }
8555         // Now that all security checks passes, perform the operation as ourselves.
8556         final long identity = Binder.clearCallingIdentity();
8557         try {
8558             int attemptsRemaining = (int) sendRequest(CMD_SET_ICC_LOCK_ENABLED,
8559                     new Pair<Boolean, String>(enabled, password), phone, null);
8560             return attemptsRemaining;
8561 
8562         } catch (Exception e) {
8563             Log.e(LOG_TAG, "setIccLockEnabled. Exception e =" + e);
8564         } finally {
8565             Binder.restoreCallingIdentity(identity);
8566         }
8567         return 0;
8568     }
8569 
8570     /**
8571      * Change the ICC password used in ICC pin lock.
8572      *
8573      * @return an integer representing the status of IccLock changed in the following three cases:
8574      *   - {@link TelephonyManager#CHANGE_ICC_LOCK_SUCCESS} if changed IccLock successfully.
8575      *   - Positive number and zero for remaining password attempts.
8576      *   - Negative number for other failure cases (such like enabling/disabling PIN failed).
8577      *
8578      */
8579     @Override
changeIccLockPassword(int subId, String oldPassword, String newPassword)8580     public int changeIccLockPassword(int subId, String oldPassword, String newPassword) {
8581         enforceModifyPermission();
8582 
8583         Phone phone = getPhone(subId);
8584         if (phone == null) {
8585             return 0;
8586         }
8587         // Now that all security checks passes, perform the operation as ourselves.
8588         final long identity = Binder.clearCallingIdentity();
8589         try {
8590             int attemptsRemaining = (int) sendRequest(CMD_CHANGE_ICC_LOCK_PASSWORD,
8591                     new Pair<String, String>(oldPassword, newPassword), phone, null);
8592             return attemptsRemaining;
8593 
8594         } catch (Exception e) {
8595             Log.e(LOG_TAG, "changeIccLockPassword. Exception e =" + e);
8596         } finally {
8597             Binder.restoreCallingIdentity(identity);
8598         }
8599         return 0;
8600     }
8601 
8602     /**
8603      * Request for receiving user activity notification
8604      */
8605     @Override
requestUserActivityNotification()8606     public void requestUserActivityNotification() {
8607         if (!mNotifyUserActivity.get()
8608                 && !mMainThreadHandler.hasMessages(MSG_NOTIFY_USER_ACTIVITY)) {
8609             mNotifyUserActivity.set(true);
8610         }
8611     }
8612 
8613     /**
8614      * Called when userActivity is signalled in the power manager.
8615      * This is safe to call from any thread, with any window manager locks held or not.
8616      */
8617     @Override
userActivity()8618     public void userActivity() {
8619         // ***************************************
8620         // *  Inherited from PhoneWindowManager  *
8621         // ***************************************
8622         // THIS IS CALLED FROM DEEP IN THE POWER MANAGER
8623         // WITH ITS LOCKS HELD.
8624         //
8625         // This code must be VERY careful about the locks
8626         // it acquires.
8627         // In fact, the current code acquires way too many,
8628         // and probably has lurking deadlocks.
8629 
8630         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
8631             throw new SecurityException("Only the OS may call notifyUserActivity()");
8632         }
8633 
8634         if (mNotifyUserActivity.getAndSet(false)) {
8635             mMainThreadHandler.sendEmptyMessageDelayed(MSG_NOTIFY_USER_ACTIVITY,
8636                     USER_ACTIVITY_NOTIFICATION_DELAY);
8637         }
8638     }
8639 
8640     @Override
canConnectTo5GInDsdsMode()8641     public boolean canConnectTo5GInDsdsMode() {
8642         return mApp.getResources().getBoolean(R.bool.config_5g_connection_in_dsds_mode);
8643     }
8644 }
8645