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