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