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