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