• 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 com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
20 
21 import android.Manifest.permission;
22 import android.app.AppOpsManager;
23 import android.app.PendingIntent;
24 import android.content.ComponentName;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.SharedPreferences;
28 import android.content.pm.ComponentInfo;
29 import android.content.pm.PackageInfo;
30 import android.content.pm.PackageManager;
31 import android.net.NetworkStats;
32 import android.net.Uri;
33 import android.os.AsyncResult;
34 import android.os.Binder;
35 import android.os.Bundle;
36 import android.os.Handler;
37 import android.os.IBinder;
38 import android.os.Looper;
39 import android.os.Message;
40 import android.os.Messenger;
41 import android.os.PersistableBundle;
42 import android.os.RemoteException;
43 import android.os.ResultReceiver;
44 import android.os.ServiceManager;
45 import android.os.ShellCallback;
46 import android.os.SystemProperties;
47 import android.os.UserHandle;
48 import android.os.UserManager;
49 import android.os.WorkSource;
50 import android.preference.PreferenceManager;
51 import android.provider.Settings;
52 import android.service.carrier.CarrierIdentifier;
53 import android.telecom.PhoneAccount;
54 import android.telecom.PhoneAccountHandle;
55 import android.telecom.TelecomManager;
56 import android.telephony.CarrierConfigManager;
57 import android.telephony.CellInfo;
58 import android.telephony.ClientRequestStats;
59 import android.telephony.IccOpenLogicalChannelResponse;
60 import android.telephony.LocationAccessPolicy;
61 import android.telephony.ModemActivityInfo;
62 import android.telephony.NeighboringCellInfo;
63 import android.telephony.NetworkScanRequest;
64 import android.telephony.RadioAccessFamily;
65 import android.telephony.Rlog;
66 import android.telephony.ServiceState;
67 import android.telephony.SignalStrength;
68 import android.telephony.SmsManager;
69 import android.telephony.SubscriptionInfo;
70 import android.telephony.SubscriptionManager;
71 import android.telephony.TelephonyHistogram;
72 import android.telephony.TelephonyManager;
73 import android.telephony.UiccSlotInfo;
74 import android.telephony.UssdResponse;
75 import android.telephony.VisualVoicemailSmsFilterSettings;
76 import android.telephony.ims.aidl.IImsConfig;
77 import android.telephony.ims.aidl.IImsMmTelFeature;
78 import android.telephony.ims.aidl.IImsRcsFeature;
79 import android.telephony.ims.aidl.IImsRegistration;
80 import android.telephony.ims.stub.ImsRegistrationImplBase;
81 import android.text.TextUtils;
82 import android.util.ArraySet;
83 import android.util.EventLog;
84 import android.util.Log;
85 import android.util.Pair;
86 import android.util.Slog;
87 
88 import com.android.ims.ImsManager;
89 import com.android.ims.internal.IImsServiceFeatureCallback;
90 import com.android.internal.telephony.CallManager;
91 import com.android.internal.telephony.CallStateException;
92 import com.android.internal.telephony.CarrierInfoManager;
93 import com.android.internal.telephony.CellNetworkScanResult;
94 import com.android.internal.telephony.CommandException;
95 import com.android.internal.telephony.DefaultPhoneNotifier;
96 import com.android.internal.telephony.ITelephony;
97 import com.android.internal.telephony.IccCard;
98 import com.android.internal.telephony.LocaleTracker;
99 import com.android.internal.telephony.MccTable;
100 import com.android.internal.telephony.NetworkScanRequestTracker;
101 import com.android.internal.telephony.OperatorInfo;
102 import com.android.internal.telephony.Phone;
103 import com.android.internal.telephony.PhoneConstantConversions;
104 import com.android.internal.telephony.PhoneConstants;
105 import com.android.internal.telephony.PhoneFactory;
106 import com.android.internal.telephony.ProxyController;
107 import com.android.internal.telephony.RIL;
108 import com.android.internal.telephony.RILConstants;
109 import com.android.internal.telephony.ServiceStateTracker;
110 import com.android.internal.telephony.SubscriptionController;
111 import com.android.internal.telephony.TelephonyPermissions;
112 import com.android.internal.telephony.euicc.EuiccConnector;
113 import com.android.internal.telephony.uicc.IccIoResult;
114 import com.android.internal.telephony.uicc.IccUtils;
115 import com.android.internal.telephony.uicc.SIMRecords;
116 import com.android.internal.telephony.uicc.UiccCard;
117 import com.android.internal.telephony.uicc.UiccCardApplication;
118 import com.android.internal.telephony.uicc.UiccController;
119 import com.android.internal.telephony.uicc.UiccProfile;
120 import com.android.internal.telephony.uicc.UiccSlot;
121 import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
122 import com.android.internal.util.HexDump;
123 import com.android.phone.vvm.PhoneAccountHandleConverter;
124 import com.android.phone.vvm.RemoteVvmTaskManager;
125 import com.android.phone.vvm.VisualVoicemailSettingsUtil;
126 import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
127 
128 import java.io.FileDescriptor;
129 import java.io.PrintWriter;
130 import java.nio.charset.StandardCharsets;
131 import java.util.ArrayList;
132 import java.util.Arrays;
133 import java.util.List;
134 import java.util.Locale;
135 import java.util.Map;
136 
137 /**
138  * Implementation of the ITelephony interface.
139  */
140 public class PhoneInterfaceManager extends ITelephony.Stub {
141     private static final String LOG_TAG = "PhoneInterfaceManager";
142     private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
143     private static final boolean DBG_LOC = false;
144     private static final boolean DBG_MERGE = false;
145 
146     // Message codes used with mMainThreadHandler
147     private static final int CMD_HANDLE_PIN_MMI = 1;
148     private static final int CMD_HANDLE_NEIGHBORING_CELL = 2;
149     private static final int EVENT_NEIGHBORING_CELL_DONE = 3;
150     private static final int CMD_ANSWER_RINGING_CALL = 4;
151     private static final int CMD_END_CALL = 5;  // not used yet
152     private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
153     private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
154     private static final int CMD_OPEN_CHANNEL = 9;
155     private static final int EVENT_OPEN_CHANNEL_DONE = 10;
156     private static final int CMD_CLOSE_CHANNEL = 11;
157     private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
158     private static final int CMD_NV_READ_ITEM = 13;
159     private static final int EVENT_NV_READ_ITEM_DONE = 14;
160     private static final int CMD_NV_WRITE_ITEM = 15;
161     private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
162     private static final int CMD_NV_WRITE_CDMA_PRL = 17;
163     private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
164     private static final int CMD_NV_RESET_CONFIG = 19;
165     private static final int EVENT_NV_RESET_CONFIG_DONE = 20;
166     private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21;
167     private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22;
168     private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23;
169     private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24;
170     private static final int CMD_SEND_ENVELOPE = 25;
171     private static final int EVENT_SEND_ENVELOPE_DONE = 26;
172     private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
173     private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
174     private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
175     private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
176     private static final int CMD_EXCHANGE_SIM_IO = 31;
177     private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
178     private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
179     private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
180     private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
181     private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
182     private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
183     private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
184     private static final int CMD_PERFORM_NETWORK_SCAN = 39;
185     private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
186     private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
187     private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
188     private static final int CMD_SET_ALLOWED_CARRIERS = 43;
189     private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
190     private static final int CMD_GET_ALLOWED_CARRIERS = 45;
191     private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
192     private static final int CMD_HANDLE_USSD_REQUEST = 47;
193     private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
194     private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
195     private static final int CMD_SWITCH_SLOTS = 50;
196     private static final int EVENT_SWITCH_SLOTS_DONE = 51;
197 
198     // Parameters of select command.
199     private static final int SELECT_COMMAND = 0xA4;
200     private static final int SELECT_P1 = 0x04;
201     private static final int SELECT_P2 = 0;
202     private static final int SELECT_P3 = 0x10;
203 
204     private static final String DEFAULT_NETWORK_MODE_PROPERTY_NAME = "ro.telephony.default_network";
205     private static final String DEFAULT_DATA_ROAMING_PROPERTY_NAME = "ro.com.android.dataroaming";
206     private static final String DEFAULT_MOBILE_DATA_PROPERTY_NAME = "ro.com.android.mobiledata";
207 
208     /** The singleton instance. */
209     private static PhoneInterfaceManager sInstance;
210 
211     private PhoneGlobals mApp;
212     private Phone mPhone;
213     private CallManager mCM;
214     private UserManager mUserManager;
215     private AppOpsManager mAppOps;
216     private MainThreadHandler mMainThreadHandler;
217     private SubscriptionController mSubscriptionController;
218     private SharedPreferences mTelephonySharedPreferences;
219 
220     private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
221     private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
222     private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
223 
224     // The AID of ISD-R.
225     private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
226 
227     private NetworkScanRequestTracker mNetworkScanRequestTracker;
228 
229     /**
230      * A request object to use for transmitting data to an ICC.
231      */
232     private static final class IccAPDUArgument {
233         public int channel, cla, command, p1, p2, p3;
234         public String data;
235 
IccAPDUArgument(int channel, int cla, int command, int p1, int p2, int p3, String data)236         public IccAPDUArgument(int channel, int cla, int command,
237                 int p1, int p2, int p3, String data) {
238             this.channel = channel;
239             this.cla = cla;
240             this.command = command;
241             this.p1 = p1;
242             this.p2 = p2;
243             this.p3 = p3;
244             this.data = data;
245         }
246     }
247 
248     /**
249      * A request object to use for transmitting data to an ICC.
250      */
251     private static final class ManualNetworkSelectionArgument {
252         public OperatorInfo operatorInfo;
253         public boolean persistSelection;
254 
ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection)255         public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
256             this.operatorInfo = operatorInfo;
257             this.persistSelection = persistSelection;
258         }
259     }
260 
261     /**
262      * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
263      * request after sending. The main thread will notify the request when it is complete.
264      */
265     private static final class MainThreadRequest {
266         /** The argument to use for the request */
267         public Object argument;
268         /** The result of the request that is run on the main thread */
269         public Object result;
270         // The subscriber id that this request applies to. Defaults to
271         // SubscriptionManager.INVALID_SUBSCRIPTION_ID
272         public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
273 
MainThreadRequest(Object argument)274         public MainThreadRequest(Object argument) {
275             this.argument = argument;
276         }
277 
MainThreadRequest(Object argument, Integer subId)278         public MainThreadRequest(Object argument, Integer subId) {
279             this.argument = argument;
280             if (subId != null) {
281                 this.subId = subId;
282             }
283         }
284     }
285 
286     private static final class IncomingThirdPartyCallArgs {
287         public final ComponentName component;
288         public final String callId;
289         public final String callerDisplayName;
290 
IncomingThirdPartyCallArgs(ComponentName component, String callId, String callerDisplayName)291         public IncomingThirdPartyCallArgs(ComponentName component, String callId,
292                 String callerDisplayName) {
293             this.component = component;
294             this.callId = callId;
295             this.callerDisplayName = callerDisplayName;
296         }
297     }
298 
299     /**
300      * A handler that processes messages on the main thread in the phone process. Since many
301      * of the Phone calls are not thread safe this is needed to shuttle the requests from the
302      * inbound binder threads to the main thread in the phone process.  The Binder thread
303      * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
304      * on, which will be notified when the operation completes and will contain the result of the
305      * request.
306      *
307      * <p>If a MainThreadRequest object is provided in the msg.obj field,
308      * note that request.result must be set to something non-null for the calling thread to
309      * unblock.
310      */
311     private final class MainThreadHandler extends Handler {
312         @Override
handleMessage(Message msg)313         public void handleMessage(Message msg) {
314             MainThreadRequest request;
315             Message onCompleted;
316             AsyncResult ar;
317             UiccCard uiccCard;
318             IccAPDUArgument iccArgument;
319 
320             switch (msg.what) {
321                  case CMD_HANDLE_USSD_REQUEST: {
322                      request = (MainThreadRequest) msg.obj;
323                      final Phone phone = getPhoneFromRequest(request);
324                      Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
325                      String ussdRequest =  ussdObject.first;
326                      ResultReceiver wrappedCallback = ussdObject.second;
327 
328                      if (!isUssdApiAllowed(request.subId)) {
329                          // Carrier does not support use of this API, return failure.
330                          Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
331                          UssdResponse response = new UssdResponse(ussdRequest, null);
332                          Bundle returnData = new Bundle();
333                          returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
334                          wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
335 
336                          request.result = true;
337                          synchronized (request) {
338                              request.notifyAll();
339                          }
340                          return;
341                      }
342 
343                      try {
344                          request.result = phone != null ?
345                                  phone.handleUssdRequest(ussdRequest, wrappedCallback)
346                                  : false;
347                      } catch (CallStateException cse) {
348                          request.result = false;
349                      }
350                      // Wake up the requesting thread
351                      synchronized (request) {
352                          request.notifyAll();
353                      }
354                      break;
355                 }
356 
357                 case CMD_HANDLE_PIN_MMI: {
358                     request = (MainThreadRequest) msg.obj;
359                     final Phone phone = getPhoneFromRequest(request);
360                     request.result = phone != null ?
361                             getPhoneFromRequest(request).handlePinMmi((String) request.argument)
362                             : false;
363                     // Wake up the requesting thread
364                     synchronized (request) {
365                         request.notifyAll();
366                     }
367                     break;
368                 }
369 
370                 case CMD_HANDLE_NEIGHBORING_CELL:
371                     request = (MainThreadRequest) msg.obj;
372                     onCompleted = obtainMessage(EVENT_NEIGHBORING_CELL_DONE,
373                             request);
374                     mPhone.getNeighboringCids(onCompleted, (WorkSource)request.argument);
375                     break;
376 
377                 case EVENT_NEIGHBORING_CELL_DONE:
378                     ar = (AsyncResult) msg.obj;
379                     request = (MainThreadRequest) ar.userObj;
380                     if (ar.exception == null && ar.result != null) {
381                         request.result = ar.result;
382                     } else {
383                         // create an empty list to notify the waiting thread
384                         request.result = new ArrayList<NeighboringCellInfo>(0);
385                     }
386                     // Wake up the requesting thread
387                     synchronized (request) {
388                         request.notifyAll();
389                     }
390                     break;
391 
392                 case CMD_ANSWER_RINGING_CALL:
393                     request = (MainThreadRequest) msg.obj;
394                     int answer_subId = request.subId;
395                     answerRingingCallInternal(answer_subId);
396                     break;
397 
398                 case CMD_END_CALL:
399                     request = (MainThreadRequest) msg.obj;
400                     int end_subId = request.subId;
401                     final boolean hungUp;
402                     Phone phone = getPhone(end_subId);
403                     if (phone == null) {
404                         if (DBG) log("CMD_END_CALL: no phone for id: " + end_subId);
405                         break;
406                     }
407                     int phoneType = phone.getPhoneType();
408                     if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
409                         // CDMA: If the user presses the Power button we treat it as
410                         // ending the complete call session
411                         hungUp = PhoneUtils.hangupRingingAndActive(getPhone(end_subId));
412                     } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
413                         // GSM: End the call as per the Phone state
414                         hungUp = PhoneUtils.hangup(mCM);
415                     } else {
416                         throw new IllegalStateException("Unexpected phone type: " + phoneType);
417                     }
418                     if (DBG) log("CMD_END_CALL: " + (hungUp ? "hung up!" : "no call to hang up"));
419                     request.result = hungUp;
420                     // Wake up the requesting thread
421                     synchronized (request) {
422                         request.notifyAll();
423                     }
424                     break;
425 
426                 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
427                     request = (MainThreadRequest) msg.obj;
428                     iccArgument = (IccAPDUArgument) request.argument;
429                     uiccCard = getUiccCardFromRequest(request);
430                     if (uiccCard == null) {
431                         loge("iccTransmitApduLogicalChannel: No UICC");
432                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
433                         synchronized (request) {
434                             request.notifyAll();
435                         }
436                     } else {
437                         onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
438                             request);
439                         uiccCard.iccTransmitApduLogicalChannel(
440                             iccArgument.channel, iccArgument.cla, iccArgument.command,
441                             iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
442                             onCompleted);
443                     }
444                     break;
445 
446                 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
447                     ar = (AsyncResult) msg.obj;
448                     request = (MainThreadRequest) ar.userObj;
449                     if (ar.exception == null && ar.result != null) {
450                         request.result = ar.result;
451                     } else {
452                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
453                         if (ar.result == null) {
454                             loge("iccTransmitApduLogicalChannel: Empty response");
455                         } else if (ar.exception instanceof CommandException) {
456                             loge("iccTransmitApduLogicalChannel: CommandException: " +
457                                     ar.exception);
458                         } else {
459                             loge("iccTransmitApduLogicalChannel: Unknown exception");
460                         }
461                     }
462                     synchronized (request) {
463                         request.notifyAll();
464                     }
465                     break;
466 
467                 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
468                     request = (MainThreadRequest) msg.obj;
469                     iccArgument = (IccAPDUArgument) request.argument;
470                     uiccCard = getUiccCardFromRequest(request);
471                     if (uiccCard == null) {
472                         loge("iccTransmitApduBasicChannel: No UICC");
473                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
474                         synchronized (request) {
475                             request.notifyAll();
476                         }
477                     } else {
478                         onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
479                             request);
480                         uiccCard.iccTransmitApduBasicChannel(
481                             iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
482                             iccArgument.p3, iccArgument.data, onCompleted);
483                     }
484                     break;
485 
486                 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
487                     ar = (AsyncResult) msg.obj;
488                     request = (MainThreadRequest) ar.userObj;
489                     if (ar.exception == null && ar.result != null) {
490                         request.result = ar.result;
491                     } else {
492                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
493                         if (ar.result == null) {
494                             loge("iccTransmitApduBasicChannel: Empty response");
495                         } else if (ar.exception instanceof CommandException) {
496                             loge("iccTransmitApduBasicChannel: CommandException: " +
497                                     ar.exception);
498                         } else {
499                             loge("iccTransmitApduBasicChannel: Unknown exception");
500                         }
501                     }
502                     synchronized (request) {
503                         request.notifyAll();
504                     }
505                     break;
506 
507                 case CMD_EXCHANGE_SIM_IO:
508                     request = (MainThreadRequest) msg.obj;
509                     iccArgument = (IccAPDUArgument) request.argument;
510                     uiccCard = getUiccCardFromRequest(request);
511                     if (uiccCard == null) {
512                         loge("iccExchangeSimIO: No UICC");
513                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
514                         synchronized (request) {
515                             request.notifyAll();
516                         }
517                     } else {
518                         onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
519                                 request);
520                         uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
521                                 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
522                                 iccArgument.data, onCompleted);
523                     }
524                     break;
525 
526                 case EVENT_EXCHANGE_SIM_IO_DONE:
527                     ar = (AsyncResult) msg.obj;
528                     request = (MainThreadRequest) ar.userObj;
529                     if (ar.exception == null && ar.result != null) {
530                         request.result = ar.result;
531                     } else {
532                         request.result = new IccIoResult(0x6f, 0, (byte[])null);
533                     }
534                     synchronized (request) {
535                         request.notifyAll();
536                     }
537                     break;
538 
539                 case CMD_SEND_ENVELOPE:
540                     request = (MainThreadRequest) msg.obj;
541                     uiccCard = getUiccCardFromRequest(request);
542                     if (uiccCard == null) {
543                         loge("sendEnvelopeWithStatus: No UICC");
544                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
545                         synchronized (request) {
546                             request.notifyAll();
547                         }
548                     } else {
549                         onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
550                         uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
551                     }
552                     break;
553 
554                 case EVENT_SEND_ENVELOPE_DONE:
555                     ar = (AsyncResult) msg.obj;
556                     request = (MainThreadRequest) ar.userObj;
557                     if (ar.exception == null && ar.result != null) {
558                         request.result = ar.result;
559                     } else {
560                         request.result = new IccIoResult(0x6F, 0, (byte[])null);
561                         if (ar.result == null) {
562                             loge("sendEnvelopeWithStatus: Empty response");
563                         } else if (ar.exception instanceof CommandException) {
564                             loge("sendEnvelopeWithStatus: CommandException: " +
565                                     ar.exception);
566                         } else {
567                             loge("sendEnvelopeWithStatus: exception:" + ar.exception);
568                         }
569                     }
570                     synchronized (request) {
571                         request.notifyAll();
572                     }
573                     break;
574 
575                 case CMD_OPEN_CHANNEL:
576                     request = (MainThreadRequest) msg.obj;
577                     uiccCard = getUiccCardFromRequest(request);
578                     Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
579                     if (uiccCard == null) {
580                         loge("iccOpenLogicalChannel: No UICC");
581                         request.result = new IccOpenLogicalChannelResponse(-1,
582                             IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
583                         synchronized (request) {
584                             request.notifyAll();
585                         }
586                     } else {
587                         onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
588                         uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
589                                 openChannelArgs.second, onCompleted);
590                     }
591                     break;
592 
593                 case EVENT_OPEN_CHANNEL_DONE:
594                     ar = (AsyncResult) msg.obj;
595                     request = (MainThreadRequest) ar.userObj;
596                     IccOpenLogicalChannelResponse openChannelResp;
597                     if (ar.exception == null && ar.result != null) {
598                         int[] result = (int[]) ar.result;
599                         int channelId = result[0];
600                         byte[] selectResponse = null;
601                         if (result.length > 1) {
602                             selectResponse = new byte[result.length - 1];
603                             for (int i = 1; i < result.length; ++i) {
604                                 selectResponse[i - 1] = (byte) result[i];
605                             }
606                         }
607                         openChannelResp = new IccOpenLogicalChannelResponse(channelId,
608                             IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
609                     } else {
610                         if (ar.result == null) {
611                             loge("iccOpenLogicalChannel: Empty response");
612                         }
613                         if (ar.exception != null) {
614                             loge("iccOpenLogicalChannel: Exception: " + ar.exception);
615                         }
616 
617                         int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
618                         if (ar.exception instanceof CommandException) {
619                             CommandException.Error error =
620                                 ((CommandException) (ar.exception)).getCommandError();
621                             if (error == CommandException.Error.MISSING_RESOURCE) {
622                                 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
623                             } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
624                                 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
625                             }
626                         }
627                         openChannelResp = new IccOpenLogicalChannelResponse(
628                             IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
629                     }
630                     request.result = openChannelResp;
631                     synchronized (request) {
632                         request.notifyAll();
633                     }
634                     break;
635 
636                 case CMD_CLOSE_CHANNEL:
637                     request = (MainThreadRequest) msg.obj;
638                     uiccCard = getUiccCardFromRequest(request);
639                     if (uiccCard == null) {
640                         loge("iccCloseLogicalChannel: No UICC");
641                         request.result = false;
642                         synchronized (request) {
643                             request.notifyAll();
644                         }
645                     } else {
646                         onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
647                         uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
648                     }
649                     break;
650 
651                 case EVENT_CLOSE_CHANNEL_DONE:
652                     handleNullReturnEvent(msg, "iccCloseLogicalChannel");
653                     break;
654 
655                 case CMD_NV_READ_ITEM:
656                     request = (MainThreadRequest) msg.obj;
657                     onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
658                     mPhone.nvReadItem((Integer) request.argument, onCompleted);
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                     synchronized (request) {
678                         request.notifyAll();
679                     }
680                     break;
681 
682                 case CMD_NV_WRITE_ITEM:
683                     request = (MainThreadRequest) msg.obj;
684                     onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
685                     Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
686                     mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted);
687                     break;
688 
689                 case EVENT_NV_WRITE_ITEM_DONE:
690                     handleNullReturnEvent(msg, "nvWriteItem");
691                     break;
692 
693                 case CMD_NV_WRITE_CDMA_PRL:
694                     request = (MainThreadRequest) msg.obj;
695                     onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
696                     mPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
697                     break;
698 
699                 case EVENT_NV_WRITE_CDMA_PRL_DONE:
700                     handleNullReturnEvent(msg, "nvWriteCdmaPrl");
701                     break;
702 
703                 case CMD_NV_RESET_CONFIG:
704                     request = (MainThreadRequest) msg.obj;
705                     onCompleted = obtainMessage(EVENT_NV_RESET_CONFIG_DONE, request);
706                     mPhone.nvResetConfig((Integer) request.argument, onCompleted);
707                     break;
708 
709                 case EVENT_NV_RESET_CONFIG_DONE:
710                     handleNullReturnEvent(msg, "nvResetConfig");
711                     break;
712 
713                 case CMD_GET_PREFERRED_NETWORK_TYPE:
714                     request = (MainThreadRequest) msg.obj;
715                     onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
716                     getPhoneFromRequest(request).getPreferredNetworkType(onCompleted);
717                     break;
718 
719                 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
720                     ar = (AsyncResult) msg.obj;
721                     request = (MainThreadRequest) ar.userObj;
722                     if (ar.exception == null && ar.result != null) {
723                         request.result = ar.result;     // Integer
724                     } else {
725                         request.result = null;
726                         if (ar.result == null) {
727                             loge("getPreferredNetworkType: Empty response");
728                         } else if (ar.exception instanceof CommandException) {
729                             loge("getPreferredNetworkType: CommandException: " +
730                                     ar.exception);
731                         } else {
732                             loge("getPreferredNetworkType: Unknown exception");
733                         }
734                     }
735                     synchronized (request) {
736                         request.notifyAll();
737                     }
738                     break;
739 
740                 case CMD_SET_PREFERRED_NETWORK_TYPE:
741                     request = (MainThreadRequest) msg.obj;
742                     onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
743                     int networkType = (Integer) request.argument;
744                     getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted);
745                     break;
746 
747                 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
748                     handleNullReturnEvent(msg, "setPreferredNetworkType");
749                     break;
750 
751                 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
752                     request = (MainThreadRequest)msg.obj;
753                     onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
754                     mPhone.invokeOemRilRequestRaw((byte[])request.argument, onCompleted);
755                     break;
756 
757                 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
758                     ar = (AsyncResult)msg.obj;
759                     request = (MainThreadRequest)ar.userObj;
760                     request.result = ar;
761                     synchronized (request) {
762                         request.notifyAll();
763                     }
764                     break;
765 
766                 case CMD_SET_VOICEMAIL_NUMBER:
767                     request = (MainThreadRequest) msg.obj;
768                     onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
769                     Pair<String, String> tagNum = (Pair<String, String>) request.argument;
770                     getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
771                             onCompleted);
772                     break;
773 
774                 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
775                     handleNullReturnEvent(msg, "setVoicemailNumber");
776                     break;
777 
778                 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
779                     request = (MainThreadRequest) msg.obj;
780                     onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
781                             request);
782                     getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
783                     break;
784 
785                 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
786                     handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
787                     break;
788 
789                 case CMD_PERFORM_NETWORK_SCAN:
790                     request = (MainThreadRequest) msg.obj;
791                     onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
792                     getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
793                     break;
794 
795                 case EVENT_PERFORM_NETWORK_SCAN_DONE:
796                     ar = (AsyncResult) msg.obj;
797                     request = (MainThreadRequest) ar.userObj;
798                     CellNetworkScanResult cellScanResult;
799                     if (ar.exception == null && ar.result != null) {
800                         cellScanResult = new CellNetworkScanResult(
801                                 CellNetworkScanResult.STATUS_SUCCESS,
802                                 (List<OperatorInfo>) ar.result);
803                     } else {
804                         if (ar.result == null) {
805                             loge("getCellNetworkScanResults: Empty response");
806                         }
807                         if (ar.exception != null) {
808                             loge("getCellNetworkScanResults: Exception: " + ar.exception);
809                         }
810                         int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
811                         if (ar.exception instanceof CommandException) {
812                             CommandException.Error error =
813                                 ((CommandException) (ar.exception)).getCommandError();
814                             if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
815                                 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
816                             } else if (error == CommandException.Error.GENERIC_FAILURE) {
817                                 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
818                             }
819                         }
820                         cellScanResult = new CellNetworkScanResult(errorCode, null);
821                     }
822                     request.result = cellScanResult;
823                     synchronized (request) {
824                         request.notifyAll();
825                     }
826                     break;
827 
828                 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
829                     request = (MainThreadRequest) msg.obj;
830                     ManualNetworkSelectionArgument selArg =
831                             (ManualNetworkSelectionArgument) request.argument;
832                     onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
833                             request);
834                     getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
835                             selArg.persistSelection, onCompleted);
836                     break;
837 
838                 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
839                     handleNullReturnEvent(msg, "setNetworkSelectionModeManual");
840                     break;
841 
842                 case CMD_GET_MODEM_ACTIVITY_INFO:
843                     request = (MainThreadRequest) msg.obj;
844                     onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
845                     mPhone.getModemActivityInfo(onCompleted);
846                     break;
847 
848                 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE:
849                     ar = (AsyncResult) msg.obj;
850                     request = (MainThreadRequest) ar.userObj;
851                     if (ar.exception == null && ar.result != null) {
852                         request.result = ar.result;
853                     } else {
854                         if (ar.result == null) {
855                             loge("queryModemActivityInfo: Empty response");
856                         } else if (ar.exception instanceof CommandException) {
857                             loge("queryModemActivityInfo: CommandException: " +
858                                     ar.exception);
859                         } else {
860                             loge("queryModemActivityInfo: Unknown exception");
861                         }
862                     }
863                     // Result cannot be null. Return ModemActivityInfo with all fields set to 0.
864                     if (request.result == null) {
865                         request.result = new ModemActivityInfo(0, 0, 0, null, 0, 0);
866                     }
867                     synchronized (request) {
868                         request.notifyAll();
869                     }
870                     break;
871 
872                 case CMD_SET_ALLOWED_CARRIERS:
873                     request = (MainThreadRequest) msg.obj;
874                     onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
875                     mPhone.setAllowedCarriers(
876                             (List<CarrierIdentifier>) request.argument,
877                             onCompleted);
878                     break;
879 
880                 case EVENT_SET_ALLOWED_CARRIERS_DONE:
881                     ar = (AsyncResult) msg.obj;
882                     request = (MainThreadRequest) ar.userObj;
883                     if (ar.exception == null && ar.result != null) {
884                         request.result = ar.result;
885                     } else {
886                         if (ar.result == null) {
887                             loge("setAllowedCarriers: Empty response");
888                         } else if (ar.exception instanceof CommandException) {
889                             loge("setAllowedCarriers: CommandException: " +
890                                     ar.exception);
891                         } else {
892                             loge("setAllowedCarriers: Unknown exception");
893                         }
894                     }
895                     // Result cannot be null. Return -1 on error.
896                     if (request.result == null) {
897                         request.result = new int[]{-1};
898                     }
899                     synchronized (request) {
900                         request.notifyAll();
901                     }
902                     break;
903 
904                 case CMD_GET_ALLOWED_CARRIERS:
905                     request = (MainThreadRequest) msg.obj;
906                     onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
907                     mPhone.getAllowedCarriers(onCompleted);
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                         if (ar.result == null) {
917                             loge("getAllowedCarriers: Empty response");
918                         } else if (ar.exception instanceof CommandException) {
919                             loge("getAllowedCarriers: CommandException: " +
920                                     ar.exception);
921                         } else {
922                             loge("getAllowedCarriers: Unknown exception");
923                         }
924                     }
925                     // Result cannot be null. Return empty list of CarrierIdentifier.
926                     if (request.result == null) {
927                         request.result = new ArrayList<CarrierIdentifier>(0);
928                     }
929                     synchronized (request) {
930                         request.notifyAll();
931                     }
932                     break;
933 
934                 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
935                     ar = (AsyncResult) msg.obj;
936                     request = (MainThreadRequest) ar.userObj;
937                     if (ar.exception == null && ar.result != null) {
938                         request.result = ar.result;
939                     } else {
940                         request.result = new IllegalArgumentException(
941                                 "Failed to retrieve Forbidden Plmns");
942                         if (ar.result == null) {
943                             loge("getForbiddenPlmns: Empty response");
944                         } else {
945                             loge("getForbiddenPlmns: Unknown exception");
946                         }
947                     }
948                     synchronized (request) {
949                         request.notifyAll();
950                     }
951                     break;
952 
953                 case CMD_GET_FORBIDDEN_PLMNS:
954                     request = (MainThreadRequest) msg.obj;
955                     uiccCard = getUiccCardFromRequest(request);
956                     if (uiccCard == null) {
957                         loge("getForbiddenPlmns() UiccCard is null");
958                         request.result = new IllegalArgumentException(
959                                 "getForbiddenPlmns() UiccCard is null");
960                         synchronized (request) {
961                             request.notifyAll();
962                         }
963                         break;
964                     }
965                     Integer appType = (Integer) request.argument;
966                     UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
967                     if (uiccApp == null) {
968                         loge("getForbiddenPlmns() no app with specified type -- "
969                                 + appType);
970                         request.result = new IllegalArgumentException("Failed to get UICC App");
971                         synchronized (request) {
972                             request.notifyAll();
973                         }
974                         break;
975                     } else {
976                         if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
977                                 + " specified type -- " + appType);
978                     }
979                     onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
980                     ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
981                               onCompleted);
982                     break;
983 
984                 case CMD_SWITCH_SLOTS:
985                     request = (MainThreadRequest) msg.obj;
986                     int[] physicalSlots = (int[]) request.argument;
987                     onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
988                     UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
989                     break;
990 
991                 case EVENT_SWITCH_SLOTS_DONE:
992                     ar = (AsyncResult) msg.obj;
993                     request = (MainThreadRequest) ar.userObj;
994                     request.result = (ar.exception == null);
995                     synchronized (request) {
996                         request.notifyAll();
997                     }
998                     break;
999 
1000                 default:
1001                     Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
1002                     break;
1003             }
1004         }
1005 
handleNullReturnEvent(Message msg, String command)1006         private void handleNullReturnEvent(Message msg, String command) {
1007             AsyncResult ar = (AsyncResult) msg.obj;
1008             MainThreadRequest request = (MainThreadRequest) ar.userObj;
1009             if (ar.exception == null) {
1010                 request.result = true;
1011             } else {
1012                 request.result = false;
1013                 if (ar.exception instanceof CommandException) {
1014                     loge(command + ": CommandException: " + ar.exception);
1015                 } else {
1016                     loge(command + ": Unknown exception");
1017                 }
1018             }
1019             synchronized (request) {
1020                 request.notifyAll();
1021             }
1022         }
1023     }
1024 
1025     /**
1026      * Posts the specified command to be executed on the main thread,
1027      * waits for the request to complete, and returns the result.
1028      * @see #sendRequestAsync
1029      */
sendRequest(int command, Object argument)1030     private Object sendRequest(int command, Object argument) {
1031         return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
1032     }
1033 
1034     /**
1035      * Posts the specified command to be executed on the main thread,
1036      * waits for the request to complete, and returns the result.
1037      * @see #sendRequestAsync
1038      */
sendRequest(int command, Object argument, Integer subId)1039     private Object sendRequest(int command, Object argument, Integer subId) {
1040         if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
1041             throw new RuntimeException("This method will deadlock if called from the main thread.");
1042         }
1043 
1044         MainThreadRequest request = new MainThreadRequest(argument, subId);
1045         Message msg = mMainThreadHandler.obtainMessage(command, request);
1046         msg.sendToTarget();
1047 
1048         // Wait for the request to complete
1049         synchronized (request) {
1050             while (request.result == null) {
1051                 try {
1052                     request.wait();
1053                 } catch (InterruptedException e) {
1054                     // Do nothing, go back and wait until the request is complete
1055                 }
1056             }
1057         }
1058         return request.result;
1059     }
1060 
1061     /**
1062      * Asynchronous ("fire and forget") version of sendRequest():
1063      * Posts the specified command to be executed on the main thread, and
1064      * returns immediately.
1065      * @see #sendRequest
1066      */
sendRequestAsync(int command)1067     private void sendRequestAsync(int command) {
1068         mMainThreadHandler.sendEmptyMessage(command);
1069     }
1070 
1071     /**
1072      * Same as {@link #sendRequestAsync(int)} except it takes an argument.
1073      * @see {@link #sendRequest(int,Object)}
1074      */
sendRequestAsync(int command, Object argument)1075     private void sendRequestAsync(int command, Object argument) {
1076         MainThreadRequest request = new MainThreadRequest(argument);
1077         Message msg = mMainThreadHandler.obtainMessage(command, request);
1078         msg.sendToTarget();
1079     }
1080 
1081     /**
1082      * Initialize the singleton PhoneInterfaceManager instance.
1083      * This is only done once, at startup, from PhoneApp.onCreate().
1084      */
init(PhoneGlobals app, Phone phone)1085     /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) {
1086         synchronized (PhoneInterfaceManager.class) {
1087             if (sInstance == null) {
1088                 sInstance = new PhoneInterfaceManager(app, phone);
1089             } else {
1090                 Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
1091             }
1092             return sInstance;
1093         }
1094     }
1095 
1096     /** Private constructor; @see init() */
PhoneInterfaceManager(PhoneGlobals app, Phone phone)1097     private PhoneInterfaceManager(PhoneGlobals app, Phone phone) {
1098         mApp = app;
1099         mPhone = phone;
1100         mCM = PhoneGlobals.getInstance().mCM;
1101         mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
1102         mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
1103         mMainThreadHandler = new MainThreadHandler();
1104         mTelephonySharedPreferences =
1105                 PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
1106         mSubscriptionController = SubscriptionController.getInstance();
1107         mNetworkScanRequestTracker = new NetworkScanRequestTracker();
1108 
1109         publish();
1110     }
1111 
publish()1112     private void publish() {
1113         if (DBG) log("publish: " + this);
1114 
1115         ServiceManager.addService("phone", this);
1116     }
1117 
getPhoneFromRequest(MainThreadRequest request)1118     private Phone getPhoneFromRequest(MainThreadRequest request) {
1119         return (request.subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
1120                 ? mPhone : getPhone(request.subId);
1121     }
1122 
getUiccCardFromRequest(MainThreadRequest request)1123     private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
1124         Phone phone = getPhoneFromRequest(request);
1125         return phone == null ? null :
1126                 UiccController.getInstance().getUiccCard(phone.getPhoneId());
1127     }
1128 
1129     // returns phone associated with the subId.
getPhone(int subId)1130     private Phone getPhone(int subId) {
1131         return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
1132     }
1133     //
1134     // Implementation of the ITelephony interface.
1135     //
1136 
dial(String number)1137     public void dial(String number) {
1138         dialForSubscriber(getPreferredVoiceSubscription(), number);
1139     }
1140 
dialForSubscriber(int subId, String number)1141     public void dialForSubscriber(int subId, String number) {
1142         if (DBG) log("dial: " + number);
1143         // No permission check needed here: This is just a wrapper around the
1144         // ACTION_DIAL intent, which is available to any app since it puts up
1145         // the UI before it does anything.
1146 
1147         String url = createTelUrl(number);
1148         if (url == null) {
1149             return;
1150         }
1151 
1152         // PENDING: should we just silently fail if phone is offhook or ringing?
1153         PhoneConstants.State state = mCM.getState(subId);
1154         if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
1155             Intent  intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
1156             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1157             mApp.startActivity(intent);
1158         }
1159     }
1160 
call(String callingPackage, String number)1161     public void call(String callingPackage, String number) {
1162         callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
1163     }
1164 
callForSubscriber(int subId, String callingPackage, String number)1165     public void callForSubscriber(int subId, String callingPackage, String number) {
1166         if (DBG) log("call: " + number);
1167 
1168         // This is just a wrapper around the ACTION_CALL intent, but we still
1169         // need to do a permission check since we're calling startActivity()
1170         // from the context of the phone app.
1171         enforceCallPermission();
1172 
1173         if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage)
1174                 != AppOpsManager.MODE_ALLOWED) {
1175             return;
1176         }
1177 
1178         String url = createTelUrl(number);
1179         if (url == null) {
1180             return;
1181         }
1182 
1183         boolean isValid = false;
1184         final List<SubscriptionInfo> slist = getActiveSubscriptionInfoList();
1185         if (slist != null) {
1186             for (SubscriptionInfo subInfoRecord : slist) {
1187                 if (subInfoRecord.getSubscriptionId() == subId) {
1188                     isValid = true;
1189                     break;
1190                 }
1191             }
1192         }
1193         if (isValid == false) {
1194             return;
1195         }
1196 
1197         Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
1198         intent.putExtra(SUBSCRIPTION_KEY, subId);
1199         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1200         mApp.startActivity(intent);
1201     }
1202 
1203     /**
1204      * End a call based on call state
1205      * @return true is a call was ended
1206      */
endCall()1207     public boolean endCall() {
1208         return endCallForSubscriber(getDefaultSubscription());
1209     }
1210 
1211     /**
1212      * End a call based on the call state of the subId
1213      * @return true is a call was ended
1214      */
endCallForSubscriber(int subId)1215     public boolean endCallForSubscriber(int subId) {
1216         if (mApp.checkCallingOrSelfPermission(permission.MODIFY_PHONE_STATE)
1217                 != PackageManager.PERMISSION_GRANTED) {
1218             Log.i(LOG_TAG, "endCall: called without modify phone state.");
1219             EventLog.writeEvent(0x534e4554, "67862398", -1, "");
1220             throw new SecurityException("MODIFY_PHONE_STATE permission required.");
1221         }
1222         return (Boolean) sendRequest(CMD_END_CALL, null, new Integer(subId));
1223     }
1224 
answerRingingCall()1225     public void answerRingingCall() {
1226         answerRingingCallForSubscriber(getDefaultSubscription());
1227     }
1228 
answerRingingCallForSubscriber(int subId)1229     public void answerRingingCallForSubscriber(int subId) {
1230         if (DBG) log("answerRingingCall...");
1231         // TODO: there should eventually be a separate "ANSWER_PHONE" permission,
1232         // but that can probably wait till the big TelephonyManager API overhaul.
1233         // For now, protect this call with the MODIFY_PHONE_STATE permission.
1234         enforceModifyPermission();
1235         sendRequest(CMD_ANSWER_RINGING_CALL, null, new Integer(subId));
1236     }
1237 
1238     /**
1239      * Make the actual telephony calls to implement answerRingingCall().
1240      * This should only be called from the main thread of the Phone app.
1241      * @see #answerRingingCall
1242      *
1243      * TODO: it would be nice to return true if we answered the call, or
1244      * false if there wasn't actually a ringing incoming call, or some
1245      * other error occurred.  (In other words, pass back the return value
1246      * from PhoneUtils.answerCall() or PhoneUtils.answerAndEndActive().)
1247      * But that would require calling this method via sendRequest() rather
1248      * than sendRequestAsync(), and right now we don't actually *need* that
1249      * return value, so let's just return void for now.
1250      */
answerRingingCallInternal(int subId)1251     private void answerRingingCallInternal(int subId) {
1252         final boolean hasRingingCall = !getPhone(subId).getRingingCall().isIdle();
1253         if (hasRingingCall) {
1254             final boolean hasActiveCall = !getPhone(subId).getForegroundCall().isIdle();
1255             final boolean hasHoldingCall = !getPhone(subId).getBackgroundCall().isIdle();
1256             if (hasActiveCall && hasHoldingCall) {
1257                 // Both lines are in use!
1258                 // TODO: provide a flag to let the caller specify what
1259                 // policy to use if both lines are in use.  (The current
1260                 // behavior is hardwired to "answer incoming, end ongoing",
1261                 // which is how the CALL button is specced to behave.)
1262                 PhoneUtils.answerAndEndActive(mCM, mCM.getFirstActiveRingingCall());
1263                 return;
1264             } else {
1265                 // answerCall() will automatically hold the current active
1266                 // call, if there is one.
1267                 PhoneUtils.answerCall(mCM.getFirstActiveRingingCall());
1268                 return;
1269             }
1270         } else {
1271             // No call was ringing.
1272             return;
1273         }
1274     }
1275 
1276     /**
1277      * This method is no longer used and can be removed once TelephonyManager stops referring to it.
1278      */
silenceRinger()1279     public void silenceRinger() {
1280         Log.e(LOG_TAG, "silenseRinger not supported");
1281     }
1282 
1283     @Override
isOffhook(String callingPackage)1284     public boolean isOffhook(String callingPackage) {
1285         return isOffhookForSubscriber(getDefaultSubscription(), callingPackage);
1286     }
1287 
1288     @Override
isOffhookForSubscriber(int subId, String callingPackage)1289     public boolean isOffhookForSubscriber(int subId, String callingPackage) {
1290         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1291                 mApp, subId, callingPackage, "isOffhookForSubscriber")) {
1292             return false;
1293         }
1294 
1295         final Phone phone = getPhone(subId);
1296         if (phone != null) {
1297             return (phone.getState() == PhoneConstants.State.OFFHOOK);
1298         } else {
1299             return false;
1300         }
1301     }
1302 
1303     @Override
isRinging(String callingPackage)1304     public boolean isRinging(String callingPackage) {
1305         return (isRingingForSubscriber(getDefaultSubscription(), callingPackage));
1306     }
1307 
1308     @Override
isRingingForSubscriber(int subId, String callingPackage)1309     public boolean isRingingForSubscriber(int subId, String callingPackage) {
1310         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1311                 mApp, subId, callingPackage, "isRingingForSubscriber")) {
1312             return false;
1313         }
1314 
1315         final Phone phone = getPhone(subId);
1316         if (phone != null) {
1317             return (phone.getState() == PhoneConstants.State.RINGING);
1318         } else {
1319             return false;
1320         }
1321     }
1322 
1323     @Override
isIdle(String callingPackage)1324     public boolean isIdle(String callingPackage) {
1325         return isIdleForSubscriber(getDefaultSubscription(), callingPackage);
1326     }
1327 
1328     @Override
isIdleForSubscriber(int subId, String callingPackage)1329     public boolean isIdleForSubscriber(int subId, String callingPackage) {
1330         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1331                 mApp, subId, callingPackage, "isIdleForSubscriber")) {
1332             return false;
1333         }
1334 
1335         final Phone phone = getPhone(subId);
1336         if (phone != null) {
1337             return (phone.getState() == PhoneConstants.State.IDLE);
1338         } else {
1339             return false;
1340         }
1341     }
1342 
supplyPin(String pin)1343     public boolean supplyPin(String pin) {
1344         return supplyPinForSubscriber(getDefaultSubscription(), pin);
1345     }
1346 
supplyPinForSubscriber(int subId, String pin)1347     public boolean supplyPinForSubscriber(int subId, String pin) {
1348         int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
1349         return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1350     }
1351 
supplyPuk(String puk, String pin)1352     public boolean supplyPuk(String puk, String pin) {
1353         return supplyPukForSubscriber(getDefaultSubscription(), puk, pin);
1354     }
1355 
supplyPukForSubscriber(int subId, String puk, String pin)1356     public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
1357         int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
1358         return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1359     }
1360 
1361     /** {@hide} */
supplyPinReportResult(String pin)1362     public int[] supplyPinReportResult(String pin) {
1363         return supplyPinReportResultForSubscriber(getDefaultSubscription(), pin);
1364     }
1365 
supplyPinReportResultForSubscriber(int subId, String pin)1366     public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
1367         enforceModifyPermission();
1368         final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
1369         checkSimPin.start();
1370         return checkSimPin.unlockSim(null, pin);
1371     }
1372 
1373     /** {@hide} */
supplyPukReportResult(String puk, String pin)1374     public int[] supplyPukReportResult(String puk, String pin) {
1375         return supplyPukReportResultForSubscriber(getDefaultSubscription(), puk, pin);
1376     }
1377 
supplyPukReportResultForSubscriber(int subId, String puk, String pin)1378     public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
1379         enforceModifyPermission();
1380         final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
1381         checkSimPuk.start();
1382         return checkSimPuk.unlockSim(puk, pin);
1383     }
1384 
1385     /**
1386      * Helper thread to turn async call to SimCard#supplyPin into
1387      * a synchronous one.
1388      */
1389     private static class UnlockSim extends Thread {
1390 
1391         private final IccCard mSimCard;
1392 
1393         private boolean mDone = false;
1394         private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1395         private int mRetryCount = -1;
1396 
1397         // For replies from SimCard interface
1398         private Handler mHandler;
1399 
1400         // For async handler to identify request type
1401         private static final int SUPPLY_PIN_COMPLETE = 100;
1402 
UnlockSim(IccCard simCard)1403         public UnlockSim(IccCard simCard) {
1404             mSimCard = simCard;
1405         }
1406 
1407         @Override
run()1408         public void run() {
1409             Looper.prepare();
1410             synchronized (UnlockSim.this) {
1411                 mHandler = new Handler() {
1412                     @Override
1413                     public void handleMessage(Message msg) {
1414                         AsyncResult ar = (AsyncResult) msg.obj;
1415                         switch (msg.what) {
1416                             case SUPPLY_PIN_COMPLETE:
1417                                 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
1418                                 synchronized (UnlockSim.this) {
1419                                     mRetryCount = msg.arg1;
1420                                     if (ar.exception != null) {
1421                                         if (ar.exception instanceof CommandException &&
1422                                                 ((CommandException)(ar.exception)).getCommandError()
1423                                                 == CommandException.Error.PASSWORD_INCORRECT) {
1424                                             mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
1425                                         } else {
1426                                             mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1427                                         }
1428                                     } else {
1429                                         mResult = PhoneConstants.PIN_RESULT_SUCCESS;
1430                                     }
1431                                     mDone = true;
1432                                     UnlockSim.this.notifyAll();
1433                                 }
1434                                 break;
1435                         }
1436                     }
1437                 };
1438                 UnlockSim.this.notifyAll();
1439             }
1440             Looper.loop();
1441         }
1442 
1443         /*
1444          * Use PIN or PUK to unlock SIM card
1445          *
1446          * If PUK is null, unlock SIM card with PIN
1447          *
1448          * If PUK is not null, unlock SIM card with PUK and set PIN code
1449          */
unlockSim(String puk, String pin)1450         synchronized int[] unlockSim(String puk, String pin) {
1451 
1452             while (mHandler == null) {
1453                 try {
1454                     wait();
1455                 } catch (InterruptedException e) {
1456                     Thread.currentThread().interrupt();
1457                 }
1458             }
1459             Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
1460 
1461             if (puk == null) {
1462                 mSimCard.supplyPin(pin, callback);
1463             } else {
1464                 mSimCard.supplyPuk(puk, pin, callback);
1465             }
1466 
1467             while (!mDone) {
1468                 try {
1469                     Log.d(LOG_TAG, "wait for done");
1470                     wait();
1471                 } catch (InterruptedException e) {
1472                     // Restore the interrupted status
1473                     Thread.currentThread().interrupt();
1474                 }
1475             }
1476             Log.d(LOG_TAG, "done");
1477             int[] resultArray = new int[2];
1478             resultArray[0] = mResult;
1479             resultArray[1] = mRetryCount;
1480             return resultArray;
1481         }
1482     }
1483 
updateServiceLocation()1484     public void updateServiceLocation() {
1485         updateServiceLocationForSubscriber(getDefaultSubscription());
1486 
1487     }
1488 
updateServiceLocationForSubscriber(int subId)1489     public void updateServiceLocationForSubscriber(int subId) {
1490         // No permission check needed here: this call is harmless, and it's
1491         // needed for the ServiceState.requestStateUpdate() call (which is
1492         // already intentionally exposed to 3rd parties.)
1493         final Phone phone = getPhone(subId);
1494         if (phone != null) {
1495             phone.updateServiceLocation();
1496         }
1497     }
1498 
1499     @Override
isRadioOn(String callingPackage)1500     public boolean isRadioOn(String callingPackage) {
1501         return isRadioOnForSubscriber(getDefaultSubscription(), callingPackage);
1502     }
1503 
1504     @Override
isRadioOnForSubscriber(int subId, String callingPackage)1505     public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
1506         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1507                 mApp, subId, callingPackage, "isRadioOnForSubscriber")) {
1508             return false;
1509         }
1510         return isRadioOnForSubscriber(subId);
1511     }
1512 
isRadioOnForSubscriber(int subId)1513     private boolean isRadioOnForSubscriber(int subId) {
1514         final Phone phone = getPhone(subId);
1515         if (phone != null) {
1516             return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
1517         } else {
1518             return false;
1519         }
1520     }
1521 
toggleRadioOnOff()1522     public void toggleRadioOnOff() {
1523         toggleRadioOnOffForSubscriber(getDefaultSubscription());
1524 
1525     }
1526 
toggleRadioOnOffForSubscriber(int subId)1527     public void toggleRadioOnOffForSubscriber(int subId) {
1528         enforceModifyPermission();
1529         final Phone phone = getPhone(subId);
1530         if (phone != null) {
1531             phone.setRadioPower(!isRadioOnForSubscriber(subId));
1532         }
1533     }
1534 
setRadio(boolean turnOn)1535     public boolean setRadio(boolean turnOn) {
1536         return setRadioForSubscriber(getDefaultSubscription(), turnOn);
1537     }
1538 
setRadioForSubscriber(int subId, boolean turnOn)1539     public boolean setRadioForSubscriber(int subId, boolean turnOn) {
1540         enforceModifyPermission();
1541         final Phone phone = getPhone(subId);
1542         if (phone == null) {
1543             return false;
1544         }
1545         if ((phone.getServiceState().getState() !=
1546                 ServiceState.STATE_POWER_OFF) != turnOn) {
1547             toggleRadioOnOffForSubscriber(subId);
1548         }
1549         return true;
1550     }
1551 
needMobileRadioShutdown()1552     public boolean needMobileRadioShutdown() {
1553         /*
1554          * If any of the Radios are available, it will need to be
1555          * shutdown. So return true if any Radio is available.
1556          */
1557         for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1558             Phone phone = PhoneFactory.getPhone(i);
1559             if (phone != null && phone.isRadioAvailable()) return true;
1560         }
1561         logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
1562         return false;
1563     }
1564 
shutdownMobileRadios()1565     public void shutdownMobileRadios() {
1566         for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1567             logv("Shutting down Phone " + i);
1568             shutdownRadioUsingPhoneId(i);
1569         }
1570     }
1571 
shutdownRadioUsingPhoneId(int phoneId)1572     private void shutdownRadioUsingPhoneId(int phoneId) {
1573         enforceModifyPermission();
1574         Phone phone = PhoneFactory.getPhone(phoneId);
1575         if (phone != null && phone.isRadioAvailable()) {
1576             phone.shutdownRadio();
1577         }
1578     }
1579 
setRadioPower(boolean turnOn)1580     public boolean setRadioPower(boolean turnOn) {
1581         enforceModifyPermission();
1582         final Phone defaultPhone = PhoneFactory.getDefaultPhone();
1583         if (defaultPhone != null) {
1584             defaultPhone.setRadioPower(turnOn);
1585             return true;
1586         } else {
1587             loge("There's no default phone.");
1588             return false;
1589         }
1590     }
1591 
setRadioPowerForSubscriber(int subId, boolean turnOn)1592     public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
1593         enforceModifyPermission();
1594         final Phone phone = getPhone(subId);
1595         if (phone != null) {
1596             phone.setRadioPower(turnOn);
1597             return true;
1598         } else {
1599             return false;
1600         }
1601     }
1602 
1603     // FIXME: subId version needed
1604     @Override
enableDataConnectivity()1605     public boolean enableDataConnectivity() {
1606         enforceModifyPermission();
1607         int subId = mSubscriptionController.getDefaultDataSubId();
1608         final Phone phone = getPhone(subId);
1609         if (phone != null) {
1610             phone.setUserDataEnabled(true);
1611             return true;
1612         } else {
1613             return false;
1614         }
1615     }
1616 
1617     // FIXME: subId version needed
1618     @Override
disableDataConnectivity()1619     public boolean disableDataConnectivity() {
1620         enforceModifyPermission();
1621         int subId = mSubscriptionController.getDefaultDataSubId();
1622         final Phone phone = getPhone(subId);
1623         if (phone != null) {
1624             phone.setUserDataEnabled(false);
1625             return true;
1626         } else {
1627             return false;
1628         }
1629     }
1630 
1631     @Override
isDataConnectivityPossible(int subId)1632     public boolean isDataConnectivityPossible(int subId) {
1633         final Phone phone = getPhone(subId);
1634         if (phone != null) {
1635             return phone.isDataAllowed();
1636         } else {
1637             return false;
1638         }
1639     }
1640 
handlePinMmi(String dialString)1641     public boolean handlePinMmi(String dialString) {
1642         return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
1643     }
1644 
handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback)1645     public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
1646       enforceCallPermission();
1647       if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1648           return;
1649       }
1650       Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
1651       sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
1652     };
1653 
handlePinMmiForSubscriber(int subId, String dialString)1654     public boolean handlePinMmiForSubscriber(int subId, String dialString) {
1655         enforceModifyPermission();
1656         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1657             return false;
1658         }
1659         return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
1660     }
1661 
getCallState()1662     public int getCallState() {
1663         return getCallStateForSlot(getSlotForDefaultSubscription());
1664     }
1665 
getCallStateForSlot(int slotIndex)1666     public int getCallStateForSlot(int slotIndex) {
1667         Phone phone = PhoneFactory.getPhone(slotIndex);
1668         return phone == null ? TelephonyManager.CALL_STATE_IDLE :
1669             PhoneConstantConversions.convertCallState(phone.getState());
1670     }
1671 
1672     @Override
getDataState()1673     public int getDataState() {
1674         Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1675         if (phone != null) {
1676             return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
1677         } else {
1678             return PhoneConstantConversions.convertDataState(PhoneConstants.DataState.DISCONNECTED);
1679         }
1680     }
1681 
1682     @Override
getDataActivity()1683     public int getDataActivity() {
1684         Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1685         if (phone != null) {
1686             return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
1687         } else {
1688             return TelephonyManager.DATA_ACTIVITY_NONE;
1689         }
1690     }
1691 
1692     @Override
getCellLocation(String callingPackage)1693     public Bundle getCellLocation(String callingPackage) {
1694         mPhone.getContext().getSystemService(AppOpsManager.class)
1695                 .checkPackage(Binder.getCallingUid(), callingPackage);
1696         if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
1697                 callingPackage, Binder.getCallingUid(), Binder.getCallingPid(), true)) {
1698             return null;
1699         }
1700 
1701         if (DBG_LOC) log("getCellLocation: is active user");
1702         Bundle data = new Bundle();
1703         Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1704         if (phone == null) {
1705             return null;
1706         }
1707 
1708         WorkSource workSource = getWorkSource(Binder.getCallingUid());
1709         phone.getCellLocation(workSource).fillInNotifierBundle(data);
1710         return data;
1711     }
1712 
1713     @Override
getNetworkCountryIsoForPhone(int phoneId)1714     public String getNetworkCountryIsoForPhone(int phoneId) {
1715         // Reporting the correct network country is ambiguous when IWLAN could conflict with
1716         // registered cell info, so return a NULL country instead.
1717         final long identity = Binder.clearCallingIdentity();
1718         try {
1719             final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
1720             // Todo: fix this when we can get the actual cellular network info when the device
1721             // is on IWLAN.
1722             if (TelephonyManager.NETWORK_TYPE_IWLAN
1723                     == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName())) {
1724                 return "";
1725             }
1726         } finally {
1727             Binder.restoreCallingIdentity(identity);
1728         }
1729 
1730         Phone phone = PhoneFactory.getPhone(phoneId);
1731         if (phone != null) {
1732             ServiceStateTracker sst = phone.getServiceStateTracker();
1733             if (sst != null) {
1734                 LocaleTracker lt = sst.getLocaleTracker();
1735                 if (lt != null) {
1736                     return lt.getCurrentCountry();
1737                 }
1738             }
1739         }
1740         return "";
1741     }
1742 
1743     @Override
enableLocationUpdates()1744     public void enableLocationUpdates() {
1745         enableLocationUpdatesForSubscriber(getDefaultSubscription());
1746     }
1747 
1748     @Override
enableLocationUpdatesForSubscriber(int subId)1749     public void enableLocationUpdatesForSubscriber(int subId) {
1750         mApp.enforceCallingOrSelfPermission(
1751                 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
1752         final Phone phone = getPhone(subId);
1753         if (phone != null) {
1754             phone.enableLocationUpdates();
1755         }
1756     }
1757 
1758     @Override
disableLocationUpdates()1759     public void disableLocationUpdates() {
1760         disableLocationUpdatesForSubscriber(getDefaultSubscription());
1761     }
1762 
1763     @Override
disableLocationUpdatesForSubscriber(int subId)1764     public void disableLocationUpdatesForSubscriber(int subId) {
1765         mApp.enforceCallingOrSelfPermission(
1766                 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
1767         final Phone phone = getPhone(subId);
1768         if (phone != null) {
1769             phone.disableLocationUpdates();
1770         }
1771     }
1772 
1773     @Override
1774     @SuppressWarnings("unchecked")
getNeighboringCellInfo(String callingPackage)1775     public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) {
1776         mPhone.getContext().getSystemService(AppOpsManager.class)
1777                 .checkPackage(Binder.getCallingUid(), callingPackage);
1778         if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
1779                 callingPackage, Binder.getCallingUid(), Binder.getCallingPid(), true)) {
1780             return null;
1781         }
1782 
1783         if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(),
1784                 callingPackage) != AppOpsManager.MODE_ALLOWED) {
1785             return null;
1786         }
1787 
1788         if (DBG_LOC) log("getNeighboringCellInfo: is active user");
1789 
1790         ArrayList<NeighboringCellInfo> cells = null;
1791 
1792         WorkSource workSource = getWorkSource(Binder.getCallingUid());
1793         try {
1794             cells = (ArrayList<NeighboringCellInfo>) sendRequest(
1795                     CMD_HANDLE_NEIGHBORING_CELL, workSource,
1796                     SubscriptionManager.INVALID_SUBSCRIPTION_ID);
1797         } catch (RuntimeException e) {
1798             Log.e(LOG_TAG, "getNeighboringCellInfo " + e);
1799         }
1800         return cells;
1801     }
1802 
1803 
1804     @Override
getAllCellInfo(String callingPackage)1805     public List<CellInfo> getAllCellInfo(String callingPackage) {
1806         mPhone.getContext().getSystemService(AppOpsManager.class)
1807                 .checkPackage(Binder.getCallingUid(), callingPackage);
1808         if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
1809                 callingPackage, Binder.getCallingUid(), Binder.getCallingPid(), true)) {
1810             return null;
1811         }
1812 
1813         if (DBG_LOC) log("getAllCellInfo: is active user");
1814         WorkSource workSource = getWorkSource(Binder.getCallingUid());
1815         List<CellInfo> cellInfos = new ArrayList<CellInfo>();
1816         for (Phone phone : PhoneFactory.getPhones()) {
1817             final List<CellInfo> info = phone.getAllCellInfo(workSource);
1818             if (info != null) cellInfos.addAll(info);
1819         }
1820         return cellInfos;
1821     }
1822 
1823     @Override
setCellInfoListRate(int rateInMillis)1824     public void setCellInfoListRate(int rateInMillis) {
1825         enforceModifyPermission();
1826         WorkSource workSource = getWorkSource(Binder.getCallingUid());
1827         mPhone.setCellInfoListRate(rateInMillis, workSource);
1828     }
1829 
1830     @Override
getImeiForSlot(int slotIndex, String callingPackage)1831     public String getImeiForSlot(int slotIndex, String callingPackage) {
1832         Phone phone = PhoneFactory.getPhone(slotIndex);
1833         if (phone == null) {
1834             return null;
1835         }
1836         int subId = phone.getSubId();
1837         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1838                 mApp, subId, callingPackage, "getImeiForSlot")) {
1839             return null;
1840         }
1841         return phone.getImei();
1842     }
1843 
1844     @Override
getMeidForSlot(int slotIndex, String callingPackage)1845     public String getMeidForSlot(int slotIndex, String callingPackage) {
1846         Phone phone = PhoneFactory.getPhone(slotIndex);
1847         if (phone == null) {
1848             return null;
1849         }
1850         int subId = phone.getSubId();
1851         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1852                 mApp, subId, callingPackage, "getMeidForSlot")) {
1853             return null;
1854         }
1855         return phone.getMeid();
1856     }
1857 
1858     @Override
getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage)1859     public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) {
1860         Phone phone = PhoneFactory.getPhone(slotIndex);
1861         if (phone == null) {
1862             return null;
1863         }
1864         int subId = phone.getSubId();
1865         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1866                 mApp, subId, callingPackage, "getDeviceSoftwareVersionForSlot")) {
1867             return null;
1868         }
1869         return phone.getDeviceSvn();
1870     }
1871 
1872     @Override
getSubscriptionCarrierId(int subId)1873     public int getSubscriptionCarrierId(int subId) {
1874         final Phone phone = getPhone(subId);
1875         return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
1876     }
1877 
1878     @Override
getSubscriptionCarrierName(int subId)1879     public String getSubscriptionCarrierName(int subId) {
1880         final Phone phone = getPhone(subId);
1881         return phone == null ? null : phone.getCarrierName();
1882     }
1883 
1884     //
1885     // Internal helper methods.
1886     //
1887 
1888     /**
1889      * Make sure the caller has the MODIFY_PHONE_STATE permission.
1890      *
1891      * @throws SecurityException if the caller does not have the required permission
1892      */
enforceModifyPermission()1893     private void enforceModifyPermission() {
1894         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
1895     }
1896 
1897     /**
1898      * Make sure the caller has the CALL_PHONE permission.
1899      *
1900      * @throws SecurityException if the caller does not have the required permission
1901      */
enforceCallPermission()1902     private void enforceCallPermission() {
1903         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
1904     }
1905 
enforceConnectivityInternalPermission()1906     private void enforceConnectivityInternalPermission() {
1907         mApp.enforceCallingOrSelfPermission(
1908                 android.Manifest.permission.CONNECTIVITY_INTERNAL,
1909                 "ConnectivityService");
1910     }
1911 
createTelUrl(String number)1912     private String createTelUrl(String number) {
1913         if (TextUtils.isEmpty(number)) {
1914             return null;
1915         }
1916 
1917         return "tel:" + number;
1918     }
1919 
log(String msg)1920     private static void log(String msg) {
1921         Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
1922     }
1923 
logv(String msg)1924     private static void logv(String msg) {
1925         Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
1926     }
1927 
loge(String msg)1928     private static void loge(String msg) {
1929         Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
1930     }
1931 
1932     @Override
getActivePhoneType()1933     public int getActivePhoneType() {
1934         return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
1935     }
1936 
1937     @Override
getActivePhoneTypeForSlot(int slotIndex)1938     public int getActivePhoneTypeForSlot(int slotIndex) {
1939         final Phone phone = PhoneFactory.getPhone(slotIndex);
1940         if (phone == null) {
1941             return PhoneConstants.PHONE_TYPE_NONE;
1942         } else {
1943             return phone.getPhoneType();
1944         }
1945     }
1946 
1947     /**
1948      * Returns the CDMA ERI icon index to display
1949      */
1950     @Override
getCdmaEriIconIndex(String callingPackage)1951     public int getCdmaEriIconIndex(String callingPackage) {
1952         return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage);
1953     }
1954 
1955     @Override
getCdmaEriIconIndexForSubscriber(int subId, String callingPackage)1956     public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) {
1957         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1958                 mApp, subId, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
1959             return -1;
1960         }
1961         final Phone phone = getPhone(subId);
1962         if (phone != null) {
1963             return phone.getCdmaEriIconIndex();
1964         } else {
1965             return -1;
1966         }
1967     }
1968 
1969     /**
1970      * Returns the CDMA ERI icon mode,
1971      * 0 - ON
1972      * 1 - FLASHING
1973      */
1974     @Override
getCdmaEriIconMode(String callingPackage)1975     public int getCdmaEriIconMode(String callingPackage) {
1976         return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage);
1977     }
1978 
1979     @Override
getCdmaEriIconModeForSubscriber(int subId, String callingPackage)1980     public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) {
1981         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
1982                 mApp, subId, callingPackage, "getCdmaEriIconModeForSubscriber")) {
1983             return -1;
1984         }
1985         final Phone phone = getPhone(subId);
1986         if (phone != null) {
1987             return phone.getCdmaEriIconMode();
1988         } else {
1989             return -1;
1990         }
1991     }
1992 
1993     /**
1994      * Returns the CDMA ERI text,
1995      */
1996     @Override
getCdmaEriText(String callingPackage)1997     public String getCdmaEriText(String callingPackage) {
1998         return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage);
1999     }
2000 
2001     @Override
getCdmaEriTextForSubscriber(int subId, String callingPackage)2002     public String getCdmaEriTextForSubscriber(int subId, String callingPackage) {
2003         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2004                 mApp, subId, callingPackage, "getCdmaEriIconTextForSubscriber")) {
2005             return null;
2006         }
2007         final Phone phone = getPhone(subId);
2008         if (phone != null) {
2009             return phone.getCdmaEriText();
2010         } else {
2011             return null;
2012         }
2013     }
2014 
2015     /**
2016      * Returns the CDMA MDN.
2017      */
2018     @Override
getCdmaMdn(int subId)2019     public String getCdmaMdn(int subId) {
2020         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2021                 mApp, subId, "getCdmaMdn");
2022         final Phone phone = getPhone(subId);
2023         if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA && phone != null) {
2024             return phone.getLine1Number();
2025         } else {
2026             return null;
2027         }
2028     }
2029 
2030     /**
2031      * Returns the CDMA MIN.
2032      */
2033     @Override
getCdmaMin(int subId)2034     public String getCdmaMin(int subId) {
2035         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2036                 mApp, subId, "getCdmaMin");
2037         final Phone phone = getPhone(subId);
2038         if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2039             return phone.getCdmaMin();
2040         } else {
2041             return null;
2042         }
2043     }
2044 
2045     /**
2046      * Returns true if CDMA provisioning needs to run.
2047      */
needsOtaServiceProvisioning()2048     public boolean needsOtaServiceProvisioning() {
2049         return mPhone.needsOtaServiceProvisioning();
2050     }
2051 
2052     /**
2053      * Sets the voice mail number of a given subId.
2054      */
2055     @Override
setVoiceMailNumber(int subId, String alphaTag, String number)2056     public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
2057         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setVoiceMailNumber");
2058         Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
2059                 new Pair<String, String>(alphaTag, number), new Integer(subId));
2060         return success;
2061     }
2062 
2063     @Override
getVisualVoicemailSettings(String callingPackage, int subId)2064     public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
2065         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2066         String systemDialer = TelecomManager.from(mPhone.getContext()).getSystemDialerPackage();
2067         if (!TextUtils.equals(callingPackage, systemDialer)) {
2068             throw new SecurityException("caller must be system dialer");
2069         }
2070         PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
2071         if (phoneAccountHandle == null){
2072             return null;
2073         }
2074         return VisualVoicemailSettingsUtil.dump(mPhone.getContext(), phoneAccountHandle);
2075     }
2076 
2077     @Override
getVisualVoicemailPackageName(String callingPackage, int subId)2078     public String getVisualVoicemailPackageName(String callingPackage, int subId) {
2079         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2080         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2081                 mApp, subId, callingPackage, "getVisualVoicemailPackageName")) {
2082             return null;
2083         }
2084         final long identity = Binder.clearCallingIdentity();
2085         try {
2086             return RemoteVvmTaskManager
2087                     .getRemotePackage(mPhone.getContext(), subId).getPackageName();
2088         } finally {
2089             Binder.restoreCallingIdentity(identity);
2090         }
2091     }
2092 
2093     @Override
enableVisualVoicemailSmsFilter(String callingPackage, int subId, VisualVoicemailSmsFilterSettings settings)2094     public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
2095             VisualVoicemailSmsFilterSettings settings) {
2096         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2097         VisualVoicemailSmsFilterConfig
2098                 .enableVisualVoicemailSmsFilter(mPhone.getContext(), callingPackage, subId,
2099                         settings);
2100     }
2101 
2102     @Override
disableVisualVoicemailSmsFilter(String callingPackage, int subId)2103     public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
2104         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2105         VisualVoicemailSmsFilterConfig
2106                 .disableVisualVoicemailSmsFilter(mPhone.getContext(), callingPackage, subId);
2107     }
2108 
2109     @Override
getVisualVoicemailSmsFilterSettings( String callingPackage, int subId)2110     public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
2111             String callingPackage, int subId) {
2112         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2113         return VisualVoicemailSmsFilterConfig
2114                 .getVisualVoicemailSmsFilterSettings(mPhone.getContext(), callingPackage, subId);
2115     }
2116 
2117     @Override
getActiveVisualVoicemailSmsFilterSettings(int subId)2118     public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
2119         enforceReadPrivilegedPermission();
2120         return VisualVoicemailSmsFilterConfig
2121                 .getActiveVisualVoicemailSmsFilterSettings(mPhone.getContext(), subId);
2122     }
2123 
2124     @Override
sendVisualVoicemailSmsForSubscriber(String callingPackage, int subId, String number, int port, String text, PendingIntent sentIntent)2125     public void sendVisualVoicemailSmsForSubscriber(String callingPackage, int subId,
2126             String number, int port, String text, PendingIntent sentIntent) {
2127         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2128         enforceVisualVoicemailPackage(callingPackage, subId);
2129         enforceSendSmsPermission();
2130         // Make the calls as the phone process.
2131         final long identity = Binder.clearCallingIdentity();
2132         try {
2133             SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId);
2134             if (port == 0) {
2135                 smsManager.sendTextMessageWithSelfPermissions(number, null, text,
2136                         sentIntent, null, false);
2137             } else {
2138                 byte[] data = text.getBytes(StandardCharsets.UTF_8);
2139                 smsManager.sendDataMessageWithSelfPermissions(number, null,
2140                         (short) port, data, sentIntent, null);
2141             }
2142         } finally {
2143             Binder.restoreCallingIdentity(identity);
2144         }
2145     }
2146     /**
2147      * Sets the voice activation state of a given subId.
2148      */
2149     @Override
setVoiceActivationState(int subId, int activationState)2150     public void setVoiceActivationState(int subId, int activationState) {
2151         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2152                 mApp, subId, "setVoiceActivationState");
2153         final Phone phone = getPhone(subId);
2154         if (phone != null) {
2155             phone.setVoiceActivationState(activationState);
2156         } else {
2157             loge("setVoiceActivationState fails with invalid subId: " + subId);
2158         }
2159     }
2160 
2161     /**
2162      * Sets the data activation state of a given subId.
2163      */
2164     @Override
setDataActivationState(int subId, int activationState)2165     public void setDataActivationState(int subId, int activationState) {
2166         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2167                 mApp, subId, "setDataActivationState");
2168         final Phone phone = getPhone(subId);
2169         if (phone != null) {
2170             phone.setDataActivationState(activationState);
2171         } else {
2172             loge("setVoiceActivationState fails with invalid subId: " + subId);
2173         }
2174     }
2175 
2176     /**
2177      * Returns the voice activation state of a given subId.
2178      */
2179     @Override
getVoiceActivationState(int subId, String callingPackage)2180     public int getVoiceActivationState(int subId, String callingPackage) {
2181         enforceReadPrivilegedPermission();
2182         final Phone phone = getPhone(subId);
2183         if (phone != null) {
2184             return phone.getVoiceActivationState();
2185         } else {
2186             return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2187         }
2188     }
2189 
2190     /**
2191      * Returns the data activation state of a given subId.
2192      */
2193     @Override
getDataActivationState(int subId, String callingPackage)2194     public int getDataActivationState(int subId, String callingPackage) {
2195         enforceReadPrivilegedPermission();
2196         final Phone phone = getPhone(subId);
2197         if (phone != null) {
2198             return phone.getDataActivationState();
2199         } else {
2200             return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2201         }
2202     }
2203 
2204     /**
2205      * Returns the unread count of voicemails
2206      */
getVoiceMessageCount()2207     public int getVoiceMessageCount() {
2208         return getVoiceMessageCountForSubscriber(getDefaultSubscription());
2209     }
2210 
2211     /**
2212      * Returns the unread count of voicemails for a subId
2213      */
2214     @Override
getVoiceMessageCountForSubscriber( int subId)2215     public int getVoiceMessageCountForSubscriber( int subId) {
2216         final Phone phone = getPhone(subId);
2217         if (phone != null) {
2218             return phone.getVoiceMessageCount();
2219         } else {
2220             return 0;
2221         }
2222     }
2223 
2224     /**
2225       * returns true, if the device is in a state where both voice and data
2226       * are supported simultaneously. This can change based on location or network condition.
2227      */
2228     @Override
isConcurrentVoiceAndDataAllowed(int subId)2229     public boolean isConcurrentVoiceAndDataAllowed(int subId) {
2230         final Phone phone = getPhone(subId);
2231         return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
2232     }
2233 
2234     /**
2235      * Send the dialer code if called from the current default dialer or the caller has
2236      * carrier privilege.
2237      * @param inputCode The dialer code to send
2238      */
2239     @Override
sendDialerSpecialCode(String callingPackage, String inputCode)2240     public void sendDialerSpecialCode(String callingPackage, String inputCode) {
2241         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2242         String defaultDialer = TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage();
2243         if (!TextUtils.equals(callingPackage, defaultDialer)) {
2244             TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
2245                     getDefaultSubscription(), "sendDialerSpecialCode");
2246         }
2247         mPhone.sendDialerSpecialCode(inputCode);
2248     }
2249 
2250     /**
2251      * Returns the data network type.
2252      * Legacy call, permission-free.
2253      *
2254      * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}.
2255      */
2256     @Override
getNetworkType()2257     public int getNetworkType() {
2258         final Phone phone = getPhone(getDefaultSubscription());
2259         if (phone != null) {
2260             return phone.getServiceState().getDataNetworkType();
2261         } else {
2262             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2263         }
2264     }
2265 
2266     /**
2267      * Returns the network type for a subId
2268      */
2269     @Override
getNetworkTypeForSubscriber(int subId, String callingPackage)2270     public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
2271         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2272                 mApp, subId, callingPackage, "getNetworkTypeForSubscriber")) {
2273             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2274         }
2275 
2276         final Phone phone = getPhone(subId);
2277         if (phone != null) {
2278             return phone.getServiceState().getDataNetworkType();
2279         } else {
2280             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2281         }
2282     }
2283 
2284     /**
2285      * Returns the data network type
2286      */
2287     @Override
getDataNetworkType(String callingPackage)2288     public int getDataNetworkType(String callingPackage) {
2289         return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage);
2290     }
2291 
2292     /**
2293      * Returns the data network type for a subId
2294      */
2295     @Override
getDataNetworkTypeForSubscriber(int subId, String callingPackage)2296     public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
2297         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2298                 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
2299             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2300         }
2301 
2302         final Phone phone = getPhone(subId);
2303         if (phone != null) {
2304             return phone.getServiceState().getDataNetworkType();
2305         } else {
2306             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2307         }
2308     }
2309 
2310     /**
2311      * Returns the Voice network type for a subId
2312      */
2313     @Override
getVoiceNetworkTypeForSubscriber(int subId, String callingPackage)2314     public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) {
2315         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2316                 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
2317             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2318         }
2319 
2320         final Phone phone = getPhone(subId);
2321         if (phone != null) {
2322             return phone.getServiceState().getVoiceNetworkType();
2323         } else {
2324             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2325         }
2326     }
2327 
2328     /**
2329      * @return true if a ICC card is present
2330      */
hasIccCard()2331     public boolean hasIccCard() {
2332         // FIXME Make changes to pass defaultSimId of type int
2333         return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
2334                 getDefaultSubscription()));
2335     }
2336 
2337     /**
2338      * @return true if a ICC card is present for a slotIndex
2339      */
2340     @Override
hasIccCardUsingSlotIndex(int slotIndex)2341     public boolean hasIccCardUsingSlotIndex(int slotIndex) {
2342         final Phone phone = PhoneFactory.getPhone(slotIndex);
2343         if (phone != null) {
2344             return phone.getIccCard().hasIccCard();
2345         } else {
2346             return false;
2347         }
2348     }
2349 
2350     /**
2351      * Return if the current radio is LTE on CDMA. This
2352      * is a tri-state return value as for a period of time
2353      * the mode may be unknown.
2354      *
2355      * @param callingPackage the name of the package making the call.
2356      * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
2357      * or {@link Phone#LTE_ON_CDMA_TRUE}
2358      */
2359     @Override
getLteOnCdmaMode(String callingPackage)2360     public int getLteOnCdmaMode(String callingPackage) {
2361         return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage);
2362     }
2363 
2364     @Override
getLteOnCdmaModeForSubscriber(int subId, String callingPackage)2365     public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) {
2366         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2367                 mApp, subId, callingPackage, "getLteOnCdmaModeForSubscriber")) {
2368             return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
2369         }
2370 
2371         final Phone phone = getPhone(subId);
2372         if (phone == null) {
2373             return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
2374         } else {
2375             return phone.getLteOnCdmaMode();
2376         }
2377     }
2378 
setPhone(Phone phone)2379     public void setPhone(Phone phone) {
2380         mPhone = phone;
2381     }
2382 
2383     /**
2384      * {@hide}
2385      * Returns Default subId, 0 in the case of single standby.
2386      */
getDefaultSubscription()2387     private int getDefaultSubscription() {
2388         return mSubscriptionController.getDefaultSubId();
2389     }
2390 
getSlotForDefaultSubscription()2391     private int getSlotForDefaultSubscription() {
2392         return mSubscriptionController.getPhoneId(getDefaultSubscription());
2393     }
2394 
getPreferredVoiceSubscription()2395     private int getPreferredVoiceSubscription() {
2396         return mSubscriptionController.getDefaultVoiceSubId();
2397     }
2398 
2399     /**
2400      * @see android.telephony.TelephonyManager.WifiCallingChoices
2401      */
getWhenToMakeWifiCalls()2402     public int getWhenToMakeWifiCalls() {
2403         return Settings.System.getInt(mPhone.getContext().getContentResolver(),
2404                 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, getWhenToMakeWifiCallsDefaultPreference());
2405     }
2406 
2407     /**
2408      * @see android.telephony.TelephonyManager.WifiCallingChoices
2409      */
setWhenToMakeWifiCalls(int preference)2410     public void setWhenToMakeWifiCalls(int preference) {
2411         if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
2412         Settings.System.putInt(mPhone.getContext().getContentResolver(),
2413                 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
2414     }
2415 
getWhenToMakeWifiCallsDefaultPreference()2416     private static int getWhenToMakeWifiCallsDefaultPreference() {
2417         // TODO: Use a build property to choose this value.
2418         return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
2419     }
2420 
2421     @Override
iccOpenLogicalChannel( int subId, String callingPackage, String aid, int p2)2422     public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
2423             int subId, String callingPackage, String aid, int p2) {
2424         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2425                 mApp, subId, "iccOpenLogicalChannel");
2426 
2427         if (TextUtils.equals(ISDR_AID, aid)) {
2428             // Only allows LPA to open logical channel to ISD-R.
2429             mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2430             ComponentInfo bestComponent =
2431                     EuiccConnector.findBestComponent(mPhone.getContext().getPackageManager());
2432             if (bestComponent == null
2433                     || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
2434                 loge("The calling package is not allowed to access ISD-R.");
2435                 throw new SecurityException("The calling package is not allowed to access ISD-R.");
2436             }
2437         }
2438 
2439         if (DBG) log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
2440         IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse)sendRequest(
2441                 CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), subId);
2442         if (DBG) log("iccOpenLogicalChannel: " + response);
2443         return response;
2444     }
2445 
2446     @Override
iccCloseLogicalChannel(int subId, int channel)2447     public boolean iccCloseLogicalChannel(int subId, int channel) {
2448         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2449                 mApp, subId, "iccCloseLogicalChannel");
2450 
2451         if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
2452         if (channel < 0) {
2453           return false;
2454         }
2455         Boolean success = (Boolean)sendRequest(CMD_CLOSE_CHANNEL, channel, subId);
2456         if (DBG) log("iccCloseLogicalChannel: " + success);
2457         return success;
2458     }
2459 
2460     @Override
iccTransmitApduLogicalChannel(int subId, int channel, int cla, int command, int p1, int p2, int p3, String data)2461     public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
2462             int command, int p1, int p2, int p3, String data) {
2463         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2464                 mApp, subId, "iccTransmitApduLogicalChannel");
2465 
2466         if (DBG) {
2467             log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel +
2468                     " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 +
2469                     " data=" + data);
2470         }
2471 
2472         if (channel < 0) {
2473             return "";
2474         }
2475 
2476         IccIoResult response = (IccIoResult)sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
2477                 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), subId);
2478         if (DBG) log("iccTransmitApduLogicalChannel: " + response);
2479 
2480         // Append the returned status code to the end of the response payload.
2481         String s = Integer.toHexString(
2482                 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
2483         if (response.payload != null) {
2484             s = IccUtils.bytesToHexString(response.payload) + s;
2485         }
2486         return s;
2487     }
2488 
2489     @Override
iccTransmitApduBasicChannel(int subId, String callingPackage, int cla, int command, int p1, int p2, int p3, String data)2490     public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
2491             int command, int p1, int p2, int p3, String data) {
2492         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2493                 mApp, subId, "iccTransmitApduBasicChannel");
2494 
2495         if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
2496                 && TextUtils.equals(ISDR_AID, data)) {
2497             // Only allows LPA to select ISD-R.
2498             mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2499             ComponentInfo bestComponent =
2500                     EuiccConnector.findBestComponent(mPhone.getContext().getPackageManager());
2501             if (bestComponent == null
2502                     || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
2503                 loge("The calling package is not allowed to select ISD-R.");
2504                 throw new SecurityException("The calling package is not allowed to select ISD-R.");
2505             }
2506         }
2507 
2508         if (DBG) {
2509             log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd=" + command
2510                     + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
2511         }
2512 
2513         IccIoResult response = (IccIoResult)sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
2514                 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), subId);
2515         if (DBG) log("iccTransmitApduBasicChannel: " + response);
2516 
2517         // Append the returned status code to the end of the response payload.
2518         String s = Integer.toHexString(
2519                 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
2520         if (response.payload != null) {
2521             s = IccUtils.bytesToHexString(response.payload) + s;
2522         }
2523         return s;
2524     }
2525 
2526     @Override
iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3, String filePath)2527     public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
2528             String filePath) {
2529         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2530                 mApp, subId, "iccExchangeSimIO");
2531 
2532         if (DBG) {
2533             log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " " +
2534                 p1 + " " + p2 + " " + p3 + ":" + filePath);
2535         }
2536 
2537         IccIoResult response =
2538             (IccIoResult)sendRequest(CMD_EXCHANGE_SIM_IO,
2539                     new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
2540                     subId);
2541 
2542         if (DBG) {
2543           log("Exchange SIM_IO [R]" + response);
2544         }
2545 
2546         byte[] result = null;
2547         int length = 2;
2548         if (response.payload != null) {
2549             length = 2 + response.payload.length;
2550             result = new byte[length];
2551             System.arraycopy(response.payload, 0, result, 0, response.payload.length);
2552         } else {
2553             result = new byte[length];
2554         }
2555 
2556         result[length - 1] = (byte) response.sw2;
2557         result[length - 2] = (byte) response.sw1;
2558         return result;
2559     }
2560 
2561     /**
2562      * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
2563      * on a particular subscription
2564      */
getForbiddenPlmns(int subId, int appType, String callingPackage)2565     public String[] getForbiddenPlmns(int subId, int appType, String callingPackage) {
2566         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2567                 mApp, subId, callingPackage, "getForbiddenPlmns")) {
2568             return null;
2569         }
2570         if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
2571             loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
2572             return null;
2573         }
2574         Object response = sendRequest(
2575             CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
2576         if (response instanceof String[]) {
2577             return (String[]) response;
2578         }
2579         // Response is an Exception of some kind, which is signalled to the user as a NULL retval
2580         return null;
2581     }
2582 
2583     @Override
sendEnvelopeWithStatus(int subId, String content)2584     public String sendEnvelopeWithStatus(int subId, String content) {
2585         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2586                 mApp, subId, "sendEnvelopeWithStatus");
2587 
2588         IccIoResult response = (IccIoResult)sendRequest(CMD_SEND_ENVELOPE, content, subId);
2589         if (response.payload == null) {
2590           return "";
2591         }
2592 
2593         // Append the returned status code to the end of the response payload.
2594         String s = Integer.toHexString(
2595                 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
2596         s = IccUtils.bytesToHexString(response.payload) + s;
2597         return s;
2598     }
2599 
2600     /**
2601      * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
2602      * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
2603      *
2604      * @param itemID the ID of the item to read
2605      * @return the NV item as a String, or null on error.
2606      */
2607     @Override
nvReadItem(int itemID)2608     public String nvReadItem(int itemID) {
2609         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2610                 mApp, getDefaultSubscription(), "nvReadItem");
2611         if (DBG) log("nvReadItem: item " + itemID);
2612         String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID);
2613         if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
2614         return value;
2615     }
2616 
2617     /**
2618      * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
2619      * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
2620      *
2621      * @param itemID the ID of the item to read
2622      * @param itemValue the value to write, as a String
2623      * @return true on success; false on any failure
2624      */
2625     @Override
nvWriteItem(int itemID, String itemValue)2626     public boolean nvWriteItem(int itemID, String itemValue) {
2627         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2628                 mApp, getDefaultSubscription(), "nvWriteItem");
2629         if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
2630         Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
2631                 new Pair<Integer, String>(itemID, itemValue));
2632         if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
2633         return success;
2634     }
2635 
2636     /**
2637      * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
2638      * Used for device configuration by some CDMA operators.
2639      *
2640      * @param preferredRoamingList byte array containing the new PRL
2641      * @return true on success; false on any failure
2642      */
2643     @Override
nvWriteCdmaPrl(byte[] preferredRoamingList)2644     public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
2645         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2646                 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
2647         if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
2648         Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
2649         if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
2650         return success;
2651     }
2652 
2653     /**
2654      * Perform the specified type of NV config reset.
2655      * Used for device configuration by some CDMA operators.
2656      *
2657      * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset)
2658      * @return true on success; false on any failure
2659      */
2660     @Override
nvResetConfig(int resetType)2661     public boolean nvResetConfig(int resetType) {
2662         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2663                 mApp, getDefaultSubscription(), "nvResetConfig");
2664         if (DBG) log("nvResetConfig: type " + resetType);
2665         Boolean success = (Boolean) sendRequest(CMD_NV_RESET_CONFIG, resetType);
2666         if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail"));
2667         return success;
2668     }
2669 
2670     /**
2671      * {@hide}
2672      * Returns Default sim, 0 in the case of single standby.
2673      */
getDefaultSim()2674     public int getDefaultSim() {
2675         //TODO Need to get it from Telephony Devcontroller
2676         return 0;
2677     }
2678 
getPcscfAddress(String apnType, String callingPackage)2679     public String[] getPcscfAddress(String apnType, String callingPackage) {
2680         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2681                 mApp, mPhone.getSubId(), callingPackage, "getPcscfAddress")) {
2682             return new String[0];
2683         }
2684 
2685 
2686         return mPhone.getPcscfAddress(apnType);
2687     }
2688 
2689     /**
2690      * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
2691      * status updates, if not already enabled.
2692      */
enableIms(int slotId)2693     public void enableIms(int slotId) {
2694         enforceModifyPermission();
2695         PhoneFactory.getImsResolver().enableIms(slotId);
2696     }
2697 
2698     /**
2699      * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
2700      * status updates to disabled.
2701      */
disableIms(int slotId)2702     public void disableIms(int slotId) {
2703         enforceModifyPermission();
2704         PhoneFactory.getImsResolver().disableIms(slotId);
2705     }
2706 
2707     /**
2708      * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id for the MMTel
2709      * feature or {@link null} if the service is not available. If the feature is available, the
2710      * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
2711      */
getMmTelFeatureAndListen(int slotId, IImsServiceFeatureCallback callback)2712     public IImsMmTelFeature getMmTelFeatureAndListen(int slotId,
2713             IImsServiceFeatureCallback callback) {
2714         enforceModifyPermission();
2715         return PhoneFactory.getImsResolver().getMmTelFeatureAndListen(slotId, callback);
2716     }
2717 
2718     /**
2719      * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id for the RCS
2720      * feature during emergency calling or {@link null} if the service is not available. If the
2721      * feature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
2722      * listener for feature updates.
2723      */
getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback)2724     public IImsRcsFeature getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback) {
2725         enforceModifyPermission();
2726         return PhoneFactory.getImsResolver().getRcsFeatureAndListen(slotId, callback);
2727     }
2728 
2729     /**
2730      * Returns the {@link IImsRegistration} structure associated with the slotId and feature
2731      * specified.
2732      */
getImsRegistration(int slotId, int feature)2733     public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
2734         enforceModifyPermission();
2735         return PhoneFactory.getImsResolver().getImsRegistration(slotId, feature);
2736     }
2737 
2738     /**
2739      * Returns the {@link IImsConfig} structure associated with the slotId and feature
2740      * specified.
2741      */
getImsConfig(int slotId, int feature)2742     public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
2743         enforceModifyPermission();
2744         return PhoneFactory.getImsResolver().getImsConfig(slotId, feature);
2745     }
2746 
2747     /**
2748      * @return true if the IMS resolver is busy resolving a binding and should not be considered
2749      * available, false if the IMS resolver is idle.
2750      */
isResolvingImsBinding()2751     public boolean isResolvingImsBinding() {
2752         enforceModifyPermission();
2753         return PhoneFactory.getImsResolver().isResolvingBinding();
2754     }
2755 
2756     /**
2757      * Sets the ImsService Package Name that Telephony will bind to.
2758      *
2759      * @param slotId the slot ID that the ImsService should bind for.
2760      * @param isCarrierImsService true if the ImsService is the carrier override, false if the
2761      *         ImsService is the device default ImsService.
2762      * @param packageName The package name of the application that contains the ImsService to bind
2763      *         to.
2764      * @return true if setting the ImsService to bind to succeeded, false if it did not.
2765      * @hide
2766      */
setImsService(int slotId, boolean isCarrierImsService, String packageName)2767     public boolean setImsService(int slotId, boolean isCarrierImsService, String packageName) {
2768         int[] subIds = SubscriptionManager.getSubId(slotId);
2769         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
2770                 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
2771                 "setImsService");
2772 
2773         return PhoneFactory.getImsResolver().overrideImsServiceConfiguration(slotId,
2774                 isCarrierImsService, packageName);
2775     }
2776 
2777     /**
2778      * Return the ImsService configuration.
2779      *
2780      * @param slotId The slot that the ImsService is associated with.
2781      * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
2782      *         the device default.
2783      * @return the package name of the ImsService configuration.
2784      */
getImsService(int slotId, boolean isCarrierImsService)2785     public String getImsService(int slotId, boolean isCarrierImsService) {
2786         int[] subIds = SubscriptionManager.getSubId(slotId);
2787         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
2788                 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
2789                 "getImsService");
2790 
2791         return PhoneFactory.getImsResolver().getImsServiceConfiguration(slotId,
2792                 isCarrierImsService);
2793     }
2794 
setImsRegistrationState(boolean registered)2795     public void setImsRegistrationState(boolean registered) {
2796         enforceModifyPermission();
2797         mPhone.setImsRegistrationState(registered);
2798     }
2799 
2800     /**
2801      * Set the network selection mode to automatic.
2802      *
2803      */
2804     @Override
setNetworkSelectionModeAutomatic(int subId)2805     public void setNetworkSelectionModeAutomatic(int subId) {
2806         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2807                 mApp, subId, "setNetworkSelectionModeAutomatic");
2808         if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
2809         sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
2810     }
2811 
2812     /**
2813      * Set the network selection mode to manual with the selected carrier.
2814      */
2815     @Override
setNetworkSelectionModeManual(int subId, String operatorNumeric, boolean persistSelection)2816     public boolean setNetworkSelectionModeManual(int subId, String operatorNumeric,
2817             boolean persistSelection) {
2818         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2819                 mApp, subId, "setNetworkSelectionModeManual");
2820         OperatorInfo operator = new OperatorInfo(
2821                 /* operatorAlphaLong */ "",
2822                 /* operatorAlphaShort */ "",
2823                 operatorNumeric);
2824         if (DBG) log("setNetworkSelectionModeManual: subId:" + subId + " operator:" + operator);
2825         ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operator,
2826                 persistSelection);
2827         return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
2828     }
2829 
2830     /**
2831      * Scans for available networks.
2832      */
2833     @Override
getCellNetworkScanResults(int subId)2834     public CellNetworkScanResult getCellNetworkScanResults(int subId) {
2835         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2836                 mApp, subId, "getCellNetworkScanResults");
2837         if (DBG) log("getCellNetworkScanResults: subId " + subId);
2838         CellNetworkScanResult result = (CellNetworkScanResult) sendRequest(
2839                 CMD_PERFORM_NETWORK_SCAN, null, subId);
2840         return result;
2841     }
2842 
2843     /**
2844      * Starts a new network scan and returns the id of this scan.
2845      *
2846      * @param subId id of the subscription
2847      * @param request contains the radio access networks with bands/channels to scan
2848      * @param messenger callback messenger for scan results or errors
2849      * @param binder for the purpose of auto clean when the user thread crashes
2850      * @return the id of the requested scan which can be used to stop the scan.
2851      */
2852     @Override
requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger, IBinder binder)2853     public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
2854             IBinder binder) {
2855         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2856                 mApp, subId, "requestNetworkScan");
2857         return mNetworkScanRequestTracker.startNetworkScan(
2858                 request, messenger, binder, getPhone(subId));
2859     }
2860 
2861     /**
2862      * Stops an existing network scan with the given scanId.
2863      *
2864      * @param subId id of the subscription
2865      * @param scanId id of the scan that needs to be stopped
2866      */
2867     @Override
stopNetworkScan(int subId, int scanId)2868     public void stopNetworkScan(int subId, int scanId) {
2869         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2870                 mApp, subId, "stopNetworkScan");
2871         mNetworkScanRequestTracker.stopNetworkScan(scanId);
2872     }
2873 
2874     /**
2875      * Get the calculated preferred network type.
2876      * Used for debugging incorrect network type.
2877      *
2878      * @return the preferred network type, defined in RILConstants.java.
2879      */
2880     @Override
getCalculatedPreferredNetworkType(String callingPackage)2881     public int getCalculatedPreferredNetworkType(String callingPackage) {
2882         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2883                 mApp, mPhone.getSubId(), callingPackage, "getCalculatedPreferredNetworkType")) {
2884             return RILConstants.PREFERRED_NETWORK_MODE;
2885         }
2886 
2887         return PhoneFactory.calculatePreferredNetworkType(mPhone.getContext(), 0); // wink FIXME: need to get SubId from somewhere.
2888     }
2889 
2890     /**
2891      * Get the preferred network type.
2892      * Used for device configuration by some CDMA operators.
2893      *
2894      * @return the preferred network type, defined in RILConstants.java.
2895      */
2896     @Override
getPreferredNetworkType(int subId)2897     public int getPreferredNetworkType(int subId) {
2898         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2899                 mApp, subId, "getPreferredNetworkType");
2900         if (DBG) log("getPreferredNetworkType");
2901         int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
2902         int networkType = (result != null ? result[0] : -1);
2903         if (DBG) log("getPreferredNetworkType: " + networkType);
2904         return networkType;
2905     }
2906 
2907     /**
2908      * Set the preferred network type.
2909      * Used for device configuration by some CDMA operators.
2910      *
2911      * @param networkType the preferred network type, defined in RILConstants.java.
2912      * @return true on success; false on any failure.
2913      */
2914     @Override
setPreferredNetworkType(int subId, int networkType)2915     public boolean setPreferredNetworkType(int subId, int networkType) {
2916         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2917                 mApp, subId, "setPreferredNetworkType");
2918         if (DBG) log("setPreferredNetworkType: subId " + subId + " type " + networkType);
2919         Boolean success = (Boolean) sendRequest(CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
2920         if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
2921         if (success) {
2922             Settings.Global.putInt(mPhone.getContext().getContentResolver(),
2923                     Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
2924         }
2925         return success;
2926     }
2927 
2928     /**
2929      * Check TETHER_DUN_REQUIRED and TETHER_DUN_APN settings, net.tethering.noprovisioning
2930      * SystemProperty, and config_tether_apndata to decide whether DUN APN is required for
2931      * tethering.
2932      *
2933      * @return 0: Not required. 1: required. 2: Not set.
2934      * @hide
2935      */
2936     @Override
getTetherApnRequired()2937     public int getTetherApnRequired() {
2938         enforceModifyPermission();
2939         int dunRequired = Settings.Global.getInt(mPhone.getContext().getContentResolver(),
2940                 Settings.Global.TETHER_DUN_REQUIRED, 2);
2941         // If not set, check net.tethering.noprovisioning, TETHER_DUN_APN setting and
2942         // config_tether_apndata.
2943         if (dunRequired == 2 && mPhone.hasMatchedTetherApnSetting()) {
2944             dunRequired = 1;
2945         }
2946         return dunRequired;
2947     }
2948 
2949     /**
2950      * Set mobile data enabled
2951      * Used by the user through settings etc to turn on/off mobile data
2952      *
2953      * @param enable {@code true} turn turn data on, else {@code false}
2954      */
2955     @Override
setUserDataEnabled(int subId, boolean enable)2956     public void setUserDataEnabled(int subId, boolean enable) {
2957         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2958                 mApp, subId, "setUserDataEnabled");
2959         int phoneId = mSubscriptionController.getPhoneId(subId);
2960         if (DBG) log("setUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
2961         Phone phone = PhoneFactory.getPhone(phoneId);
2962         if (phone != null) {
2963             if (DBG) log("setUserDataEnabled: subId=" + subId + " enable=" + enable);
2964             phone.setUserDataEnabled(enable);
2965         } else {
2966             loge("setUserDataEnabled: no phone for subId=" + subId);
2967         }
2968     }
2969 
2970     /**
2971      * Get the user enabled state of Mobile Data.
2972      *
2973      * TODO: remove and use isUserDataEnabled.
2974      * This can't be removed now because some vendor codes
2975      * calls through ITelephony directly while they should
2976      * use TelephonyManager.
2977      *
2978      * @return true on enabled
2979      */
2980     @Override
getDataEnabled(int subId)2981     public boolean getDataEnabled(int subId) {
2982         return isUserDataEnabled(subId);
2983     }
2984 
2985     /**
2986      * Get whether mobile data is enabled per user setting.
2987      *
2988      * There are other factors deciding whether mobile data is actually enabled, but they are
2989      * not considered here. See {@link #isDataEnabled(int)} for more details.
2990      *
2991      * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
2992      *
2993      * @return {@code true} if data is enabled else {@code false}
2994      */
2995     @Override
isUserDataEnabled(int subId)2996     public boolean isUserDataEnabled(int subId) {
2997         try {
2998             mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
2999                     null);
3000         } catch (Exception e) {
3001             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3002                     mApp, subId, "isUserDataEnabled");
3003         }
3004         int phoneId = mSubscriptionController.getPhoneId(subId);
3005         if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3006         Phone phone = PhoneFactory.getPhone(phoneId);
3007         if (phone != null) {
3008             boolean retVal = phone.isUserDataEnabled();
3009             if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
3010             return retVal;
3011         } else {
3012             if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
3013             return false;
3014         }
3015     }
3016 
3017     /**
3018      * Get whether mobile data is enabled.
3019      *
3020      * Comparable to {@link #isUserDataEnabled(int)}, this considers all factors deciding
3021      * whether mobile data is actually enabled.
3022      *
3023      * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
3024      *
3025      * @return {@code true} if data is enabled else {@code false}
3026      */
3027     @Override
isDataEnabled(int subId)3028     public boolean isDataEnabled(int subId) {
3029         try {
3030             mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
3031                     null);
3032         } catch (Exception e) {
3033             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3034                     mApp, subId, "isDataEnabled");
3035         }
3036         int phoneId = mSubscriptionController.getPhoneId(subId);
3037         if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3038         Phone phone = PhoneFactory.getPhone(phoneId);
3039         if (phone != null) {
3040             boolean retVal = phone.isDataEnabled();
3041             if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
3042             return retVal;
3043         } else {
3044             if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
3045             return false;
3046         }
3047     }
3048 
3049     @Override
getCarrierPrivilegeStatus(int subId)3050     public int getCarrierPrivilegeStatus(int subId) {
3051         final Phone phone = getPhone(subId);
3052         if (phone == null) {
3053             loge("getCarrierPrivilegeStatus: Invalid subId");
3054             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3055         }
3056         UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
3057         if (card == null) {
3058             loge("getCarrierPrivilegeStatus: No UICC");
3059             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3060         }
3061         return card.getCarrierPrivilegeStatusForCurrentTransaction(
3062                 phone.getContext().getPackageManager());
3063     }
3064 
3065     @Override
getCarrierPrivilegeStatusForUid(int subId, int uid)3066     public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
3067         final Phone phone = getPhone(subId);
3068         if (phone == null) {
3069             loge("getCarrierPrivilegeStatus: Invalid subId");
3070             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3071         }
3072         UiccProfile profile =
3073                 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
3074         if (profile == null) {
3075             loge("getCarrierPrivilegeStatus: No UICC");
3076             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3077         }
3078         return profile.getCarrierPrivilegeStatusForUid(phone.getContext().getPackageManager(), uid);
3079     }
3080 
3081     @Override
checkCarrierPrivilegesForPackage(String pkgName)3082     public int checkCarrierPrivilegesForPackage(String pkgName) {
3083         if (TextUtils.isEmpty(pkgName))
3084             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3085         UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
3086         if (card == null) {
3087             loge("checkCarrierPrivilegesForPackage: No UICC");
3088             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3089         }
3090         return card.getCarrierPrivilegeStatus(mPhone.getContext().getPackageManager(), pkgName);
3091     }
3092 
3093     @Override
checkCarrierPrivilegesForPackageAnyPhone(String pkgName)3094     public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
3095         if (TextUtils.isEmpty(pkgName))
3096             return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3097         int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3098         for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3099             UiccCard card = UiccController.getInstance().getUiccCard(i);
3100             if (card == null) {
3101               // No UICC in that slot.
3102               continue;
3103             }
3104 
3105             result = card.getCarrierPrivilegeStatus(
3106                 mPhone.getContext().getPackageManager(), pkgName);
3107             if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3108                 break;
3109             }
3110         }
3111 
3112         return result;
3113     }
3114 
3115     @Override
getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId)3116     public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
3117         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
3118             loge("phoneId " + phoneId + " is not valid.");
3119             return null;
3120         }
3121         UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
3122         if (card == null) {
3123             loge("getCarrierPackageNamesForIntent: No UICC");
3124             return null ;
3125         }
3126         return card.getCarrierPackageNamesForIntent(
3127                 mPhone.getContext().getPackageManager(), intent);
3128     }
3129 
3130     @Override
getPackagesWithCarrierPrivileges()3131     public List<String> getPackagesWithCarrierPrivileges() {
3132         PackageManager pm = mPhone.getContext().getPackageManager();
3133         List<String> privilegedPackages = new ArrayList<>();
3134         List<PackageInfo> packages = null;
3135         for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3136             UiccCard card = UiccController.getInstance().getUiccCard(i);
3137             if (card == null) {
3138                 // No UICC in that slot.
3139                 continue;
3140             }
3141             if (card.hasCarrierPrivilegeRules()) {
3142                 if (packages == null) {
3143                     // Only check packages in user 0 for now
3144                     packages = pm.getInstalledPackagesAsUser(
3145                             PackageManager.MATCH_DISABLED_COMPONENTS
3146                             | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
3147                             | PackageManager.GET_SIGNATURES, UserHandle.USER_SYSTEM);
3148                 }
3149                 for (int p = packages.size() - 1; p >= 0; p--) {
3150                     PackageInfo pkgInfo = packages.get(p);
3151                     if (pkgInfo != null && pkgInfo.packageName != null
3152                             && card.getCarrierPrivilegeStatus(pkgInfo)
3153                                 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3154                         privilegedPackages.add(pkgInfo.packageName);
3155                     }
3156                 }
3157             }
3158         }
3159         return privilegedPackages;
3160     }
3161 
getIccId(int subId)3162     private String getIccId(int subId) {
3163         final Phone phone = getPhone(subId);
3164         UiccCard card = phone == null ? null : phone.getUiccCard();
3165         if (card == null) {
3166             loge("getIccId: No UICC");
3167             return null;
3168         }
3169         String iccId = card.getIccId();
3170         if (TextUtils.isEmpty(iccId)) {
3171             loge("getIccId: ICC ID is null or empty.");
3172             return null;
3173         }
3174         return iccId;
3175     }
3176 
3177     @Override
setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, String number)3178     public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
3179             String number) {
3180         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
3181                 subId, "setLine1NumberForDisplayForSubscriber");
3182 
3183         final String iccId = getIccId(subId);
3184         final Phone phone = getPhone(subId);
3185         if (phone == null) {
3186             return false;
3187         }
3188         final String subscriberId = phone.getSubscriberId();
3189 
3190         if (DBG_MERGE) {
3191             Slog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
3192                     + subscriberId + " to " + number);
3193         }
3194 
3195         if (TextUtils.isEmpty(iccId)) {
3196             return false;
3197         }
3198 
3199         final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
3200 
3201         final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
3202         if (alphaTag == null) {
3203             editor.remove(alphaTagPrefKey);
3204         } else {
3205             editor.putString(alphaTagPrefKey, alphaTag);
3206         }
3207 
3208         // Record both the line number and IMSI for this ICCID, since we need to
3209         // track all merged IMSIs based on line number
3210         final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
3211         final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
3212         if (number == null) {
3213             editor.remove(numberPrefKey);
3214             editor.remove(subscriberPrefKey);
3215         } else {
3216             editor.putString(numberPrefKey, number);
3217             editor.putString(subscriberPrefKey, subscriberId);
3218         }
3219 
3220         editor.commit();
3221         return true;
3222     }
3223 
3224     @Override
getLine1NumberForDisplay(int subId, String callingPackage)3225     public String getLine1NumberForDisplay(int subId, String callingPackage) {
3226         // This is open to apps with WRITE_SMS.
3227         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
3228                 mApp, subId, callingPackage, "getLine1NumberForDisplay")) {
3229             if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
3230             return null;
3231         }
3232 
3233         String iccId = getIccId(subId);
3234         if (iccId != null) {
3235             String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
3236             if (DBG_MERGE) {
3237                 log("getLine1NumberForDisplay returning " +
3238                         mTelephonySharedPreferences.getString(numberPrefKey, null));
3239             }
3240             return mTelephonySharedPreferences.getString(numberPrefKey, null);
3241         }
3242         if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
3243         return null;
3244     }
3245 
3246     @Override
getLine1AlphaTagForDisplay(int subId, String callingPackage)3247     public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
3248         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3249                 mApp, subId, callingPackage, "getLine1AlphaTagForDisplay")) {
3250             return null;
3251         }
3252 
3253         String iccId = getIccId(subId);
3254         if (iccId != null) {
3255             String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
3256             return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
3257         }
3258         return null;
3259     }
3260 
3261     @Override
getMergedSubscriberIds(String callingPackage)3262     public String[] getMergedSubscriberIds(String callingPackage) {
3263         // This API isn't public, so no need to provide a valid subscription ID - we're not worried
3264         // about carrier-privileged callers not having access.
3265         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3266                 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
3267                 "getMergedSubscriberIds")) {
3268             return null;
3269         }
3270         final Context context = mPhone.getContext();
3271         final TelephonyManager tele = TelephonyManager.from(context);
3272         final SubscriptionManager sub = SubscriptionManager.from(context);
3273 
3274         // Figure out what subscribers are currently active
3275         final ArraySet<String> activeSubscriberIds = new ArraySet<>();
3276         // Clear calling identity, when calling TelephonyManager, because callerUid must be
3277         // the process, where TelephonyManager was instantiated. Otherwise AppOps check will fail.
3278         final long identity  = Binder.clearCallingIdentity();
3279         try {
3280             final int[] subIds = sub.getActiveSubscriptionIdList();
3281             for (int subId : subIds) {
3282                 activeSubscriberIds.add(tele.getSubscriberId(subId));
3283             }
3284         } finally {
3285             Binder.restoreCallingIdentity(identity);
3286         }
3287 
3288         // First pass, find a number override for an active subscriber
3289         String mergeNumber = null;
3290         final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
3291         for (String key : prefs.keySet()) {
3292             if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
3293                 final String subscriberId = (String) prefs.get(key);
3294                 if (activeSubscriberIds.contains(subscriberId)) {
3295                     final String iccId = key.substring(PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
3296                     final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
3297                     mergeNumber = (String) prefs.get(numberKey);
3298                     if (DBG_MERGE) {
3299                         Slog.d(LOG_TAG, "Found line number " + mergeNumber
3300                                 + " for active subscriber " + subscriberId);
3301                     }
3302                     if (!TextUtils.isEmpty(mergeNumber)) {
3303                         break;
3304                     }
3305                 }
3306             }
3307         }
3308 
3309         // Shortcut when no active merged subscribers
3310         if (TextUtils.isEmpty(mergeNumber)) {
3311             return null;
3312         }
3313 
3314         // Second pass, find all subscribers under that line override
3315         final ArraySet<String> result = new ArraySet<>();
3316         for (String key : prefs.keySet()) {
3317             if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
3318                 final String number = (String) prefs.get(key);
3319                 if (mergeNumber.equals(number)) {
3320                     final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
3321                     final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
3322                     final String subscriberId = (String) prefs.get(subscriberKey);
3323                     if (!TextUtils.isEmpty(subscriberId)) {
3324                         result.add(subscriberId);
3325                     }
3326                 }
3327             }
3328         }
3329 
3330         final String[] resultArray = result.toArray(new String[result.size()]);
3331         Arrays.sort(resultArray);
3332         if (DBG_MERGE) {
3333             Slog.d(LOG_TAG, "Found subscribers " + Arrays.toString(resultArray) + " after merge");
3334         }
3335         return resultArray;
3336     }
3337 
3338     @Override
setOperatorBrandOverride(int subId, String brand)3339     public boolean setOperatorBrandOverride(int subId, String brand) {
3340         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
3341                 subId, "setOperatorBrandOverride");
3342         final Phone phone = getPhone(subId);
3343         return phone == null ? false : phone.setOperatorBrandOverride(brand);
3344     }
3345 
3346     @Override
setRoamingOverride(int subId, List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList)3347     public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
3348             List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
3349             List<String> cdmaNonRoamingList) {
3350         TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setRoamingOverride");
3351         final Phone phone = getPhone(subId);
3352         if (phone == null) {
3353             return false;
3354         }
3355         return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
3356                 cdmaNonRoamingList);
3357     }
3358 
3359     @Override
3360     @Deprecated
invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp)3361     public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
3362         enforceModifyPermission();
3363 
3364         int returnValue = 0;
3365         try {
3366             AsyncResult result = (AsyncResult)sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
3367             if(result.exception == null) {
3368                 if (result.result != null) {
3369                     byte[] responseData = (byte[])(result.result);
3370                     if(responseData.length > oemResp.length) {
3371                         Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
3372                                 responseData.length +  "bytes. Buffer Size is " +
3373                                 oemResp.length + "bytes.");
3374                     }
3375                     System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
3376                     returnValue = responseData.length;
3377                 }
3378             } else {
3379                 CommandException ex = (CommandException) result.exception;
3380                 returnValue = ex.getCommandError().ordinal();
3381                 if(returnValue > 0) returnValue *= -1;
3382             }
3383         } catch (RuntimeException e) {
3384             Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
3385             returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
3386             if(returnValue > 0) returnValue *= -1;
3387         }
3388 
3389         return returnValue;
3390     }
3391 
3392     @Override
setRadioCapability(RadioAccessFamily[] rafs)3393     public void setRadioCapability(RadioAccessFamily[] rafs) {
3394         try {
3395             ProxyController.getInstance().setRadioCapability(rafs);
3396         } catch (RuntimeException e) {
3397             Log.w(LOG_TAG, "setRadioCapability: Runtime Exception");
3398         }
3399     }
3400 
3401     @Override
getRadioAccessFamily(int phoneId, String callingPackage)3402     public int getRadioAccessFamily(int phoneId, String callingPackage) {
3403         Phone phone = PhoneFactory.getPhone(phoneId);
3404         if (phone == null) {
3405             return RadioAccessFamily.RAF_UNKNOWN;
3406         }
3407         int subId = phone.getSubId();
3408         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3409                 mApp, subId, callingPackage, "getRadioAccessFamily")) {
3410             return RadioAccessFamily.RAF_UNKNOWN;
3411         }
3412 
3413         return ProxyController.getInstance().getRadioAccessFamily(phoneId);
3414     }
3415 
3416     @Override
enableVideoCalling(boolean enable)3417     public void enableVideoCalling(boolean enable) {
3418         enforceModifyPermission();
3419         ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId()).setVtSetting(enable);
3420     }
3421 
3422     @Override
isVideoCallingEnabled(String callingPackage)3423     public boolean isVideoCallingEnabled(String callingPackage) {
3424         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3425                 mApp, mPhone.getSubId(), callingPackage, "isVideoCallingEnabled")) {
3426             return false;
3427         }
3428 
3429         // Check the user preference and the  system-level IMS setting. Even if the user has
3430         // enabled video calling, if IMS is disabled we aren't able to support video calling.
3431         // In the long run, we may instead need to check if there exists a connection service
3432         // which can support video calling.
3433         ImsManager imsManager = ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
3434         return imsManager.isVtEnabledByPlatform()
3435                 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
3436                 && imsManager.isVtEnabledByUser();
3437     }
3438 
3439     @Override
canChangeDtmfToneLength()3440     public boolean canChangeDtmfToneLength() {
3441         return mApp.getCarrierConfig().getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
3442     }
3443 
3444     @Override
isWorldPhone()3445     public boolean isWorldPhone() {
3446         return mApp.getCarrierConfig().getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
3447     }
3448 
3449     @Override
isTtyModeSupported()3450     public boolean isTtyModeSupported() {
3451         TelecomManager telecomManager = TelecomManager.from(mPhone.getContext());
3452         TelephonyManager telephonyManager =
3453                 (TelephonyManager) mPhone.getContext().getSystemService(Context.TELEPHONY_SERVICE);
3454         return telecomManager.isTtySupported();
3455     }
3456 
3457     @Override
isHearingAidCompatibilitySupported()3458     public boolean isHearingAidCompatibilitySupported() {
3459         return mPhone.getContext().getResources().getBoolean(R.bool.hac_enabled);
3460     }
3461 
isRttSupported()3462     public boolean isRttSupported() {
3463         boolean isCarrierSupported =
3464                 mApp.getCarrierConfig().getBoolean(CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
3465         boolean isDeviceSupported =
3466                 mPhone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
3467         return isCarrierSupported && isDeviceSupported;
3468     }
3469 
isRttEnabled()3470     public boolean isRttEnabled() {
3471         return isRttSupported() && Settings.Secure.getInt(mPhone.getContext().getContentResolver(),
3472                 Settings.Secure.RTT_CALLING_MODE, 0) != 0;
3473     }
3474 
3475     /**
3476      * Returns the unique device ID of phone, for example, the IMEI for
3477      * GSM and the MEID for CDMA phones. Return null if device ID is not available.
3478      *
3479      * <p>Requires Permission:
3480      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
3481      */
3482     @Override
getDeviceId(String callingPackage)3483     public String getDeviceId(String callingPackage) {
3484         final Phone phone = PhoneFactory.getPhone(0);
3485         if (phone == null) {
3486             return null;
3487         }
3488         int subId = phone.getSubId();
3489         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3490                 mApp, subId, callingPackage, "getDeviceId")) {
3491             return null;
3492         }
3493         return phone.getDeviceId();
3494     }
3495 
3496     /**
3497      * {@hide}
3498      * Returns the IMS Registration Status on a particular subid
3499      *
3500      * @param subId
3501      */
isImsRegistered(int subId)3502     public boolean isImsRegistered(int subId) {
3503         Phone phone = getPhone(subId);
3504         if (phone != null) {
3505             return phone.isImsRegistered();
3506         } else {
3507             return false;
3508         }
3509     }
3510 
3511     @Override
getSubIdForPhoneAccount(PhoneAccount phoneAccount)3512     public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
3513         return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
3514     }
3515 
3516     /**
3517      * @return the VoWiFi calling availability.
3518      */
isWifiCallingAvailable(int subId)3519     public boolean isWifiCallingAvailable(int subId) {
3520         Phone phone = getPhone(subId);
3521         if (phone != null) {
3522             return phone.isWifiCallingEnabled();
3523         } else {
3524             return false;
3525         }
3526     }
3527 
3528     /**
3529      * @return the VoLTE availability.
3530      */
isVolteAvailable(int subId)3531     public boolean isVolteAvailable(int subId) {
3532         Phone phone = getPhone(subId);
3533         if (phone != null) {
3534             return phone.isVolteEnabled();
3535         } else {
3536             return false;
3537         }
3538     }
3539 
3540     /**
3541      * @return the VT calling availability.
3542      */
isVideoTelephonyAvailable(int subId)3543     public boolean isVideoTelephonyAvailable(int subId) {
3544         Phone phone = getPhone(subId);
3545         if (phone != null) {
3546             return phone.isVideoEnabled();
3547         } else {
3548             return false;
3549         }
3550     }
3551 
3552     /**
3553      * @return the IMS registration technology for the MMTEL feature. Valid return values are
3554      * defined in {@link ImsRegistrationImplBase}.
3555      */
getImsRegTechnologyForMmTel(int subId)3556     public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
3557         Phone phone = getPhone(subId);
3558         if (phone != null) {
3559             return phone.getImsRegistrationTech();
3560         } else {
3561             return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
3562         }
3563     }
3564 
3565     @Override
factoryReset(int subId)3566     public void factoryReset(int subId) {
3567         enforceConnectivityInternalPermission();
3568         if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
3569             return;
3570         }
3571 
3572         final long identity = Binder.clearCallingIdentity();
3573         try {
3574             if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
3575                     UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
3576                 setUserDataEnabled(subId, getDefaultDataEnabled());
3577                 setNetworkSelectionModeAutomatic(subId);
3578                 setPreferredNetworkType(subId, getDefaultNetworkType(subId));
3579                 mPhone.setDataRoamingEnabled(getDefaultDataRoamingEnabled(subId));
3580                 CarrierInfoManager.deleteAllCarrierKeysForImsiEncryption(mPhone.getContext());
3581             }
3582         } finally {
3583             Binder.restoreCallingIdentity(identity);
3584         }
3585     }
3586 
3587     @Override
getLocaleFromDefaultSim()3588     public String getLocaleFromDefaultSim() {
3589         // We query all subscriptions instead of just the active ones, because
3590         // this might be called early on in the provisioning flow when the
3591         // subscriptions potentially aren't active yet.
3592         final List<SubscriptionInfo> slist = getAllSubscriptionInfoList();
3593         if (slist == null || slist.isEmpty()) {
3594             return null;
3595         }
3596 
3597         // This function may be called very early, say, from the setup wizard, at
3598         // which point we won't have a default subscription set. If that's the case
3599         // we just choose the first, which will be valid in "most cases".
3600         final int defaultSubId = getDefaultSubscription();
3601         SubscriptionInfo info = null;
3602         if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
3603             info = slist.get(0);
3604         } else {
3605             for (SubscriptionInfo item : slist) {
3606                 if (item.getSubscriptionId() == defaultSubId) {
3607                     info = item;
3608                     break;
3609                 }
3610             }
3611 
3612             if (info == null) {
3613                 return null;
3614             }
3615         }
3616 
3617         // Try and fetch the locale from the carrier properties or from the SIM language
3618         // preferences (EF-PL and EF-LI)...
3619         final int mcc = info.getMcc();
3620         final Phone defaultPhone = getPhone(info.getSubscriptionId());
3621         String simLanguage = null;
3622         if (defaultPhone != null) {
3623             final Locale localeFromDefaultSim = defaultPhone.getLocaleFromSimAndCarrierPrefs();
3624             if (localeFromDefaultSim != null) {
3625                 if (!localeFromDefaultSim.getCountry().isEmpty()) {
3626                     if (DBG) log("Using locale from default SIM:" + localeFromDefaultSim);
3627                     return localeFromDefaultSim.toLanguageTag();
3628                 } else {
3629                     simLanguage = localeFromDefaultSim.getLanguage();
3630                 }
3631             }
3632         }
3633 
3634         // The SIM language preferences only store a language (e.g. fr = French), not an
3635         // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
3636         // the SIM and carrier preferences does not include a country we add the country
3637         // determined from the SIM MCC to provide an exact locale.
3638         final Locale mccLocale = MccTable.getLocaleFromMcc(mPhone.getContext(), mcc, simLanguage);
3639         if (mccLocale != null) {
3640             if (DBG) log("No locale from default SIM, using mcc locale:" + mccLocale);
3641             return mccLocale.toLanguageTag();
3642         }
3643 
3644         if (DBG) log("No locale found - returning null");
3645         return null;
3646     }
3647 
getAllSubscriptionInfoList()3648     private List<SubscriptionInfo> getAllSubscriptionInfoList() {
3649         final long identity = Binder.clearCallingIdentity();
3650         try {
3651             return mSubscriptionController.getAllSubInfoList(
3652                     mPhone.getContext().getOpPackageName());
3653         } finally {
3654             Binder.restoreCallingIdentity(identity);
3655         }
3656     }
3657 
getActiveSubscriptionInfoList()3658     private List<SubscriptionInfo> getActiveSubscriptionInfoList() {
3659         final long identity = Binder.clearCallingIdentity();
3660         try {
3661             return mSubscriptionController.getActiveSubscriptionInfoList(
3662                     mPhone.getContext().getOpPackageName());
3663         } finally {
3664             Binder.restoreCallingIdentity(identity);
3665         }
3666     }
3667 
3668     private final ModemActivityInfo mLastModemActivityInfo =
3669             new ModemActivityInfo(0, 0, 0, new int[0], 0, 0);
3670 
3671     /**
3672      * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
3673      * representing the state of the modem.
3674      *
3675      * NOTE: The underlying implementation clears the modem state, so there should only ever be one
3676      * caller to it. Everyone should call this class to get cumulative data.
3677      * @hide
3678      */
3679     @Override
requestModemActivityInfo(ResultReceiver result)3680     public void requestModemActivityInfo(ResultReceiver result) {
3681         enforceModifyPermission();
3682         ModemActivityInfo ret = null;
3683         synchronized (mLastModemActivityInfo) {
3684             ModemActivityInfo info = (ModemActivityInfo) sendRequest(CMD_GET_MODEM_ACTIVITY_INFO,
3685                     null);
3686             if (info != null) {
3687                 int[] mergedTxTimeMs = new int[ModemActivityInfo.TX_POWER_LEVELS];
3688                 for (int i = 0; i < mergedTxTimeMs.length; i++) {
3689                     mergedTxTimeMs[i] =
3690                             info.getTxTimeMillis()[i] + mLastModemActivityInfo.getTxTimeMillis()[i];
3691                 }
3692                 mLastModemActivityInfo.setTimestamp(info.getTimestamp());
3693                 mLastModemActivityInfo.setSleepTimeMillis(
3694                         info.getSleepTimeMillis() + mLastModemActivityInfo.getSleepTimeMillis());
3695                 mLastModemActivityInfo.setIdleTimeMillis(
3696                         info.getIdleTimeMillis() + mLastModemActivityInfo.getIdleTimeMillis());
3697                 mLastModemActivityInfo.setTxTimeMillis(mergedTxTimeMs);
3698                 mLastModemActivityInfo.setRxTimeMillis(
3699                         info.getRxTimeMillis() + mLastModemActivityInfo.getRxTimeMillis());
3700                 mLastModemActivityInfo.setEnergyUsed(
3701                         info.getEnergyUsed() + mLastModemActivityInfo.getEnergyUsed());
3702             }
3703             ret = new ModemActivityInfo(mLastModemActivityInfo.getTimestamp(),
3704                     mLastModemActivityInfo.getSleepTimeMillis(),
3705                     mLastModemActivityInfo.getIdleTimeMillis(),
3706                     mLastModemActivityInfo.getTxTimeMillis(),
3707                     mLastModemActivityInfo.getRxTimeMillis(),
3708                     mLastModemActivityInfo.getEnergyUsed());
3709         }
3710         Bundle bundle = new Bundle();
3711         bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, ret);
3712         result.send(0, bundle);
3713     }
3714 
3715     /**
3716      * {@hide}
3717      * Returns the service state information on specified subscription.
3718      */
3719     @Override
getServiceStateForSubscriber(int subId, String callingPackage)3720     public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) {
3721 
3722         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
3723                 mApp, subId, callingPackage, "getServiceStateForSubscriber")) {
3724             return null;
3725         }
3726 
3727         final Phone phone = getPhone(subId);
3728         if (phone == null) {
3729             return null;
3730         }
3731 
3732         return phone.getServiceState();
3733     }
3734 
3735     /**
3736      * Returns the URI for the per-account voicemail ringtone set in Phone settings.
3737      *
3738      * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
3739      * voicemail ringtone.
3740      * @return The URI for the ringtone to play when receiving a voicemail from a specific
3741      * PhoneAccount.
3742      */
3743     @Override
getVoicemailRingtoneUri(PhoneAccountHandle accountHandle)3744     public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
3745         Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
3746         if (phone == null) {
3747             phone = mPhone;
3748         }
3749 
3750         return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
3751     }
3752 
3753     /**
3754      * Sets the per-account voicemail ringtone.
3755      *
3756      * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
3757      * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
3758      *
3759      * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
3760      * voicemail ringtone.
3761      * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
3762      * PhoneAccount.
3763      */
3764     @Override
setVoicemailRingtoneUri(String callingPackage, PhoneAccountHandle phoneAccountHandle, Uri uri)3765     public void setVoicemailRingtoneUri(String callingPackage,
3766             PhoneAccountHandle phoneAccountHandle, Uri uri) {
3767         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3768         if (!TextUtils.equals(callingPackage,
3769                 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
3770             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3771                     mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
3772                     "setVoicemailRingtoneUri");
3773         }
3774         Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
3775         if (phone == null){
3776            phone = mPhone;
3777         }
3778         VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
3779     }
3780 
3781     /**
3782      * Returns whether vibration is set for voicemail notification in Phone settings.
3783      *
3784      * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
3785      * voicemail vibration setting.
3786      * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
3787      */
3788     @Override
isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle)3789     public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
3790         Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
3791         if (phone == null) {
3792             phone = mPhone;
3793         }
3794 
3795         return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
3796     }
3797 
3798     /**
3799      * Sets the per-account voicemail vibration.
3800      *
3801      * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
3802      * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
3803      *
3804      * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
3805      * voicemail vibration setting.
3806      * @param enabled Whether to enable or disable vibration for voicemail notifications from a
3807      * specific PhoneAccount.
3808      */
3809     @Override
setVoicemailVibrationEnabled(String callingPackage, PhoneAccountHandle phoneAccountHandle, boolean enabled)3810     public void setVoicemailVibrationEnabled(String callingPackage,
3811             PhoneAccountHandle phoneAccountHandle, boolean enabled) {
3812         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
3813         if (!TextUtils.equals(callingPackage,
3814                 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
3815             TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3816                     mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
3817                     "setVoicemailVibrationEnabled");
3818         }
3819 
3820         Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
3821         if (phone == null){
3822             phone = mPhone;
3823         }
3824         VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
3825     }
3826 
3827     /**
3828      * Make sure either called from same process as self (phone) or IPC caller has read privilege.
3829      *
3830      * @throws SecurityException if the caller does not have the required permission
3831      */
enforceReadPrivilegedPermission()3832     private void enforceReadPrivilegedPermission() {
3833         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
3834                 null);
3835     }
3836 
3837     /**
3838      * Make sure either called from same process as self (phone) or IPC caller has send SMS
3839      * permission.
3840      *
3841      * @throws SecurityException if the caller does not have the required permission
3842      */
enforceSendSmsPermission()3843     private void enforceSendSmsPermission() {
3844         mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
3845     }
3846 
3847     /**
3848      * Make sure called from the package in charge of visual voicemail.
3849      *
3850      * @throws SecurityException if the caller is not the visual voicemail package.
3851      */
enforceVisualVoicemailPackage(String callingPackage, int subId)3852     private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
3853         ComponentName componentName =
3854                 RemoteVvmTaskManager.getRemotePackage(mPhone.getContext(), subId);
3855         if(componentName == null) {
3856             throw new SecurityException("Caller not current active visual voicemail package[null]");
3857         }
3858         String vvmPackage = componentName.getPackageName();
3859         if (!callingPackage.equals(vvmPackage)) {
3860             throw new SecurityException("Caller not current active visual voicemail package[" +
3861                     vvmPackage + "]");
3862         }
3863     }
3864 
3865     /**
3866      * Return the application ID for the app type.
3867      *
3868      * @param subId the subscription ID that this request applies to.
3869      * @param appType the uicc app type.
3870      * @return Application ID for specificied app type, or null if no uicc.
3871      */
3872     @Override
getAidForAppType(int subId, int appType)3873     public String getAidForAppType(int subId, int appType) {
3874         enforceReadPrivilegedPermission();
3875         Phone phone = getPhone(subId);
3876         if (phone == null) {
3877             return null;
3878         }
3879         String aid = null;
3880         try {
3881             aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
3882                     .getApplicationByType(appType).getAid();
3883         } catch (Exception e) {
3884             Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
3885         }
3886         return aid;
3887     }
3888 
3889     /**
3890      * Return the Electronic Serial Number.
3891      *
3892      * @param subId the subscription ID that this request applies to.
3893      * @return ESN or null if error.
3894      */
3895     @Override
getEsn(int subId)3896     public String getEsn(int subId) {
3897         enforceReadPrivilegedPermission();
3898         Phone phone = getPhone(subId);
3899         if (phone == null) {
3900             return null;
3901         }
3902         String esn = null;
3903         try {
3904             esn = phone.getEsn();
3905         } catch (Exception e) {
3906             Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
3907         }
3908         return esn;
3909     }
3910 
3911     /**
3912      * Return the Preferred Roaming List Version.
3913      *
3914      * @param subId the subscription ID that this request applies to.
3915      * @return PRLVersion or null if error.
3916      */
3917     @Override
getCdmaPrlVersion(int subId)3918     public String getCdmaPrlVersion(int subId) {
3919         enforceReadPrivilegedPermission();
3920         Phone phone = getPhone(subId);
3921         if (phone == null) {
3922             return null;
3923         }
3924         String cdmaPrlVersion = null;
3925         try {
3926             cdmaPrlVersion = phone.getCdmaPrlVersion();
3927         } catch (Exception e) {
3928             Log.e(LOG_TAG, "Not getting PRLVersion", e);
3929         }
3930         return cdmaPrlVersion;
3931     }
3932 
3933     /**
3934      * Get snapshot of Telephony histograms
3935      * @return List of Telephony histograms
3936      * @hide
3937      */
3938     @Override
getTelephonyHistograms()3939     public List<TelephonyHistogram> getTelephonyHistograms() {
3940         TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3941                 mApp, getDefaultSubscription(), "getTelephonyHistograms");
3942         return RIL.getTelephonyRILTimingHistograms();
3943     }
3944 
3945     /**
3946      * {@hide}
3947      * Set the allowed carrier list for slotIndex
3948      * Require system privileges. In the future we may add this to carrier APIs.
3949      *
3950      * @return The number of carriers set successfully, should match length of carriers
3951      */
3952     @Override
setAllowedCarriers(int slotIndex, List<CarrierIdentifier> carriers)3953     public int setAllowedCarriers(int slotIndex, List<CarrierIdentifier> carriers) {
3954         enforceModifyPermission();
3955 
3956         if (carriers == null) {
3957             throw new NullPointerException("carriers cannot be null");
3958         }
3959 
3960         int subId = SubscriptionManager.getSubId(slotIndex)[0];
3961         int[] retVal = (int[]) sendRequest(CMD_SET_ALLOWED_CARRIERS, carriers, subId);
3962         return retVal[0];
3963     }
3964 
3965     /**
3966      * {@hide}
3967      * Get the allowed carrier list for slotIndex.
3968      * Require system privileges. In the future we may add this to carrier APIs.
3969      *
3970      * @return List of {@link android.service.telephony.CarrierIdentifier}; empty list
3971      * means all carriers are allowed.
3972      */
3973     @Override
getAllowedCarriers(int slotIndex)3974     public List<CarrierIdentifier> getAllowedCarriers(int slotIndex) {
3975         enforceReadPrivilegedPermission();
3976         int subId = SubscriptionManager.getSubId(slotIndex)[0];
3977         return (List<CarrierIdentifier>) sendRequest(CMD_GET_ALLOWED_CARRIERS, null, subId);
3978     }
3979 
3980     /**
3981      * Action set from carrier signalling broadcast receivers to enable/disable metered apns
3982      * @param subId the subscription ID that this action applies to.
3983      * @param enabled control enable or disable metered apns.
3984      * {@hide}
3985      */
3986     @Override
carrierActionSetMeteredApnsEnabled(int subId, boolean enabled)3987     public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
3988         enforceModifyPermission();
3989         final Phone phone = getPhone(subId);
3990         if (phone == null) {
3991             loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId);
3992             return;
3993         }
3994         try {
3995             phone.carrierActionSetMeteredApnsEnabled(enabled);
3996         } catch (Exception e) {
3997             Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e);
3998         }
3999     }
4000 
4001     /**
4002      * Action set from carrier signalling broadcast receivers to enable/disable radio
4003      * @param subId the subscription ID that this action applies to.
4004      * @param enabled control enable or disable radio.
4005      * {@hide}
4006      */
4007     @Override
carrierActionSetRadioEnabled(int subId, boolean enabled)4008     public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
4009         enforceModifyPermission();
4010         final Phone phone = getPhone(subId);
4011         if (phone == null) {
4012             loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
4013             return;
4014         }
4015         try {
4016             phone.carrierActionSetRadioEnabled(enabled);
4017         } catch (Exception e) {
4018             Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
4019         }
4020     }
4021 
4022     /**
4023      * Action set from carrier signalling broadcast receivers to start/stop reporting the default
4024      * network status based on which carrier apps could apply actions accordingly,
4025      * enable/disable default url handler for example.
4026      *
4027      * @param subId the subscription ID that this action applies to.
4028      * @param report control start/stop reporting the default network status.
4029      * {@hide}
4030      */
4031     @Override
carrierActionReportDefaultNetworkStatus(int subId, boolean report)4032     public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
4033         enforceModifyPermission();
4034         final Phone phone = getPhone(subId);
4035         if (phone == null) {
4036             loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
4037             return;
4038         }
4039         try {
4040             phone.carrierActionReportDefaultNetworkStatus(report);
4041         } catch (Exception e) {
4042             Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
4043         }
4044     }
4045 
4046     /**
4047      * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
4048      * bug report is being generated.
4049      */
4050     @Override
dump(FileDescriptor fd, PrintWriter writer, String[] args)4051     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
4052         if (mPhone.getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
4053                 != PackageManager.PERMISSION_GRANTED) {
4054             writer.println("Permission Denial: can't dump Phone from pid="
4055                     + Binder.getCallingPid()
4056                     + ", uid=" + Binder.getCallingUid()
4057                     + "without permission "
4058                     + android.Manifest.permission.DUMP);
4059             return;
4060         }
4061         DumpsysHandler.dump(mPhone.getContext(), fd, writer, args);
4062     }
4063 
4064     @Override
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)4065     public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
4066             String[] args, ShellCallback callback, ResultReceiver resultReceiver)
4067             throws RemoteException {
4068         (new TelephonyShellCommand(this)).exec(this, in, out, err, args, callback, resultReceiver);
4069     }
4070 
4071     /**
4072      * Get aggregated video call data usage since boot.
4073      *
4074      * @param perUidStats True if requesting data usage per uid, otherwise overall usage.
4075      * @return Snapshot of video call data usage
4076      * {@hide}
4077      */
4078     @Override
getVtDataUsage(int subId, boolean perUidStats)4079     public NetworkStats getVtDataUsage(int subId, boolean perUidStats) {
4080         mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_NETWORK_USAGE_HISTORY,
4081                 null);
4082 
4083         // NetworkStatsService keeps tracking the active network interface and identity. It
4084         // records the delta with the corresponding network identity. We just return the total video
4085         // call data usage snapshot since boot.
4086         Phone phone = getPhone(subId);
4087         if (phone != null) {
4088             return phone.getVtDataUsage(perUidStats);
4089         }
4090         return null;
4091     }
4092 
4093     /**
4094      * Policy control of data connection. Usually used when data limit is passed.
4095      * @param enabled True if enabling the data, otherwise disabling.
4096      * @param subId Subscription index
4097      * {@hide}
4098      */
4099     @Override
setPolicyDataEnabled(boolean enabled, int subId)4100     public void setPolicyDataEnabled(boolean enabled, int subId) {
4101         enforceModifyPermission();
4102         Phone phone = getPhone(subId);
4103         if (phone != null) {
4104             phone.setPolicyDataEnabled(enabled);
4105         }
4106     }
4107 
4108     /**
4109      * Get Client request stats
4110      * @return List of Client Request Stats
4111      * @hide
4112      */
4113     @Override
getClientRequestStats(String callingPackage, int subId)4114     public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
4115         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4116                 mApp, subId, callingPackage, "getClientRequestStats")) {
4117             return null;
4118         }
4119 
4120         Phone phone = getPhone(subId);
4121         if (phone != null) {
4122             return phone.getClientRequestStats();
4123         }
4124 
4125         return null;
4126     }
4127 
getWorkSource(int uid)4128     private WorkSource getWorkSource(int uid) {
4129         String packageName = mPhone.getContext().getPackageManager().getNameForUid(uid);
4130         return new WorkSource(uid, packageName);
4131     }
4132 
4133     /**
4134      * Set SIM card power state.
4135      *
4136      * @param slotIndex SIM slot id.
4137      * @param state  State of SIM (power down, power up, pass through)
4138      * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
4139      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
4140      * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
4141      *
4142      **/
4143     @Override
setSimPowerStateForSlot(int slotIndex, int state)4144     public void setSimPowerStateForSlot(int slotIndex, int state) {
4145         enforceModifyPermission();
4146         Phone phone = PhoneFactory.getPhone(slotIndex);
4147 
4148         if (phone != null) {
4149             phone.setSimPowerState(state);
4150         }
4151     }
4152 
isUssdApiAllowed(int subId)4153     private boolean isUssdApiAllowed(int subId) {
4154         CarrierConfigManager configManager =
4155                 (CarrierConfigManager) mPhone.getContext().getSystemService(
4156                         Context.CARRIER_CONFIG_SERVICE);
4157         if (configManager == null) {
4158             return false;
4159         }
4160         PersistableBundle pb = configManager.getConfigForSubId(subId);
4161         if (pb == null) {
4162             return false;
4163         }
4164         return pb.getBoolean(
4165                 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
4166     }
4167 
4168     /**
4169      * Check if phone is in emergency callback mode
4170      * @return true if phone is in emergency callback mode
4171      * @param subId sub id
4172      */
4173     @Override
getEmergencyCallbackMode(int subId)4174     public boolean getEmergencyCallbackMode(int subId) {
4175         enforceReadPrivilegedPermission();
4176         final Phone phone = getPhone(subId);
4177         if (phone != null) {
4178             return phone.isInEcm();
4179         } else {
4180             return false;
4181         }
4182     }
4183 
4184     /**
4185      * Get the current signal strength information for the given subscription.
4186      * Because this information is not updated when the device is in a low power state
4187      * it should not be relied-upon to be current.
4188      * @param subId Subscription index
4189      * @return the most recent cached signal strength info from the modem
4190      */
4191     @Override
getSignalStrength(int subId)4192     public SignalStrength getSignalStrength(int subId) {
4193         Phone p = getPhone(subId);
4194         if (p == null) {
4195             return null;
4196         }
4197 
4198         return p.getSignalStrength();
4199     }
4200 
4201     @Override
getUiccSlotsInfo()4202     public UiccSlotInfo[] getUiccSlotsInfo() {
4203         enforceReadPrivilegedPermission();
4204 
4205         UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
4206         if (slots == null) {
4207             Rlog.i(LOG_TAG, "slots is null.");
4208             return null;
4209         }
4210 
4211         UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
4212         for (int i = 0; i < slots.length; i++) {
4213             UiccSlot slot = slots[i];
4214             if (slot == null) {
4215                 continue;
4216             }
4217 
4218             String cardId;
4219             UiccCard card = slot.getUiccCard();
4220             if (card != null) {
4221                 cardId = card.getCardId();
4222             } else {
4223                 cardId = slot.getIccId();
4224             }
4225 
4226             int cardState = 0;
4227             switch (slot.getCardState()) {
4228                 case CARDSTATE_ABSENT:
4229                     cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
4230                     break;
4231                 case CARDSTATE_PRESENT:
4232                     cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
4233                     break;
4234                 case CARDSTATE_ERROR:
4235                     cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
4236                     break;
4237                 case CARDSTATE_RESTRICTED:
4238                     cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
4239                     break;
4240                 default:
4241                     break;
4242 
4243             }
4244 
4245             infos[i] = new UiccSlotInfo(
4246                     slot.isActive(),
4247                     slot.isEuicc(),
4248                     cardId,
4249                     cardState,
4250                     slot.getPhoneId(),
4251                     slot.isExtendedApduSupported());
4252         }
4253         return infos;
4254     }
4255 
4256     @Override
switchSlots(int[] physicalSlots)4257     public boolean switchSlots(int[] physicalSlots) {
4258         enforceModifyPermission();
4259         return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
4260     }
4261 
4262     @Override
setRadioIndicationUpdateMode(int subId, int filters, int mode)4263     public void setRadioIndicationUpdateMode(int subId, int filters, int mode) {
4264         enforceModifyPermission();
4265         final Phone phone = getPhone(subId);
4266         if (phone == null) {
4267             loge("setRadioIndicationUpdateMode fails with invalid subId: " + subId);
4268             return;
4269         }
4270 
4271         phone.setRadioIndicationUpdateMode(filters, mode);
4272     }
4273 
4274     /**
4275      * A test API to reload the UICC profile.
4276      *
4277      * <p>Requires that the calling app has permission
4278      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
4279      * @hide
4280      */
4281     @Override
refreshUiccProfile(int subId)4282     public void refreshUiccProfile(int subId) {
4283         enforceModifyPermission();
4284 
4285         final long identity = Binder.clearCallingIdentity();
4286         try {
4287             Phone phone = getPhone(subId);
4288             if (phone == null) {
4289                 return;
4290             }
4291             UiccCard uiccCard = phone.getUiccCard();
4292             if (uiccCard == null) {
4293                 return;
4294             }
4295             UiccProfile uiccProfile = uiccCard.getUiccProfile();
4296             if (uiccProfile == null) {
4297                 return;
4298             }
4299             uiccProfile.refresh();
4300         } finally {
4301             Binder.restoreCallingIdentity(identity);
4302         }
4303     }
4304 
4305     /**
4306      * Returns false if the mobile data is disabled by default, otherwise return true.
4307      */
getDefaultDataEnabled()4308     private boolean getDefaultDataEnabled() {
4309         return "true".equalsIgnoreCase(
4310                 SystemProperties.get(DEFAULT_MOBILE_DATA_PROPERTY_NAME, "true"));
4311     }
4312 
4313     /**
4314      * Returns true if the data roaming is enabled by default, i.e the system property
4315      * of {@link #DEFAULT_DATA_ROAMING_PROPERTY_NAME} is true or the config of
4316      * {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL} is true.
4317      */
getDefaultDataRoamingEnabled(int subId)4318     private boolean getDefaultDataRoamingEnabled(int subId) {
4319         final CarrierConfigManager configMgr = (CarrierConfigManager)
4320                 mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
4321         boolean isDataRoamingEnabled = "true".equalsIgnoreCase(
4322                 SystemProperties.get(DEFAULT_DATA_ROAMING_PROPERTY_NAME, "false"));
4323         isDataRoamingEnabled |= configMgr.getConfigForSubId(subId).getBoolean(
4324                 CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
4325         return isDataRoamingEnabled;
4326     }
4327 
4328     /**
4329      * Returns the default network type for the given {@code subId}, if the default network type is
4330      * not set, return {@link Phone#PREFERRED_NT_MODE}.
4331      */
getDefaultNetworkType(int subId)4332     private int getDefaultNetworkType(int subId) {
4333         return Integer.parseInt(
4334                 TelephonyManager.getTelephonyProperty(
4335                         mSubscriptionController.getPhoneId(subId),
4336                         DEFAULT_NETWORK_MODE_PROPERTY_NAME,
4337                         String.valueOf(Phone.PREFERRED_NT_MODE)));
4338     }
4339 
4340     @Override
setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String gid1, String gid2, String plmn, String spn)4341     public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
4342             gid1, String gid2, String plmn, String spn) {
4343         enforceModifyPermission();
4344         final Phone phone = getPhone(subId);
4345         if (phone == null) {
4346             loge("setCarrierTestOverride fails with invalid subId: " + subId);
4347             return;
4348         }
4349         phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn);
4350     }
4351 
4352     @Override
getCarrierIdListVersion(int subId)4353     public int getCarrierIdListVersion(int subId) {
4354         enforceReadPrivilegedPermission();
4355         final Phone phone = getPhone(subId);
4356         if (phone == null) {
4357             loge("getCarrierIdListVersion fails with invalid subId: " + subId);
4358             return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
4359         }
4360         return phone.getCarrierIdListVersion();
4361     }
4362 }
4363