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