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