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