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