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