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