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 final Phone defaultPhone = PhoneFactory.getDefaultPhone(); 1406 if (defaultPhone != null) { 1407 defaultPhone.setRadioPower(turnOn); 1408 return true; 1409 } else { 1410 loge("There's no default phone."); 1411 return false; 1412 } 1413 } 1414 setRadioPowerForSubscriber(int subId, boolean turnOn)1415 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) { 1416 enforceModifyPermission(); 1417 final Phone phone = getPhone(subId); 1418 if (phone != null) { 1419 phone.setRadioPower(turnOn); 1420 return true; 1421 } else { 1422 return false; 1423 } 1424 } 1425 1426 // FIXME: subId version needed 1427 @Override enableDataConnectivity()1428 public boolean enableDataConnectivity() { 1429 enforceModifyPermission(); 1430 int subId = mSubscriptionController.getDefaultDataSubId(); 1431 final Phone phone = getPhone(subId); 1432 if (phone != null) { 1433 phone.setDataEnabled(true); 1434 return true; 1435 } else { 1436 return false; 1437 } 1438 } 1439 1440 // FIXME: subId version needed 1441 @Override disableDataConnectivity()1442 public boolean disableDataConnectivity() { 1443 enforceModifyPermission(); 1444 int subId = mSubscriptionController.getDefaultDataSubId(); 1445 final Phone phone = getPhone(subId); 1446 if (phone != null) { 1447 phone.setDataEnabled(false); 1448 return true; 1449 } else { 1450 return false; 1451 } 1452 } 1453 1454 // FIXME: subId version needed 1455 @Override isDataConnectivityPossible()1456 public boolean isDataConnectivityPossible() { 1457 int subId = mSubscriptionController.getDefaultDataSubId(); 1458 final Phone phone = getPhone(subId); 1459 if (phone != null) { 1460 return phone.isDataConnectivityPossible(); 1461 } else { 1462 return false; 1463 } 1464 } 1465 handlePinMmi(String dialString)1466 public boolean handlePinMmi(String dialString) { 1467 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString); 1468 } 1469 handlePinMmiForSubscriber(int subId, String dialString)1470 public boolean handlePinMmiForSubscriber(int subId, String dialString) { 1471 enforceModifyPermission(); 1472 if (!SubscriptionManager.isValidSubscriptionId(subId)) { 1473 return false; 1474 } 1475 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId); 1476 } 1477 getCallState()1478 public int getCallState() { 1479 return getCallStateForSlot(getSlotForDefaultSubscription()); 1480 } 1481 getCallStateForSlot(int slotId)1482 public int getCallStateForSlot(int slotId) { 1483 Phone phone = PhoneFactory.getPhone(slotId); 1484 return phone == null ? TelephonyManager.CALL_STATE_IDLE : 1485 DefaultPhoneNotifier.convertCallState(phone.getState()); 1486 } 1487 1488 @Override getDataState()1489 public int getDataState() { 1490 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId()); 1491 if (phone != null) { 1492 return DefaultPhoneNotifier.convertDataState(phone.getDataConnectionState()); 1493 } else { 1494 return DefaultPhoneNotifier.convertDataState(PhoneConstants.DataState.DISCONNECTED); 1495 } 1496 } 1497 1498 @Override getDataActivity()1499 public int getDataActivity() { 1500 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId()); 1501 if (phone != null) { 1502 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState()); 1503 } else { 1504 return TelephonyManager.DATA_ACTIVITY_NONE; 1505 } 1506 } 1507 1508 @Override getCellLocation(String callingPackage)1509 public Bundle getCellLocation(String callingPackage) { 1510 enforceFineOrCoarseLocationPermission("getCellLocation"); 1511 1512 // OP_COARSE_LOCATION controls both fine and coarse location. 1513 if (mAppOps.noteOp(AppOpsManager.OP_COARSE_LOCATION, Binder.getCallingUid(), 1514 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1515 log("getCellLocation: returning null; mode != allowed"); 1516 return null; 1517 } 1518 1519 if (checkIfCallerIsSelfOrForegroundUser() || 1520 checkCallerInteractAcrossUsersFull()) { 1521 if (DBG_LOC) log("getCellLocation: is active user"); 1522 Bundle data = new Bundle(); 1523 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId()); 1524 if (phone == null) { 1525 return null; 1526 } 1527 phone.getCellLocation().fillInNotifierBundle(data); 1528 return data; 1529 } else { 1530 log("getCellLocation: suppress non-active user"); 1531 return null; 1532 } 1533 } 1534 enforceFineOrCoarseLocationPermission(String message)1535 private void enforceFineOrCoarseLocationPermission(String message) { 1536 try { 1537 mApp.enforceCallingOrSelfPermission( 1538 android.Manifest.permission.ACCESS_FINE_LOCATION, null); 1539 } catch (SecurityException e) { 1540 // If we have ACCESS_FINE_LOCATION permission, skip the check for ACCESS_COARSE_LOCATION 1541 // A failure should throw the SecurityException from ACCESS_COARSE_LOCATION since this 1542 // is the weaker precondition 1543 mApp.enforceCallingOrSelfPermission( 1544 android.Manifest.permission.ACCESS_COARSE_LOCATION, message); 1545 } 1546 } 1547 1548 1549 @Override enableLocationUpdates()1550 public void enableLocationUpdates() { 1551 enableLocationUpdatesForSubscriber(getDefaultSubscription()); 1552 } 1553 1554 @Override enableLocationUpdatesForSubscriber(int subId)1555 public void enableLocationUpdatesForSubscriber(int subId) { 1556 mApp.enforceCallingOrSelfPermission( 1557 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 1558 final Phone phone = getPhone(subId); 1559 if (phone != null) { 1560 phone.enableLocationUpdates(); 1561 } 1562 } 1563 1564 @Override disableLocationUpdates()1565 public void disableLocationUpdates() { 1566 disableLocationUpdatesForSubscriber(getDefaultSubscription()); 1567 } 1568 1569 @Override disableLocationUpdatesForSubscriber(int subId)1570 public void disableLocationUpdatesForSubscriber(int subId) { 1571 mApp.enforceCallingOrSelfPermission( 1572 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 1573 final Phone phone = getPhone(subId); 1574 if (phone != null) { 1575 phone.disableLocationUpdates(); 1576 } 1577 } 1578 1579 @Override 1580 @SuppressWarnings("unchecked") getNeighboringCellInfo(String callingPackage)1581 public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) { 1582 enforceFineOrCoarseLocationPermission("getNeighboringCellInfo"); 1583 1584 // OP_COARSE_LOCATION controls both fine and coarse location. 1585 if (mAppOps.noteOp(AppOpsManager.OP_COARSE_LOCATION, Binder.getCallingUid(), 1586 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1587 return null; 1588 } 1589 1590 if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(), 1591 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1592 return null; 1593 } 1594 1595 if (checkIfCallerIsSelfOrForegroundUser() || 1596 checkCallerInteractAcrossUsersFull()) { 1597 if (DBG_LOC) log("getNeighboringCellInfo: is active user"); 1598 1599 ArrayList<NeighboringCellInfo> cells = null; 1600 1601 try { 1602 cells = (ArrayList<NeighboringCellInfo>) sendRequest( 1603 CMD_HANDLE_NEIGHBORING_CELL, null, 1604 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 1605 } catch (RuntimeException e) { 1606 Log.e(LOG_TAG, "getNeighboringCellInfo " + e); 1607 } 1608 return cells; 1609 } else { 1610 if (DBG_LOC) log("getNeighboringCellInfo: suppress non-active user"); 1611 return null; 1612 } 1613 } 1614 1615 1616 @Override getAllCellInfo(String callingPackage)1617 public List<CellInfo> getAllCellInfo(String callingPackage) { 1618 enforceFineOrCoarseLocationPermission("getAllCellInfo"); 1619 1620 // OP_COARSE_LOCATION controls both fine and coarse location. 1621 if (mAppOps.noteOp(AppOpsManager.OP_COARSE_LOCATION, Binder.getCallingUid(), 1622 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1623 return null; 1624 } 1625 1626 if (checkIfCallerIsSelfOrForegroundUser() || 1627 checkCallerInteractAcrossUsersFull()) { 1628 if (DBG_LOC) log("getAllCellInfo: is active user"); 1629 List<CellInfo> cellInfos = new ArrayList<CellInfo>(); 1630 for (Phone phone : PhoneFactory.getPhones()) { 1631 final List<CellInfo> info = phone.getAllCellInfo(); 1632 if (info != null) cellInfos.addAll(phone.getAllCellInfo()); 1633 } 1634 return cellInfos; 1635 } else { 1636 if (DBG_LOC) log("getAllCellInfo: suppress non-active user"); 1637 return null; 1638 } 1639 } 1640 1641 @Override setCellInfoListRate(int rateInMillis)1642 public void setCellInfoListRate(int rateInMillis) { 1643 enforceModifyPermission(); 1644 mPhone.setCellInfoListRate(rateInMillis); 1645 } 1646 1647 @Override getImeiForSlot(int slotId, String callingPackage)1648 public String getImeiForSlot(int slotId, String callingPackage) { 1649 if (!canReadPhoneState(callingPackage, "getImeiForSlot")) { 1650 return null; 1651 } 1652 Phone phone = PhoneFactory.getPhone(slotId); 1653 return phone == null ? null : phone.getImei(); 1654 } 1655 1656 @Override getDeviceSoftwareVersionForSlot(int slotId, String callingPackage)1657 public String getDeviceSoftwareVersionForSlot(int slotId, String callingPackage) { 1658 if (!canReadPhoneState(callingPackage, "getDeviceSoftwareVersionForSlot")) { 1659 return null; 1660 } 1661 Phone phone = PhoneFactory.getPhone(slotId); 1662 return phone == null ? null : phone.getDeviceSvn(); 1663 } 1664 1665 // 1666 // Internal helper methods. 1667 // 1668 1669 /** 1670 * Returns true if the caller holds INTERACT_ACROSS_USERS_FULL. 1671 */ checkCallerInteractAcrossUsersFull()1672 private boolean checkCallerInteractAcrossUsersFull() { 1673 return mPhone.getContext().checkCallingOrSelfPermission( 1674 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 1675 == PackageManager.PERMISSION_GRANTED; 1676 } 1677 checkIfCallerIsSelfOrForegroundUser()1678 private static boolean checkIfCallerIsSelfOrForegroundUser() { 1679 boolean ok; 1680 1681 boolean self = Binder.getCallingUid() == Process.myUid(); 1682 if (!self) { 1683 // Get the caller's user id then clear the calling identity 1684 // which will be restored in the finally clause. 1685 int callingUser = UserHandle.getCallingUserId(); 1686 long ident = Binder.clearCallingIdentity(); 1687 1688 try { 1689 // With calling identity cleared the current user is the foreground user. 1690 int foregroundUser = ActivityManager.getCurrentUser(); 1691 ok = (foregroundUser == callingUser); 1692 if (DBG_LOC) { 1693 log("checkIfCallerIsSelfOrForegoundUser: foregroundUser=" + foregroundUser 1694 + " callingUser=" + callingUser + " ok=" + ok); 1695 } 1696 } catch (Exception ex) { 1697 if (DBG_LOC) loge("checkIfCallerIsSelfOrForegoundUser: Exception ex=" + ex); 1698 ok = false; 1699 } finally { 1700 Binder.restoreCallingIdentity(ident); 1701 } 1702 } else { 1703 if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: is self"); 1704 ok = true; 1705 } 1706 if (DBG_LOC) log("checkIfCallerIsSelfOrForegoundUser: ret=" + ok); 1707 return ok; 1708 } 1709 1710 /** 1711 * Make sure the caller has the MODIFY_PHONE_STATE permission. 1712 * 1713 * @throws SecurityException if the caller does not have the required permission 1714 */ enforceModifyPermission()1715 private void enforceModifyPermission() { 1716 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null); 1717 } 1718 1719 /** 1720 * Make sure either system app or the caller has carrier privilege. 1721 * 1722 * @throws SecurityException if the caller does not have the required permission/privilege 1723 */ enforceModifyPermissionOrCarrierPrivilege(int subId)1724 private void enforceModifyPermissionOrCarrierPrivilege(int subId) { 1725 int permission = mApp.checkCallingOrSelfPermission( 1726 android.Manifest.permission.MODIFY_PHONE_STATE); 1727 if (permission == PackageManager.PERMISSION_GRANTED) { 1728 return; 1729 } 1730 1731 log("No modify permission, check carrier privilege next."); 1732 enforceCarrierPrivilege(subId); 1733 } 1734 1735 /** 1736 * Make sure the caller has carrier privilege. 1737 * 1738 * @throws SecurityException if the caller does not have the required permission 1739 */ enforceCarrierPrivilege(int subId)1740 private void enforceCarrierPrivilege(int subId) { 1741 if (getCarrierPrivilegeStatus(subId) != 1742 TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 1743 loge("No Carrier Privilege."); 1744 throw new SecurityException("No Carrier Privilege."); 1745 } 1746 } 1747 1748 /** 1749 * Make sure the caller has the CALL_PHONE permission. 1750 * 1751 * @throws SecurityException if the caller does not have the required permission 1752 */ enforceCallPermission()1753 private void enforceCallPermission() { 1754 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null); 1755 } 1756 enforceConnectivityInternalPermission()1757 private void enforceConnectivityInternalPermission() { 1758 mApp.enforceCallingOrSelfPermission( 1759 android.Manifest.permission.CONNECTIVITY_INTERNAL, 1760 "ConnectivityService"); 1761 } 1762 createTelUrl(String number)1763 private String createTelUrl(String number) { 1764 if (TextUtils.isEmpty(number)) { 1765 return null; 1766 } 1767 1768 return "tel:" + number; 1769 } 1770 log(String msg)1771 private static void log(String msg) { 1772 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg); 1773 } 1774 logv(String msg)1775 private static void logv(String msg) { 1776 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg); 1777 } 1778 loge(String msg)1779 private static void loge(String msg) { 1780 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg); 1781 } 1782 1783 @Override getActivePhoneType()1784 public int getActivePhoneType() { 1785 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription()); 1786 } 1787 1788 @Override getActivePhoneTypeForSlot(int slotId)1789 public int getActivePhoneTypeForSlot(int slotId) { 1790 final Phone phone = PhoneFactory.getPhone(slotId); 1791 if (phone == null) { 1792 return PhoneConstants.PHONE_TYPE_NONE; 1793 } else { 1794 return phone.getPhoneType(); 1795 } 1796 } 1797 1798 /** 1799 * Returns the CDMA ERI icon index to display 1800 */ 1801 @Override getCdmaEriIconIndex(String callingPackage)1802 public int getCdmaEriIconIndex(String callingPackage) { 1803 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage); 1804 } 1805 1806 @Override getCdmaEriIconIndexForSubscriber(int subId, String callingPackage)1807 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) { 1808 if (!canReadPhoneState(callingPackage, "getCdmaEriIconIndexForSubscriber")) { 1809 return -1; 1810 } 1811 final Phone phone = getPhone(subId); 1812 if (phone != null) { 1813 return phone.getCdmaEriIconIndex(); 1814 } else { 1815 return -1; 1816 } 1817 } 1818 1819 /** 1820 * Returns the CDMA ERI icon mode, 1821 * 0 - ON 1822 * 1 - FLASHING 1823 */ 1824 @Override getCdmaEriIconMode(String callingPackage)1825 public int getCdmaEriIconMode(String callingPackage) { 1826 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage); 1827 } 1828 1829 @Override getCdmaEriIconModeForSubscriber(int subId, String callingPackage)1830 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) { 1831 if (!canReadPhoneState(callingPackage, "getCdmaEriIconModeForSubscriber")) { 1832 return -1; 1833 } 1834 final Phone phone = getPhone(subId); 1835 if (phone != null) { 1836 return phone.getCdmaEriIconMode(); 1837 } else { 1838 return -1; 1839 } 1840 } 1841 1842 /** 1843 * Returns the CDMA ERI text, 1844 */ 1845 @Override getCdmaEriText(String callingPackage)1846 public String getCdmaEriText(String callingPackage) { 1847 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage); 1848 } 1849 1850 @Override getCdmaEriTextForSubscriber(int subId, String callingPackage)1851 public String getCdmaEriTextForSubscriber(int subId, String callingPackage) { 1852 if (!canReadPhoneState(callingPackage, "getCdmaEriIconTextForSubscriber")) { 1853 return null; 1854 } 1855 final Phone phone = getPhone(subId); 1856 if (phone != null) { 1857 return phone.getCdmaEriText(); 1858 } else { 1859 return null; 1860 } 1861 } 1862 1863 /** 1864 * Returns the CDMA MDN. 1865 */ 1866 @Override getCdmaMdn(int subId)1867 public String getCdmaMdn(int subId) { 1868 enforceModifyPermissionOrCarrierPrivilege(subId); 1869 final Phone phone = getPhone(subId); 1870 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA && phone != null) { 1871 return phone.getLine1Number(); 1872 } else { 1873 return null; 1874 } 1875 } 1876 1877 /** 1878 * Returns the CDMA MIN. 1879 */ 1880 @Override getCdmaMin(int subId)1881 public String getCdmaMin(int subId) { 1882 enforceModifyPermissionOrCarrierPrivilege(subId); 1883 final Phone phone = getPhone(subId); 1884 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 1885 return phone.getCdmaMin(); 1886 } else { 1887 return null; 1888 } 1889 } 1890 1891 /** 1892 * Returns true if CDMA provisioning needs to run. 1893 */ needsOtaServiceProvisioning()1894 public boolean needsOtaServiceProvisioning() { 1895 return mPhone.needsOtaServiceProvisioning(); 1896 } 1897 1898 /** 1899 * Sets the voice mail number of a given subId. 1900 */ 1901 @Override setVoiceMailNumber(int subId, String alphaTag, String number)1902 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) { 1903 enforceCarrierPrivilege(subId); 1904 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER, 1905 new Pair<String, String>(alphaTag, number), new Integer(subId)); 1906 return success; 1907 } 1908 1909 @Override setVisualVoicemailEnabled(String callingPackage, PhoneAccountHandle phoneAccountHandle, boolean enabled)1910 public void setVisualVoicemailEnabled(String callingPackage, 1911 PhoneAccountHandle phoneAccountHandle, boolean enabled) { 1912 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 1913 if (!TextUtils.equals(callingPackage, 1914 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) { 1915 enforceModifyPermissionOrCarrierPrivilege( 1916 PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle)); 1917 } 1918 VisualVoicemailSettingsUtil.setEnabled(mPhone.getContext(), phoneAccountHandle, enabled); 1919 } 1920 1921 @Override isVisualVoicemailEnabled(String callingPackage, PhoneAccountHandle phoneAccountHandle)1922 public boolean isVisualVoicemailEnabled(String callingPackage, 1923 PhoneAccountHandle phoneAccountHandle) { 1924 if (!canReadPhoneState(callingPackage, "isVisualVoicemailEnabled")) { 1925 return false; 1926 } 1927 return VisualVoicemailSettingsUtil.isEnabled(mPhone.getContext(), phoneAccountHandle); 1928 } 1929 1930 @Override enableVisualVoicemailSmsFilter(String callingPackage, int subId, VisualVoicemailSmsFilterSettings settings)1931 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId, 1932 VisualVoicemailSmsFilterSettings settings) { 1933 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 1934 VisualVoicemailSmsFilterConfig 1935 .enableVisualVoicemailSmsFilter(mPhone.getContext(), callingPackage, subId, 1936 settings); 1937 } 1938 1939 @Override disableVisualVoicemailSmsFilter(String callingPackage, int subId)1940 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) { 1941 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 1942 VisualVoicemailSmsFilterConfig 1943 .disableVisualVoicemailSmsFilter(mPhone.getContext(), callingPackage, subId); 1944 } 1945 1946 @Override getVisualVoicemailSmsFilterSettings( String callingPackage, int subId)1947 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings( 1948 String callingPackage, int subId) { 1949 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 1950 return VisualVoicemailSmsFilterConfig 1951 .getVisualVoicemailSmsFilterSettings(mPhone.getContext(), callingPackage, subId); 1952 } 1953 1954 @Override getSystemVisualVoicemailSmsFilterSettings( String packageName, int subId)1955 public VisualVoicemailSmsFilterSettings getSystemVisualVoicemailSmsFilterSettings( 1956 String packageName, int subId) { 1957 enforceReadPrivilegedPermission(); 1958 return VisualVoicemailSmsFilterConfig 1959 .getVisualVoicemailSmsFilterSettings(mPhone.getContext(), packageName, subId); 1960 } 1961 /** 1962 * Returns the unread count of voicemails 1963 */ getVoiceMessageCount()1964 public int getVoiceMessageCount() { 1965 return getVoiceMessageCountForSubscriber(getDefaultSubscription()); 1966 } 1967 1968 /** 1969 * Returns the unread count of voicemails for a subId 1970 */ 1971 @Override getVoiceMessageCountForSubscriber( int subId)1972 public int getVoiceMessageCountForSubscriber( int subId) { 1973 final Phone phone = getPhone(subId); 1974 if (phone != null) { 1975 return phone.getVoiceMessageCount(); 1976 } else { 1977 return 0; 1978 } 1979 } 1980 1981 /** 1982 * Returns the data network type. 1983 * Legacy call, permission-free. 1984 * 1985 * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}. 1986 */ 1987 @Override getNetworkType()1988 public int getNetworkType() { 1989 final Phone phone = getPhone(getDefaultSubscription()); 1990 if (phone != null) { 1991 return phone.getServiceState().getDataNetworkType(); 1992 } else { 1993 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 1994 } 1995 } 1996 1997 /** 1998 * Returns the network type for a subId 1999 */ 2000 @Override getNetworkTypeForSubscriber(int subId, String callingPackage)2001 public int getNetworkTypeForSubscriber(int subId, String callingPackage) { 2002 if (!canReadPhoneState(callingPackage, "getNetworkTypeForSubscriber")) { 2003 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 2004 } 2005 2006 final Phone phone = getPhone(subId); 2007 if (phone != null) { 2008 return phone.getServiceState().getDataNetworkType(); 2009 } else { 2010 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 2011 } 2012 } 2013 2014 /** 2015 * Returns the data network type 2016 */ 2017 @Override getDataNetworkType(String callingPackage)2018 public int getDataNetworkType(String callingPackage) { 2019 return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage); 2020 } 2021 2022 /** 2023 * Returns the data network type for a subId 2024 */ 2025 @Override getDataNetworkTypeForSubscriber(int subId, String callingPackage)2026 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) { 2027 if (!canReadPhoneState(callingPackage, "getDataNetworkTypeForSubscriber")) { 2028 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 2029 } 2030 2031 final Phone phone = getPhone(subId); 2032 if (phone != null) { 2033 return phone.getServiceState().getDataNetworkType(); 2034 } else { 2035 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 2036 } 2037 } 2038 2039 /** 2040 * Returns the Voice network type for a subId 2041 */ 2042 @Override getVoiceNetworkTypeForSubscriber(int subId, String callingPackage)2043 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) { 2044 if (!canReadPhoneState(callingPackage, "getDataNetworkTypeForSubscriber")) { 2045 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 2046 } 2047 2048 final Phone phone = getPhone(subId); 2049 if (phone != null) { 2050 return phone.getServiceState().getVoiceNetworkType(); 2051 } else { 2052 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 2053 } 2054 } 2055 2056 /** 2057 * @return true if a ICC card is present 2058 */ hasIccCard()2059 public boolean hasIccCard() { 2060 // FIXME Make changes to pass defaultSimId of type int 2061 return hasIccCardUsingSlotId(mSubscriptionController.getSlotId(getDefaultSubscription())); 2062 } 2063 2064 /** 2065 * @return true if a ICC card is present for a slotId 2066 */ 2067 @Override hasIccCardUsingSlotId(int slotId)2068 public boolean hasIccCardUsingSlotId(int slotId) { 2069 int subId[] = mSubscriptionController.getSubIdUsingSlotId(slotId); 2070 final Phone phone = getPhone(subId[0]); 2071 if (subId != null && phone != null) { 2072 return phone.getIccCard().hasIccCard(); 2073 } else { 2074 return false; 2075 } 2076 } 2077 2078 /** 2079 * Return if the current radio is LTE on CDMA. This 2080 * is a tri-state return value as for a period of time 2081 * the mode may be unknown. 2082 * 2083 * @param callingPackage the name of the package making the call. 2084 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE} 2085 * or {@link Phone#LTE_ON_CDMA_TRUE} 2086 */ 2087 @Override getLteOnCdmaMode(String callingPackage)2088 public int getLteOnCdmaMode(String callingPackage) { 2089 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage); 2090 } 2091 2092 @Override getLteOnCdmaModeForSubscriber(int subId, String callingPackage)2093 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) { 2094 if (!canReadPhoneState(callingPackage, "getLteOnCdmaModeForSubscriber")) { 2095 return PhoneConstants.LTE_ON_CDMA_UNKNOWN; 2096 } 2097 2098 final Phone phone = getPhone(subId); 2099 if (phone == null) { 2100 return PhoneConstants.LTE_ON_CDMA_UNKNOWN; 2101 } else { 2102 return phone.getLteOnCdmaMode(); 2103 } 2104 } 2105 setPhone(Phone phone)2106 public void setPhone(Phone phone) { 2107 mPhone = phone; 2108 } 2109 2110 /** 2111 * {@hide} 2112 * Returns Default subId, 0 in the case of single standby. 2113 */ getDefaultSubscription()2114 private int getDefaultSubscription() { 2115 return mSubscriptionController.getDefaultSubId(); 2116 } 2117 getSlotForDefaultSubscription()2118 private int getSlotForDefaultSubscription() { 2119 return mSubscriptionController.getPhoneId(getDefaultSubscription()); 2120 } 2121 getPreferredVoiceSubscription()2122 private int getPreferredVoiceSubscription() { 2123 return mSubscriptionController.getDefaultVoiceSubId(); 2124 } 2125 2126 /** 2127 * @see android.telephony.TelephonyManager.WifiCallingChoices 2128 */ getWhenToMakeWifiCalls()2129 public int getWhenToMakeWifiCalls() { 2130 return Settings.System.getInt(mPhone.getContext().getContentResolver(), 2131 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, getWhenToMakeWifiCallsDefaultPreference()); 2132 } 2133 2134 /** 2135 * @see android.telephony.TelephonyManager.WifiCallingChoices 2136 */ setWhenToMakeWifiCalls(int preference)2137 public void setWhenToMakeWifiCalls(int preference) { 2138 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference); 2139 Settings.System.putInt(mPhone.getContext().getContentResolver(), 2140 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference); 2141 } 2142 getWhenToMakeWifiCallsDefaultPreference()2143 private static int getWhenToMakeWifiCallsDefaultPreference() { 2144 // TODO: Use a build property to choose this value. 2145 return TelephonyManager.WifiCallingChoices.ALWAYS_USE; 2146 } 2147 2148 @Override iccOpenLogicalChannel(int subId, String AID)2149 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(int subId, String AID) { 2150 enforceModifyPermissionOrCarrierPrivilege(subId); 2151 2152 if (DBG) log("iccOpenLogicalChannel: subId=" + subId + " aid=" + AID); 2153 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse)sendRequest( 2154 CMD_OPEN_CHANNEL, AID, subId); 2155 if (DBG) log("iccOpenLogicalChannel: " + response); 2156 return response; 2157 } 2158 2159 @Override iccCloseLogicalChannel(int subId, int channel)2160 public boolean iccCloseLogicalChannel(int subId, int channel) { 2161 enforceModifyPermissionOrCarrierPrivilege(subId); 2162 2163 if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel); 2164 if (channel < 0) { 2165 return false; 2166 } 2167 Boolean success = (Boolean)sendRequest(CMD_CLOSE_CHANNEL, channel, subId); 2168 if (DBG) log("iccCloseLogicalChannel: " + success); 2169 return success; 2170 } 2171 2172 @Override iccTransmitApduLogicalChannel(int subId, int channel, int cla, int command, int p1, int p2, int p3, String data)2173 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla, 2174 int command, int p1, int p2, int p3, String data) { 2175 enforceModifyPermissionOrCarrierPrivilege(subId); 2176 2177 if (DBG) { 2178 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel + 2179 " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + 2180 " data=" + data); 2181 } 2182 2183 if (channel < 0) { 2184 return ""; 2185 } 2186 2187 IccIoResult response = (IccIoResult)sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL, 2188 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), subId); 2189 if (DBG) log("iccTransmitApduLogicalChannel: " + response); 2190 2191 // Append the returned status code to the end of the response payload. 2192 String s = Integer.toHexString( 2193 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 2194 if (response.payload != null) { 2195 s = IccUtils.bytesToHexString(response.payload) + s; 2196 } 2197 return s; 2198 } 2199 2200 @Override iccTransmitApduBasicChannel(int subId, int cla, int command, int p1, int p2, int p3, String data)2201 public String iccTransmitApduBasicChannel(int subId, int cla, int command, int p1, int p2, 2202 int p3, String data) { 2203 enforceModifyPermissionOrCarrierPrivilege(subId); 2204 2205 if (DBG) { 2206 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd=" + command 2207 + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data); 2208 } 2209 2210 IccIoResult response = (IccIoResult)sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL, 2211 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), subId); 2212 if (DBG) log("iccTransmitApduBasicChannel: " + response); 2213 2214 // Append the returned status code to the end of the response payload. 2215 String s = Integer.toHexString( 2216 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 2217 if (response.payload != null) { 2218 s = IccUtils.bytesToHexString(response.payload) + s; 2219 } 2220 return s; 2221 } 2222 2223 @Override iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3, String filePath)2224 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3, 2225 String filePath) { 2226 enforceModifyPermissionOrCarrierPrivilege(subId); 2227 2228 if (DBG) { 2229 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " " + 2230 p1 + " " + p2 + " " + p3 + ":" + filePath); 2231 } 2232 2233 IccIoResult response = 2234 (IccIoResult)sendRequest(CMD_EXCHANGE_SIM_IO, 2235 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath), 2236 subId); 2237 2238 if (DBG) { 2239 log("Exchange SIM_IO [R]" + response); 2240 } 2241 2242 byte[] result = null; 2243 int length = 2; 2244 if (response.payload != null) { 2245 length = 2 + response.payload.length; 2246 result = new byte[length]; 2247 System.arraycopy(response.payload, 0, result, 0, response.payload.length); 2248 } else { 2249 result = new byte[length]; 2250 } 2251 2252 result[length - 1] = (byte) response.sw2; 2253 result[length - 2] = (byte) response.sw1; 2254 return result; 2255 } 2256 2257 @Override sendEnvelopeWithStatus(int subId, String content)2258 public String sendEnvelopeWithStatus(int subId, String content) { 2259 enforceModifyPermissionOrCarrierPrivilege(subId); 2260 2261 IccIoResult response = (IccIoResult)sendRequest(CMD_SEND_ENVELOPE, content, subId); 2262 if (response.payload == null) { 2263 return ""; 2264 } 2265 2266 // Append the returned status code to the end of the response payload. 2267 String s = Integer.toHexString( 2268 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 2269 s = IccUtils.bytesToHexString(response.payload) + s; 2270 return s; 2271 } 2272 2273 /** 2274 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems} 2275 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators. 2276 * 2277 * @param itemID the ID of the item to read 2278 * @return the NV item as a String, or null on error. 2279 */ 2280 @Override nvReadItem(int itemID)2281 public String nvReadItem(int itemID) { 2282 enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription()); 2283 if (DBG) log("nvReadItem: item " + itemID); 2284 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID); 2285 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"'); 2286 return value; 2287 } 2288 2289 /** 2290 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems} 2291 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators. 2292 * 2293 * @param itemID the ID of the item to read 2294 * @param itemValue the value to write, as a String 2295 * @return true on success; false on any failure 2296 */ 2297 @Override nvWriteItem(int itemID, String itemValue)2298 public boolean nvWriteItem(int itemID, String itemValue) { 2299 enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription()); 2300 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"'); 2301 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM, 2302 new Pair<Integer, String>(itemID, itemValue)); 2303 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail")); 2304 return success; 2305 } 2306 2307 /** 2308 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. 2309 * Used for device configuration by some CDMA operators. 2310 * 2311 * @param preferredRoamingList byte array containing the new PRL 2312 * @return true on success; false on any failure 2313 */ 2314 @Override nvWriteCdmaPrl(byte[] preferredRoamingList)2315 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) { 2316 enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription()); 2317 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList)); 2318 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList); 2319 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail")); 2320 return success; 2321 } 2322 2323 /** 2324 * Perform the specified type of NV config reset. 2325 * Used for device configuration by some CDMA operators. 2326 * 2327 * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset) 2328 * @return true on success; false on any failure 2329 */ 2330 @Override nvResetConfig(int resetType)2331 public boolean nvResetConfig(int resetType) { 2332 enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription()); 2333 if (DBG) log("nvResetConfig: type " + resetType); 2334 Boolean success = (Boolean) sendRequest(CMD_NV_RESET_CONFIG, resetType); 2335 if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail")); 2336 return success; 2337 } 2338 2339 /** 2340 * {@hide} 2341 * Returns Default sim, 0 in the case of single standby. 2342 */ getDefaultSim()2343 public int getDefaultSim() { 2344 //TODO Need to get it from Telephony Devcontroller 2345 return 0; 2346 } 2347 getPcscfAddress(String apnType, String callingPackage)2348 public String[] getPcscfAddress(String apnType, String callingPackage) { 2349 if (!canReadPhoneState(callingPackage, "getPcscfAddress")) { 2350 return new String[0]; 2351 } 2352 2353 2354 return mPhone.getPcscfAddress(apnType); 2355 } 2356 setImsRegistrationState(boolean registered)2357 public void setImsRegistrationState(boolean registered) { 2358 enforceModifyPermission(); 2359 mPhone.setImsRegistrationState(registered); 2360 } 2361 2362 /** 2363 * Set the network selection mode to automatic. 2364 * 2365 */ 2366 @Override setNetworkSelectionModeAutomatic(int subId)2367 public void setNetworkSelectionModeAutomatic(int subId) { 2368 enforceModifyPermissionOrCarrierPrivilege(subId); 2369 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId); 2370 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId); 2371 } 2372 2373 /** 2374 * Set the network selection mode to manual with the selected carrier. 2375 */ 2376 @Override setNetworkSelectionModeManual(int subId, OperatorInfo operator, boolean persistSelection)2377 public boolean setNetworkSelectionModeManual(int subId, OperatorInfo operator, 2378 boolean persistSelection) { 2379 enforceModifyPermissionOrCarrierPrivilege(subId); 2380 if (DBG) log("setNetworkSelectionModeManual: subId:" + subId + " operator:" + operator); 2381 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operator, 2382 persistSelection); 2383 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId); 2384 } 2385 2386 /** 2387 * Scans for available networks. 2388 */ 2389 @Override getCellNetworkScanResults(int subId)2390 public CellNetworkScanResult getCellNetworkScanResults(int subId) { 2391 enforceModifyPermissionOrCarrierPrivilege(subId); 2392 if (DBG) log("getCellNetworkScanResults: subId " + subId); 2393 CellNetworkScanResult result = (CellNetworkScanResult) sendRequest( 2394 CMD_PERFORM_NETWORK_SCAN, null, subId); 2395 return result; 2396 } 2397 2398 /** 2399 * Get the calculated preferred network type. 2400 * Used for debugging incorrect network type. 2401 * 2402 * @return the preferred network type, defined in RILConstants.java. 2403 */ 2404 @Override getCalculatedPreferredNetworkType(String callingPackage)2405 public int getCalculatedPreferredNetworkType(String callingPackage) { 2406 if (!canReadPhoneState(callingPackage, "getCalculatedPreferredNetworkType")) { 2407 return RILConstants.PREFERRED_NETWORK_MODE; 2408 } 2409 2410 return PhoneFactory.calculatePreferredNetworkType(mPhone.getContext(), 0); // wink FIXME: need to get SubId from somewhere. 2411 } 2412 2413 /** 2414 * Get the preferred network type. 2415 * Used for device configuration by some CDMA operators. 2416 * 2417 * @return the preferred network type, defined in RILConstants.java. 2418 */ 2419 @Override getPreferredNetworkType(int subId)2420 public int getPreferredNetworkType(int subId) { 2421 enforceModifyPermissionOrCarrierPrivilege(subId); 2422 if (DBG) log("getPreferredNetworkType"); 2423 int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId); 2424 int networkType = (result != null ? result[0] : -1); 2425 if (DBG) log("getPreferredNetworkType: " + networkType); 2426 return networkType; 2427 } 2428 2429 /** 2430 * Set the preferred network type. 2431 * Used for device configuration by some CDMA operators. 2432 * 2433 * @param networkType the preferred network type, defined in RILConstants.java. 2434 * @return true on success; false on any failure. 2435 */ 2436 @Override setPreferredNetworkType(int subId, int networkType)2437 public boolean setPreferredNetworkType(int subId, int networkType) { 2438 enforceModifyPermissionOrCarrierPrivilege(subId); 2439 if (DBG) log("setPreferredNetworkType: subId " + subId + " type " + networkType); 2440 Boolean success = (Boolean) sendRequest(CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId); 2441 if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail")); 2442 if (success) { 2443 Settings.Global.putInt(mPhone.getContext().getContentResolver(), 2444 Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType); 2445 } 2446 return success; 2447 } 2448 2449 /** 2450 * Check TETHER_DUN_REQUIRED and TETHER_DUN_APN settings, net.tethering.noprovisioning 2451 * SystemProperty, and config_tether_apndata to decide whether DUN APN is required for 2452 * tethering. 2453 * 2454 * @return 0: Not required. 1: required. 2: Not set. 2455 * @hide 2456 */ 2457 @Override getTetherApnRequired()2458 public int getTetherApnRequired() { 2459 enforceModifyPermission(); 2460 int dunRequired = Settings.Global.getInt(mPhone.getContext().getContentResolver(), 2461 Settings.Global.TETHER_DUN_REQUIRED, 2); 2462 // If not set, check net.tethering.noprovisioning, TETHER_DUN_APN setting and 2463 // config_tether_apndata. 2464 if (dunRequired == 2 && mPhone.hasMatchedTetherApnSetting()) { 2465 dunRequired = 1; 2466 } 2467 return dunRequired; 2468 } 2469 2470 /** 2471 * Set mobile data enabled 2472 * Used by the user through settings etc to turn on/off mobile data 2473 * 2474 * @param enable {@code true} turn turn data on, else {@code false} 2475 */ 2476 @Override setDataEnabled(int subId, boolean enable)2477 public void setDataEnabled(int subId, boolean enable) { 2478 enforceModifyPermission(); 2479 int phoneId = mSubscriptionController.getPhoneId(subId); 2480 if (DBG) log("getDataEnabled: subId=" + subId + " phoneId=" + phoneId); 2481 Phone phone = PhoneFactory.getPhone(phoneId); 2482 if (phone != null) { 2483 if (DBG) log("setDataEnabled: subId=" + subId + " enable=" + enable); 2484 phone.setDataEnabled(enable); 2485 } else { 2486 loge("setDataEnabled: no phone for subId=" + subId); 2487 } 2488 } 2489 2490 /** 2491 * Get whether mobile data is enabled. 2492 * 2493 * Note that this used to be available from ConnectivityService, gated by 2494 * ACCESS_NETWORK_STATE permission, so this will accept either that or 2495 * our MODIFY_PHONE_STATE. 2496 * 2497 * @return {@code true} if data is enabled else {@code false} 2498 */ 2499 @Override getDataEnabled(int subId)2500 public boolean getDataEnabled(int subId) { 2501 try { 2502 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE, 2503 null); 2504 } catch (Exception e) { 2505 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, 2506 null); 2507 } 2508 int phoneId = mSubscriptionController.getPhoneId(subId); 2509 if (DBG) log("getDataEnabled: subId=" + subId + " phoneId=" + phoneId); 2510 Phone phone = PhoneFactory.getPhone(phoneId); 2511 if (phone != null) { 2512 boolean retVal = phone.getDataEnabled(); 2513 if (DBG) log("getDataEnabled: subId=" + subId + " retVal=" + retVal); 2514 return retVal; 2515 } else { 2516 if (DBG) loge("getDataEnabled: no phone subId=" + subId + " retVal=false"); 2517 return false; 2518 } 2519 } 2520 2521 @Override getCarrierPrivilegeStatus(int subId)2522 public int getCarrierPrivilegeStatus(int subId) { 2523 final Phone phone = getPhone(subId); 2524 if (phone == null) { 2525 loge("getCarrierPrivilegeStatus: Invalid subId"); 2526 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 2527 } 2528 UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId()); 2529 if (card == null) { 2530 loge("getCarrierPrivilegeStatus: No UICC"); 2531 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 2532 } 2533 return card.getCarrierPrivilegeStatusForCurrentTransaction( 2534 phone.getContext().getPackageManager()); 2535 } 2536 2537 @Override checkCarrierPrivilegesForPackage(String pkgName)2538 public int checkCarrierPrivilegesForPackage(String pkgName) { 2539 if (TextUtils.isEmpty(pkgName)) 2540 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 2541 UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId()); 2542 if (card == null) { 2543 loge("checkCarrierPrivilegesForPackage: No UICC"); 2544 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 2545 } 2546 return card.getCarrierPrivilegeStatus(mPhone.getContext().getPackageManager(), pkgName); 2547 } 2548 2549 @Override checkCarrierPrivilegesForPackageAnyPhone(String pkgName)2550 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) { 2551 if (TextUtils.isEmpty(pkgName)) 2552 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 2553 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 2554 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 2555 UiccCard card = UiccController.getInstance().getUiccCard(i); 2556 if (card == null) { 2557 // No UICC in that slot. 2558 continue; 2559 } 2560 2561 result = card.getCarrierPrivilegeStatus( 2562 mPhone.getContext().getPackageManager(), pkgName); 2563 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 2564 break; 2565 } 2566 } 2567 2568 return result; 2569 } 2570 2571 @Override getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId)2572 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) { 2573 if (!SubscriptionManager.isValidPhoneId(phoneId)) { 2574 loge("phoneId " + phoneId + " is not valid."); 2575 return null; 2576 } 2577 UiccCard card = UiccController.getInstance().getUiccCard(phoneId); 2578 if (card == null) { 2579 loge("getCarrierPackageNamesForIntent: No UICC"); 2580 return null ; 2581 } 2582 return card.getCarrierPackageNamesForIntent( 2583 mPhone.getContext().getPackageManager(), intent); 2584 } 2585 2586 @Override getPackagesWithCarrierPrivileges()2587 public List<String> getPackagesWithCarrierPrivileges() { 2588 PackageManager pm = mPhone.getContext().getPackageManager(); 2589 List<String> privilegedPackages = new ArrayList<>(); 2590 List<PackageInfo> packages = null; 2591 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 2592 UiccCard card = UiccController.getInstance().getUiccCard(i); 2593 if (card == null) { 2594 // No UICC in that slot. 2595 continue; 2596 } 2597 if (card.hasCarrierPrivilegeRules()) { 2598 if (packages == null) { 2599 // Only check packages in user 0 for now 2600 packages = pm.getInstalledPackagesAsUser( 2601 PackageManager.MATCH_DISABLED_COMPONENTS 2602 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS 2603 | PackageManager.GET_SIGNATURES, UserHandle.USER_SYSTEM); 2604 } 2605 for (int p = packages.size() - 1; p >= 0; p--) { 2606 PackageInfo pkgInfo = packages.get(p); 2607 if (pkgInfo != null && pkgInfo.packageName != null 2608 && card.getCarrierPrivilegeStatus(pkgInfo) 2609 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 2610 privilegedPackages.add(pkgInfo.packageName); 2611 } 2612 } 2613 } 2614 } 2615 return privilegedPackages; 2616 } 2617 getIccId(int subId)2618 private String getIccId(int subId) { 2619 final Phone phone = getPhone(subId); 2620 UiccCard card = phone == null ? null : phone.getUiccCard(); 2621 if (card == null) { 2622 loge("getIccId: No UICC"); 2623 return null; 2624 } 2625 String iccId = card.getIccId(); 2626 if (TextUtils.isEmpty(iccId)) { 2627 loge("getIccId: ICC ID is null or empty."); 2628 return null; 2629 } 2630 return iccId; 2631 } 2632 2633 @Override setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, String number)2634 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, 2635 String number) { 2636 enforceCarrierPrivilege(subId); 2637 2638 final String iccId = getIccId(subId); 2639 final Phone phone = getPhone(subId); 2640 if (phone == null) { 2641 return false; 2642 } 2643 final String subscriberId = phone.getSubscriberId(); 2644 2645 if (DBG_MERGE) { 2646 Slog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId=" 2647 + subscriberId + " to " + number); 2648 } 2649 2650 if (TextUtils.isEmpty(iccId)) { 2651 return false; 2652 } 2653 2654 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit(); 2655 2656 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId; 2657 if (alphaTag == null) { 2658 editor.remove(alphaTagPrefKey); 2659 } else { 2660 editor.putString(alphaTagPrefKey, alphaTag); 2661 } 2662 2663 // Record both the line number and IMSI for this ICCID, since we need to 2664 // track all merged IMSIs based on line number 2665 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId; 2666 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId; 2667 if (number == null) { 2668 editor.remove(numberPrefKey); 2669 editor.remove(subscriberPrefKey); 2670 } else { 2671 editor.putString(numberPrefKey, number); 2672 editor.putString(subscriberPrefKey, subscriberId); 2673 } 2674 2675 editor.commit(); 2676 return true; 2677 } 2678 2679 @Override getLine1NumberForDisplay(int subId, String callingPackage)2680 public String getLine1NumberForDisplay(int subId, String callingPackage) { 2681 // This is open to apps with WRITE_SMS. 2682 if (!canReadPhoneNumber(callingPackage, "getLine1NumberForDisplay")) { 2683 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission"); 2684 return null; 2685 } 2686 2687 String iccId = getIccId(subId); 2688 if (iccId != null) { 2689 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId; 2690 if (DBG_MERGE) { 2691 log("getLine1NumberForDisplay returning " + 2692 mTelephonySharedPreferences.getString(numberPrefKey, null)); 2693 } 2694 return mTelephonySharedPreferences.getString(numberPrefKey, null); 2695 } 2696 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null"); 2697 return null; 2698 } 2699 2700 @Override getLine1AlphaTagForDisplay(int subId, String callingPackage)2701 public String getLine1AlphaTagForDisplay(int subId, String callingPackage) { 2702 if (!canReadPhoneState(callingPackage, "getLine1AlphaTagForDisplay")) { 2703 return null; 2704 } 2705 2706 String iccId = getIccId(subId); 2707 if (iccId != null) { 2708 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId; 2709 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null); 2710 } 2711 return null; 2712 } 2713 2714 @Override getMergedSubscriberIds(String callingPackage)2715 public String[] getMergedSubscriberIds(String callingPackage) { 2716 if (!canReadPhoneState(callingPackage, "getMergedSubscriberIds")) { 2717 return null; 2718 } 2719 final Context context = mPhone.getContext(); 2720 final TelephonyManager tele = TelephonyManager.from(context); 2721 final SubscriptionManager sub = SubscriptionManager.from(context); 2722 2723 // Figure out what subscribers are currently active 2724 final ArraySet<String> activeSubscriberIds = new ArraySet<>(); 2725 // Clear calling identity, when calling TelephonyManager, because callerUid must be 2726 // the process, where TelephonyManager was instantiated. Otherwise AppOps check will fail. 2727 final long identity = Binder.clearCallingIdentity(); 2728 try { 2729 final int[] subIds = sub.getActiveSubscriptionIdList(); 2730 for (int subId : subIds) { 2731 activeSubscriberIds.add(tele.getSubscriberId(subId)); 2732 } 2733 } finally { 2734 Binder.restoreCallingIdentity(identity); 2735 } 2736 2737 // First pass, find a number override for an active subscriber 2738 String mergeNumber = null; 2739 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll(); 2740 for (String key : prefs.keySet()) { 2741 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) { 2742 final String subscriberId = (String) prefs.get(key); 2743 if (activeSubscriberIds.contains(subscriberId)) { 2744 final String iccId = key.substring(PREF_CARRIERS_SUBSCRIBER_PREFIX.length()); 2745 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId; 2746 mergeNumber = (String) prefs.get(numberKey); 2747 if (DBG_MERGE) { 2748 Slog.d(LOG_TAG, "Found line number " + mergeNumber 2749 + " for active subscriber " + subscriberId); 2750 } 2751 if (!TextUtils.isEmpty(mergeNumber)) { 2752 break; 2753 } 2754 } 2755 } 2756 } 2757 2758 // Shortcut when no active merged subscribers 2759 if (TextUtils.isEmpty(mergeNumber)) { 2760 return null; 2761 } 2762 2763 // Second pass, find all subscribers under that line override 2764 final ArraySet<String> result = new ArraySet<>(); 2765 for (String key : prefs.keySet()) { 2766 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) { 2767 final String number = (String) prefs.get(key); 2768 if (mergeNumber.equals(number)) { 2769 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length()); 2770 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId; 2771 final String subscriberId = (String) prefs.get(subscriberKey); 2772 if (!TextUtils.isEmpty(subscriberId)) { 2773 result.add(subscriberId); 2774 } 2775 } 2776 } 2777 } 2778 2779 final String[] resultArray = result.toArray(new String[result.size()]); 2780 Arrays.sort(resultArray); 2781 if (DBG_MERGE) { 2782 Slog.d(LOG_TAG, "Found subscribers " + Arrays.toString(resultArray) + " after merge"); 2783 } 2784 return resultArray; 2785 } 2786 2787 @Override setOperatorBrandOverride(int subId, String brand)2788 public boolean setOperatorBrandOverride(int subId, String brand) { 2789 enforceCarrierPrivilege(subId); 2790 final Phone phone = getPhone(subId); 2791 return phone == null ? false : phone.setOperatorBrandOverride(brand); 2792 } 2793 2794 @Override setRoamingOverride(int subId, List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList)2795 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList, 2796 List<String> gsmNonRoamingList, List<String> cdmaRoamingList, 2797 List<String> cdmaNonRoamingList) { 2798 enforceCarrierPrivilege(subId); 2799 final Phone phone = getPhone(subId); 2800 if (phone == null) { 2801 return false; 2802 } 2803 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList, 2804 cdmaNonRoamingList); 2805 } 2806 2807 @Override invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp)2808 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) { 2809 enforceModifyPermission(); 2810 2811 int returnValue = 0; 2812 try { 2813 AsyncResult result = (AsyncResult)sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq); 2814 if(result.exception == null) { 2815 if (result.result != null) { 2816 byte[] responseData = (byte[])(result.result); 2817 if(responseData.length > oemResp.length) { 2818 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " + 2819 responseData.length + "bytes. Buffer Size is " + 2820 oemResp.length + "bytes."); 2821 } 2822 System.arraycopy(responseData, 0, oemResp, 0, responseData.length); 2823 returnValue = responseData.length; 2824 } 2825 } else { 2826 CommandException ex = (CommandException) result.exception; 2827 returnValue = ex.getCommandError().ordinal(); 2828 if(returnValue > 0) returnValue *= -1; 2829 } 2830 } catch (RuntimeException e) { 2831 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception"); 2832 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal()); 2833 if(returnValue > 0) returnValue *= -1; 2834 } 2835 2836 return returnValue; 2837 } 2838 2839 @Override setRadioCapability(RadioAccessFamily[] rafs)2840 public void setRadioCapability(RadioAccessFamily[] rafs) { 2841 try { 2842 ProxyController.getInstance().setRadioCapability(rafs); 2843 } catch (RuntimeException e) { 2844 Log.w(LOG_TAG, "setRadioCapability: Runtime Exception"); 2845 } 2846 } 2847 2848 @Override getRadioAccessFamily(int phoneId, String callingPackage)2849 public int getRadioAccessFamily(int phoneId, String callingPackage) { 2850 if (!canReadPhoneState(callingPackage, "getRadioAccessFamily")) { 2851 return RadioAccessFamily.RAF_UNKNOWN; 2852 } 2853 2854 return ProxyController.getInstance().getRadioAccessFamily(phoneId); 2855 } 2856 2857 @Override enableVideoCalling(boolean enable)2858 public void enableVideoCalling(boolean enable) { 2859 enforceModifyPermission(); 2860 ImsManager.setVtSetting(mPhone.getContext(), enable); 2861 } 2862 2863 @Override isVideoCallingEnabled(String callingPackage)2864 public boolean isVideoCallingEnabled(String callingPackage) { 2865 if (!canReadPhoneState(callingPackage, "isVideoCallingEnabled")) { 2866 return false; 2867 } 2868 2869 // Check the user preference and the system-level IMS setting. Even if the user has 2870 // enabled video calling, if IMS is disabled we aren't able to support video calling. 2871 // In the long run, we may instead need to check if there exists a connection service 2872 // which can support video calling. 2873 return ImsManager.isVtEnabledByPlatform(mPhone.getContext()) 2874 && ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mPhone.getContext()) 2875 && ImsManager.isVtEnabledByUser(mPhone.getContext()); 2876 } 2877 2878 @Override canChangeDtmfToneLength()2879 public boolean canChangeDtmfToneLength() { 2880 return mApp.getCarrierConfig().getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL); 2881 } 2882 2883 @Override isWorldPhone()2884 public boolean isWorldPhone() { 2885 return mApp.getCarrierConfig().getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL); 2886 } 2887 2888 @Override isTtyModeSupported()2889 public boolean isTtyModeSupported() { 2890 TelecomManager telecomManager = TelecomManager.from(mPhone.getContext()); 2891 TelephonyManager telephonyManager = 2892 (TelephonyManager) mPhone.getContext().getSystemService(Context.TELEPHONY_SERVICE); 2893 return telecomManager.isTtySupported(); 2894 } 2895 2896 @Override isHearingAidCompatibilitySupported()2897 public boolean isHearingAidCompatibilitySupported() { 2898 return mPhone.getContext().getResources().getBoolean(R.bool.hac_enabled); 2899 } 2900 2901 /** 2902 * Returns the unique device ID of phone, for example, the IMEI for 2903 * GSM and the MEID for CDMA phones. Return null if device ID is not available. 2904 * 2905 * <p>Requires Permission: 2906 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 2907 */ 2908 @Override getDeviceId(String callingPackage)2909 public String getDeviceId(String callingPackage) { 2910 if (!canReadPhoneState(callingPackage, "getDeviceId")) { 2911 return null; 2912 } 2913 2914 final Phone phone = PhoneFactory.getPhone(0); 2915 if (phone != null) { 2916 return phone.getDeviceId(); 2917 } else { 2918 return null; 2919 } 2920 } 2921 2922 /* 2923 * {@hide} 2924 * Returns the IMS Registration Status 2925 */ 2926 @Override isImsRegistered()2927 public boolean isImsRegistered() { 2928 return mPhone.isImsRegistered(); 2929 } 2930 2931 @Override getSubIdForPhoneAccount(PhoneAccount phoneAccount)2932 public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) { 2933 return PhoneUtils.getSubIdForPhoneAccount(phoneAccount); 2934 } 2935 2936 /* 2937 * {@hide} 2938 * Returns the IMS Registration Status 2939 */ isWifiCallingAvailable()2940 public boolean isWifiCallingAvailable() { 2941 return mPhone.isWifiCallingEnabled(); 2942 } 2943 2944 /* 2945 * {@hide} 2946 * Returns the IMS Registration Status 2947 */ isVolteAvailable()2948 public boolean isVolteAvailable() { 2949 return mPhone.isVolteEnabled(); 2950 } 2951 2952 /* 2953 * {@hide} Returns the IMS Registration Status 2954 */ isVideoTelephonyAvailable()2955 public boolean isVideoTelephonyAvailable() { 2956 return mPhone.isVideoEnabled(); 2957 } 2958 canReadPhoneState(String callingPackage, String message)2959 private boolean canReadPhoneState(String callingPackage, String message) { 2960 try { 2961 mApp.enforceCallingOrSelfPermission( 2962 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message); 2963 2964 // SKIP checking for run-time permission since caller or self has PRIVILEDGED permission 2965 return true; 2966 } catch (SecurityException e) { 2967 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE, 2968 message); 2969 } 2970 2971 if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(), 2972 callingPackage) != AppOpsManager.MODE_ALLOWED) { 2973 return false; 2974 } 2975 2976 return true; 2977 } 2978 2979 /** 2980 * Besides READ_PHONE_STATE, WRITE_SMS and READ_SMS also allow apps to get phone numbers. 2981 */ canReadPhoneNumber(String callingPackage, String message)2982 private boolean canReadPhoneNumber(String callingPackage, String message) { 2983 // Default SMS app can always read it. 2984 if (mAppOps.noteOp(AppOpsManager.OP_WRITE_SMS, 2985 Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED) { 2986 return true; 2987 } 2988 try { 2989 return canReadPhoneState(callingPackage, message); 2990 } catch (SecurityException readPhoneStateSecurityException) { 2991 try { 2992 // Can be read with READ_SMS too. 2993 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_SMS, message); 2994 return mAppOps.noteOp(AppOpsManager.OP_READ_SMS, 2995 Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED; 2996 } catch (SecurityException readSmsSecurityException) { 2997 // Throw exception with message including both READ_PHONE_STATE and READ_SMS 2998 // permissions 2999 throw new SecurityException(message + ": Neither user " + Binder.getCallingUid() + 3000 " nor current process has " + android.Manifest.permission.READ_PHONE_STATE + 3001 " or " + android.Manifest.permission.READ_SMS + "."); 3002 } 3003 } 3004 } 3005 3006 @Override factoryReset(int subId)3007 public void factoryReset(int subId) { 3008 enforceConnectivityInternalPermission(); 3009 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) { 3010 return; 3011 } 3012 3013 final long identity = Binder.clearCallingIdentity(); 3014 try { 3015 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction( 3016 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) { 3017 // Enable data 3018 setDataEnabled(subId, true); 3019 // Set network selection mode to automatic 3020 setNetworkSelectionModeAutomatic(subId); 3021 // Set preferred mobile network type to the best available 3022 setPreferredNetworkType(subId, Phone.PREFERRED_NT_MODE); 3023 // Turn off roaming 3024 SubscriptionManager.from(mApp).setDataRoaming(0, subId); 3025 } 3026 } finally { 3027 Binder.restoreCallingIdentity(identity); 3028 } 3029 } 3030 3031 @Override getLocaleFromDefaultSim()3032 public String getLocaleFromDefaultSim() { 3033 // We query all subscriptions instead of just the active ones, because 3034 // this might be called early on in the provisioning flow when the 3035 // subscriptions potentially aren't active yet. 3036 final List<SubscriptionInfo> slist = getAllSubscriptionInfoList(); 3037 if (slist == null || slist.isEmpty()) { 3038 return null; 3039 } 3040 3041 // This function may be called very early, say, from the setup wizard, at 3042 // which point we won't have a default subscription set. If that's the case 3043 // we just choose the first, which will be valid in "most cases". 3044 final int defaultSubId = getDefaultSubscription(); 3045 SubscriptionInfo info = null; 3046 if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 3047 info = slist.get(0); 3048 } else { 3049 for (SubscriptionInfo item : slist) { 3050 if (item.getSubscriptionId() == defaultSubId) { 3051 info = item; 3052 break; 3053 } 3054 } 3055 3056 if (info == null) { 3057 return null; 3058 } 3059 } 3060 3061 // Try and fetch the locale from the carrier properties or from the SIM language 3062 // preferences (EF-PL and EF-LI)... 3063 final int mcc = info.getMcc(); 3064 final Phone defaultPhone = getPhone(info.getSubscriptionId()); 3065 String simLanguage = null; 3066 if (defaultPhone != null) { 3067 final Locale localeFromDefaultSim = defaultPhone.getLocaleFromSimAndCarrierPrefs(); 3068 if (localeFromDefaultSim != null) { 3069 if (!localeFromDefaultSim.getCountry().isEmpty()) { 3070 if (DBG) log("Using locale from default SIM:" + localeFromDefaultSim); 3071 return localeFromDefaultSim.toLanguageTag(); 3072 } else { 3073 simLanguage = localeFromDefaultSim.getLanguage(); 3074 } 3075 } 3076 } 3077 3078 // The SIM language preferences only store a language (e.g. fr = French), not an 3079 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from 3080 // the SIM and carrier preferences does not include a country we add the country 3081 // determined from the SIM MCC to provide an exact locale. 3082 final Locale mccLocale = MccTable.getLocaleFromMcc(mPhone.getContext(), mcc, simLanguage); 3083 if (mccLocale != null) { 3084 if (DBG) log("No locale from default SIM, using mcc locale:" + mccLocale); 3085 return mccLocale.toLanguageTag(); 3086 } 3087 3088 if (DBG) log("No locale found - returning null"); 3089 return null; 3090 } 3091 getAllSubscriptionInfoList()3092 private List<SubscriptionInfo> getAllSubscriptionInfoList() { 3093 final long identity = Binder.clearCallingIdentity(); 3094 try { 3095 return mSubscriptionController.getAllSubInfoList( 3096 mPhone.getContext().getOpPackageName()); 3097 } finally { 3098 Binder.restoreCallingIdentity(identity); 3099 } 3100 } 3101 getActiveSubscriptionInfoList()3102 private List<SubscriptionInfo> getActiveSubscriptionInfoList() { 3103 final long identity = Binder.clearCallingIdentity(); 3104 try { 3105 return mSubscriptionController.getActiveSubscriptionInfoList( 3106 mPhone.getContext().getOpPackageName()); 3107 } finally { 3108 Binder.restoreCallingIdentity(identity); 3109 } 3110 } 3111 3112 /** 3113 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object 3114 * representing the state of the modem. 3115 * 3116 * NOTE: This clears the modem state, so there should only every be one caller. 3117 * @hide 3118 */ 3119 @Override requestModemActivityInfo(ResultReceiver result)3120 public void requestModemActivityInfo(ResultReceiver result) { 3121 enforceModifyPermission(); 3122 3123 ModemActivityInfo info = (ModemActivityInfo) sendRequest(CMD_GET_MODEM_ACTIVITY_INFO, null); 3124 Bundle bundle = new Bundle(); 3125 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, info); 3126 result.send(0, bundle); 3127 } 3128 3129 /** 3130 * {@hide} 3131 * Returns the service state information on specified subscription. 3132 */ 3133 @Override getServiceStateForSubscriber(int subId, String callingPackage)3134 public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) { 3135 3136 if (!canReadPhoneState(callingPackage, "getServiceStateForSubscriber")) { 3137 return null; 3138 } 3139 3140 final Phone phone = getPhone(subId); 3141 if (phone == null) { 3142 return null; 3143 } 3144 3145 return phone.getServiceState(); 3146 } 3147 3148 /** 3149 * Returns the URI for the per-account voicemail ringtone set in Phone settings. 3150 * 3151 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the 3152 * voicemail ringtone. 3153 * @return The URI for the ringtone to play when receiving a voicemail from a specific 3154 * PhoneAccount. 3155 */ 3156 @Override getVoicemailRingtoneUri(PhoneAccountHandle accountHandle)3157 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) { 3158 final Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle); 3159 if (phone == null) { 3160 return null; 3161 } 3162 3163 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone); 3164 } 3165 3166 /** 3167 * Returns whether vibration is set for voicemail notification in Phone settings. 3168 * 3169 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the 3170 * voicemail vibration setting. 3171 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise. 3172 */ 3173 @Override isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle)3174 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) { 3175 final Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle); 3176 if (phone == null) { 3177 return false; 3178 } 3179 3180 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone); 3181 } 3182 3183 /** 3184 * Make sure either called from same process as self (phone) or IPC caller has read privilege. 3185 * 3186 * @throws SecurityException if the caller does not have the required permission 3187 */ enforceReadPrivilegedPermission()3188 private void enforceReadPrivilegedPermission() { 3189 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 3190 null); 3191 } 3192 3193 /** 3194 * Return the application ID for the app type. 3195 * 3196 * @param subId the subscription ID that this request applies to. 3197 * @param appType the uicc app type. 3198 * @return Application ID for specificied app type, or null if no uicc. 3199 */ 3200 @Override getAidForAppType(int subId, int appType)3201 public String getAidForAppType(int subId, int appType) { 3202 enforceReadPrivilegedPermission(); 3203 Phone phone = getPhone(subId); 3204 if (phone == null) { 3205 return null; 3206 } 3207 String aid = null; 3208 try { 3209 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId()) 3210 .getApplicationByType(appType).getAid(); 3211 } catch (Exception e) { 3212 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e); 3213 } 3214 return aid; 3215 } 3216 3217 /** 3218 * Return the Electronic Serial Number. 3219 * 3220 * @param subId the subscription ID that this request applies to. 3221 * @return ESN or null if error. 3222 */ 3223 @Override getEsn(int subId)3224 public String getEsn(int subId) { 3225 enforceReadPrivilegedPermission(); 3226 Phone phone = getPhone(subId); 3227 if (phone == null) { 3228 return null; 3229 } 3230 String esn = null; 3231 try { 3232 esn = phone.getEsn(); 3233 } catch (Exception e) { 3234 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e); 3235 } 3236 return esn; 3237 } 3238 3239 /** 3240 * Return the Preferred Roaming List Version. 3241 * 3242 * @param subId the subscription ID that this request applies to. 3243 * @return PRLVersion or null if error. 3244 */ 3245 @Override getCdmaPrlVersion(int subId)3246 public String getCdmaPrlVersion(int subId) { 3247 enforceReadPrivilegedPermission(); 3248 Phone phone = getPhone(subId); 3249 if (phone == null) { 3250 return null; 3251 } 3252 String cdmaPrlVersion = null; 3253 try { 3254 cdmaPrlVersion = phone.getCdmaPrlVersion(); 3255 } catch (Exception e) { 3256 Log.e(LOG_TAG, "Not getting PRLVersion", e); 3257 } 3258 return cdmaPrlVersion; 3259 } 3260 3261 /** 3262 * Get snapshot of Telephony histograms 3263 * @return List of Telephony histograms 3264 * @hide 3265 */ 3266 @Override getTelephonyHistograms()3267 public List<TelephonyHistogram> getTelephonyHistograms() { 3268 enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription()); 3269 return RIL.getTelephonyRILTimingHistograms(); 3270 } 3271 3272 /** 3273 * {@hide} 3274 * Set the allowed carrier list for slotId 3275 * Require system privileges. In the future we may add this to carrier APIs. 3276 * 3277 * @return The number of carriers set successfully, should match length of carriers 3278 */ 3279 @Override setAllowedCarriers(int slotId, List<CarrierIdentifier> carriers)3280 public int setAllowedCarriers(int slotId, List<CarrierIdentifier> carriers) { 3281 enforceModifyPermission(); 3282 int subId = SubscriptionManager.getSubId(slotId)[0]; 3283 int[] retVal = (int[]) sendRequest(CMD_SET_ALLOWED_CARRIERS, carriers, subId); 3284 return retVal[0]; 3285 } 3286 3287 /** 3288 * {@hide} 3289 * Get the allowed carrier list for slotId. 3290 * Require system privileges. In the future we may add this to carrier APIs. 3291 * 3292 * @return List of {@link android.service.telephony.CarrierIdentifier}; empty list 3293 * means all carriers are allowed. 3294 */ 3295 @Override getAllowedCarriers(int slotId)3296 public List<CarrierIdentifier> getAllowedCarriers(int slotId) { 3297 enforceReadPrivilegedPermission(); 3298 int subId = SubscriptionManager.getSubId(slotId)[0]; 3299 return (List<CarrierIdentifier>) sendRequest(CMD_GET_ALLOWED_CARRIERS, null, subId); 3300 } 3301 3302 /** 3303 * Action set from carrier signalling broadcast receivers to enable/disable metered apns 3304 * @param subId the subscription ID that this action applies to. 3305 * @param enabled control enable or disable metered apns. 3306 * {@hide} 3307 */ 3308 @Override carrierActionSetMeteredApnsEnabled(int subId, boolean enabled)3309 public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) { 3310 enforceModifyPermission(); 3311 final Phone phone = getPhone(subId); 3312 if (phone == null) { 3313 loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId); 3314 return; 3315 } 3316 try { 3317 phone.carrierActionSetMeteredApnsEnabled(enabled); 3318 } catch (Exception e) { 3319 Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e); 3320 } 3321 } 3322 3323 /** 3324 * Action set from carrier signalling broadcast receivers to enable/disable radio 3325 * @param subId the subscription ID that this action applies to. 3326 * @param enabled control enable or disable radio. 3327 * {@hide} 3328 */ 3329 @Override carrierActionSetRadioEnabled(int subId, boolean enabled)3330 public void carrierActionSetRadioEnabled(int subId, boolean enabled) { 3331 enforceModifyPermission(); 3332 final Phone phone = getPhone(subId); 3333 if (phone == null) { 3334 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId); 3335 return; 3336 } 3337 try { 3338 phone.carrierActionSetRadioEnabled(enabled); 3339 } catch (Exception e) { 3340 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e); 3341 } 3342 } 3343 3344 /** 3345 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a 3346 * bug report is being generated. 3347 */ 3348 @Override dump(FileDescriptor fd, PrintWriter writer, String[] args)3349 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 3350 if (mPhone.getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 3351 != PackageManager.PERMISSION_GRANTED) { 3352 writer.println("Permission Denial: can't dump Phone from pid=" 3353 + Binder.getCallingPid() 3354 + ", uid=" + Binder.getCallingUid() 3355 + "without permission " 3356 + android.Manifest.permission.DUMP); 3357 return; 3358 } 3359 DumpsysHandler.dump(mPhone.getContext(), fd, writer, args); 3360 } 3361 3362 /** 3363 * Get aggregated video call data usage from all subscriptions since boot. 3364 * @return total data usage in bytes 3365 * {@hide} 3366 */ 3367 @Override getVtDataUsage()3368 public long getVtDataUsage() { 3369 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_NETWORK_USAGE_HISTORY, 3370 null); 3371 3372 // NetworkStatsService keeps tracking the active network interface and identity. It will 3373 // record the delta with the corresponding network identity. What we need to do here is 3374 // returning total video call data usage from all subscriptions since boot. 3375 3376 // TODO: Add sub id support in the future. We'll need it when we support DSDA and 3377 // simultaneous VT calls. 3378 final Phone[] phones = PhoneFactory.getPhones(); 3379 long total = 0; 3380 for (Phone phone : phones) { 3381 total += phone.getVtDataUsage(); 3382 } 3383 return total; 3384 } 3385 3386 /** 3387 * Policy control of data connection. Usually used when data limit is passed. 3388 * @param enabled True if enabling the data, otherwise disabling. 3389 * @param subId Subscription index 3390 * {@hide} 3391 */ 3392 @Override setPolicyDataEnabled(boolean enabled, int subId)3393 public void setPolicyDataEnabled(boolean enabled, int subId) { 3394 enforceModifyPermission(); 3395 Phone phone = getPhone(subId); 3396 if (phone != null) { 3397 phone.setPolicyDataEnabled(enabled); 3398 } 3399 } 3400 } 3401