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