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