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