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