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 IccAPDUArgument(int channel, int cla, int command, int p1, int p2, int p3, String data)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 MainThreadRequest(Object argument)171 public MainThreadRequest(Object argument) { 172 this.argument = argument; 173 } 174 MainThreadRequest(Object argument, Integer subId)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 IncomingThirdPartyCallArgs(ComponentName component, String callId, String callerDisplayName)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 handleMessage(Message msg)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 handleNullReturnEvent(Message msg, String command)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 */ sendRequest(int command, Object argument)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 */ sendRequest(int command, Object argument, Integer subId)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 */ sendRequestAsync(int command)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 */ sendRequestAsync(int command, Object argument)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 */ init(PhoneGlobals app, Phone phone)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() */ PhoneInterfaceManager(PhoneGlobals app, Phone phone)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 publish()728 private void publish() { 729 if (DBG) log("publish: " + this); 730 731 ServiceManager.addService("phone", this); 732 } 733 getPhoneFromRequest(MainThreadRequest request)734 private Phone getPhoneFromRequest(MainThreadRequest request) { 735 return (request.subId == null) ? mPhone : getPhone(request.subId); 736 } 737 738 // returns phone associated with the subId. getPhone(int subId)739 private Phone getPhone(int subId) { 740 return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId)); 741 } 742 // 743 // Implementation of the ITelephony interface. 744 // 745 dial(String number)746 public void dial(String number) { 747 dialForSubscriber(getPreferredVoiceSubscription(), number); 748 } 749 dialForSubscriber(int subId, String number)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 call(String callingPackage, String number)770 public void call(String callingPackage, String number) { 771 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number); 772 } 773 callForSubscriber(int subId, String callingPackage, String number)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 */ endCall()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 */ endCallForSubscriber(int subId)824 public boolean endCallForSubscriber(int subId) { 825 enforceCallPermission(); 826 return (Boolean) sendRequest(CMD_END_CALL, null, new Integer(subId)); 827 } 828 answerRingingCall()829 public void answerRingingCall() { 830 answerRingingCallForSubscriber(getDefaultSubscription()); 831 } 832 answerRingingCallForSubscriber(int subId)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 */ answerRingingCallInternal(int subId)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 */ silenceRinger()883 public void silenceRinger() { 884 Log.e(LOG_TAG, "silenseRinger not supported"); 885 } 886 isOffhook()887 public boolean isOffhook() { 888 return isOffhookForSubscriber(getDefaultSubscription()); 889 } 890 isOffhookForSubscriber(int subId)891 public boolean isOffhookForSubscriber(int subId) { 892 return (getPhone(subId).getState() == PhoneConstants.State.OFFHOOK); 893 } 894 isRinging()895 public boolean isRinging() { 896 return (isRingingForSubscriber(getDefaultSubscription())); 897 } 898 isRingingForSubscriber(int subId)899 public boolean isRingingForSubscriber(int subId) { 900 return (getPhone(subId).getState() == PhoneConstants.State.RINGING); 901 } 902 isIdle()903 public boolean isIdle() { 904 return isIdleForSubscriber(getDefaultSubscription()); 905 } 906 isIdleForSubscriber(int subId)907 public boolean isIdleForSubscriber(int subId) { 908 return (getPhone(subId).getState() == PhoneConstants.State.IDLE); 909 } 910 isSimPinEnabled()911 public boolean isSimPinEnabled() { 912 enforceReadPermission(); 913 return (PhoneGlobals.getInstance().isSimPinEnabled()); 914 } 915 supplyPin(String pin)916 public boolean supplyPin(String pin) { 917 return supplyPinForSubscriber(getDefaultSubscription(), pin); 918 } 919 supplyPinForSubscriber(int subId, String pin)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 supplyPuk(String puk, String pin)925 public boolean supplyPuk(String puk, String pin) { 926 return supplyPukForSubscriber(getDefaultSubscription(), puk, pin); 927 } 928 supplyPukForSubscriber(int subId, String puk, String pin)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} */ supplyPinReportResult(String pin)935 public int[] supplyPinReportResult(String pin) { 936 return supplyPinReportResultForSubscriber(getDefaultSubscription(), pin); 937 } 938 supplyPinReportResultForSubscriber(int subId, String pin)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} */ supplyPukReportResult(String puk, String pin)947 public int[] supplyPukReportResult(String puk, String pin) { 948 return supplyPukReportResultForSubscriber(getDefaultSubscription(), puk, pin); 949 } 950 supplyPukReportResultForSubscriber(int subId, String puk, String pin)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 UnlockSim(IccCard simCard)976 public UnlockSim(IccCard simCard) { 977 mSimCard = simCard; 978 } 979 980 @Override run()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 */ unlockSim(String puk, String pin)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 updateServiceLocation()1057 public void updateServiceLocation() { 1058 updateServiceLocationForSubscriber(getDefaultSubscription()); 1059 1060 } 1061 updateServiceLocationForSubscriber(int subId)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 isRadioOn()1069 public boolean isRadioOn() { 1070 return isRadioOnForSubscriber(getDefaultSubscription()); 1071 } 1072 isRadioOnForSubscriber(int subId)1073 public boolean isRadioOnForSubscriber(int subId) { 1074 return getPhone(subId).getServiceState().getState() != ServiceState.STATE_POWER_OFF; 1075 } 1076 toggleRadioOnOff()1077 public void toggleRadioOnOff() { 1078 toggleRadioOnOffForSubscriber(getDefaultSubscription()); 1079 1080 } 1081 toggleRadioOnOffForSubscriber(int subId)1082 public void toggleRadioOnOffForSubscriber(int subId) { 1083 enforceModifyPermission(); 1084 getPhone(subId).setRadioPower(!isRadioOnForSubscriber(subId)); 1085 } 1086 setRadio(boolean turnOn)1087 public boolean setRadio(boolean turnOn) { 1088 return setRadioForSubscriber(getDefaultSubscription(), turnOn); 1089 } 1090 setRadioForSubscriber(int subId, boolean turnOn)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 needMobileRadioShutdown()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 shutdownMobileRadios()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 shutdownRadioUsingPhoneId(int phoneId)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 setRadioPower(boolean turnOn)1128 public boolean setRadioPower(boolean turnOn) { 1129 return setRadioPowerForSubscriber(getDefaultSubscription(), turnOn); 1130 } 1131 setRadioPowerForSubscriber(int subId, boolean turnOn)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 enableDataConnectivity()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 disableDataConnectivity()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 isDataConnectivityPossible()1155 public boolean isDataConnectivityPossible() { 1156 int subId = mSubscriptionController.getDefaultDataSubId(); 1157 return getPhone(subId).isDataConnectivityPossible(); 1158 } 1159 handlePinMmi(String dialString)1160 public boolean handlePinMmi(String dialString) { 1161 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString); 1162 } 1163 handlePinMmiForSubscriber(int subId, String dialString)1164 public boolean handlePinMmiForSubscriber(int subId, String dialString) { 1165 enforceModifyPermission(); 1166 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId); 1167 } 1168 getCallState()1169 public int getCallState() { 1170 return getCallStateForSubscriber(getDefaultSubscription()); 1171 } 1172 getCallStateForSubscriber(int subId)1173 public int getCallStateForSubscriber(int subId) { 1174 return DefaultPhoneNotifier.convertCallState(getPhone(subId).getState()); 1175 } 1176 getDataState()1177 public int getDataState() { 1178 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId()); 1179 return DefaultPhoneNotifier.convertDataState(phone.getDataConnectionState()); 1180 } 1181 getDataActivity()1182 public int getDataActivity() { 1183 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId()); 1184 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState()); 1185 } 1186 1187 @Override getCellLocation()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 enableLocationUpdates()1213 public void enableLocationUpdates() { 1214 enableLocationUpdatesForSubscriber(getDefaultSubscription()); 1215 } 1216 enableLocationUpdatesForSubscriber(int subId)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 disableLocationUpdates()1224 public void disableLocationUpdates() { 1225 disableLocationUpdatesForSubscriber(getDefaultSubscription()); 1226 } 1227 disableLocationUpdatesForSubscriber(int subId)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") getNeighboringCellInfo(String callingPackage)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 getAllCellInfo()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 setCellInfoListRate(int rateInMillis)1299 public void setCellInfoListRate(int rateInMillis) { 1300 mPhone.setCellInfoListRate(rateInMillis); 1301 } 1302 1303 // 1304 // Internal helper methods. 1305 // 1306 checkIfCallerIsSelfOrForegroundUser()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 */ enforceReadPermission()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 */ enforceModifyPermission()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 */ enforceModifyPermissionOrCarrierPrivilege()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 */ enforceCarrierPrivilege()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 */ enforceCallPermission()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 */ enforcePrivilegedPhoneStatePermission()1402 private void enforcePrivilegedPhoneStatePermission() { 1403 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 1404 null); 1405 } 1406 createTelUrl(String number)1407 private String createTelUrl(String number) { 1408 if (TextUtils.isEmpty(number)) { 1409 return null; 1410 } 1411 1412 return "tel:" + number; 1413 } 1414 log(String msg)1415 private static void log(String msg) { 1416 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg); 1417 } 1418 logv(String msg)1419 private static void logv(String msg) { 1420 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg); 1421 } 1422 loge(String msg)1423 private static void loge(String msg) { 1424 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg); 1425 } 1426 getActivePhoneType()1427 public int getActivePhoneType() { 1428 return getActivePhoneTypeForSubscriber(getDefaultSubscription()); 1429 } 1430 getActivePhoneTypeForSubscriber(int subId)1431 public int getActivePhoneTypeForSubscriber(int subId) { 1432 return getPhone(subId).getPhoneType(); 1433 } 1434 1435 /** 1436 * Returns the CDMA ERI icon index to display 1437 */ getCdmaEriIconIndex()1438 public int getCdmaEriIconIndex() { 1439 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription()); 1440 1441 } 1442 getCdmaEriIconIndexForSubscriber(int subId)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 */ getCdmaEriIconMode()1452 public int getCdmaEriIconMode() { 1453 return getCdmaEriIconModeForSubscriber(getDefaultSubscription()); 1454 } 1455 getCdmaEriIconModeForSubscriber(int subId)1456 public int getCdmaEriIconModeForSubscriber(int subId) { 1457 return getPhone(subId).getCdmaEriIconMode(); 1458 } 1459 1460 /** 1461 * Returns the CDMA ERI text, 1462 */ getCdmaEriText()1463 public String getCdmaEriText() { 1464 return getCdmaEriTextForSubscriber(getDefaultSubscription()); 1465 } 1466 getCdmaEriTextForSubscriber(int subId)1467 public String getCdmaEriTextForSubscriber(int subId) { 1468 return getPhone(subId).getCdmaEriText(); 1469 } 1470 1471 /** 1472 * Returns the CDMA MDN. 1473 */ getCdmaMdn(int subId)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 */ getCdmaMin(int subId)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 */ needsOtaServiceProvisioning()1498 public boolean needsOtaServiceProvisioning() { 1499 return mPhone.needsOtaServiceProvisioning(); 1500 } 1501 1502 /** 1503 * Sets the voice mail number of a given subId. 1504 */ 1505 @Override setVoiceMailNumber(int subId, String alphaTag, String number)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 */ getVoiceMessageCount()1516 public int getVoiceMessageCount() { 1517 return getVoiceMessageCountForSubscriber(getDefaultSubscription()); 1518 } 1519 1520 /** 1521 * Returns the unread count of voicemails for a subId 1522 */ getVoiceMessageCountForSubscriber( int subId)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 getNetworkType()1533 public int getNetworkType() { 1534 return getNetworkTypeForSubscriber(getDefaultSubscription()); 1535 } 1536 1537 /** 1538 * Returns the network type for a subId 1539 */ 1540 @Override getNetworkTypeForSubscriber(int subId)1541 public int getNetworkTypeForSubscriber(int subId) { 1542 return getPhone(subId).getServiceState().getDataNetworkType(); 1543 } 1544 1545 /** 1546 * Returns the data network type 1547 */ 1548 @Override getDataNetworkType()1549 public int getDataNetworkType() { 1550 return getDataNetworkTypeForSubscriber(getDefaultSubscription()); 1551 } 1552 1553 /** 1554 * Returns the data network type for a subId 1555 */ 1556 @Override getDataNetworkTypeForSubscriber(int subId)1557 public int getDataNetworkTypeForSubscriber(int subId) { 1558 return getPhone(subId).getServiceState().getDataNetworkType(); 1559 } 1560 1561 /** 1562 * Returns the data network type 1563 */ 1564 @Override getVoiceNetworkType()1565 public int getVoiceNetworkType() { 1566 return getVoiceNetworkTypeForSubscriber(getDefaultSubscription()); 1567 } 1568 1569 /** 1570 * Returns the Voice network type for a subId 1571 */ 1572 @Override getVoiceNetworkTypeForSubscriber(int subId)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 */ hasIccCard()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 */ hasIccCardUsingSlotId(int slotId)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 */ getLteOnCdmaMode()1605 public int getLteOnCdmaMode() { 1606 return getLteOnCdmaModeForSubscriber(getDefaultSubscription()); 1607 } 1608 getLteOnCdmaModeForSubscriber(int subId)1609 public int getLteOnCdmaModeForSubscriber(int subId) { 1610 return getPhone(subId).getLteOnCdmaMode(); 1611 } 1612 setPhone(Phone phone)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 */ getDefaultSubscription()1621 private int getDefaultSubscription() { 1622 return mSubscriptionController.getDefaultSubId(); 1623 } 1624 getPreferredVoiceSubscription()1625 private int getPreferredVoiceSubscription() { 1626 return mSubscriptionController.getDefaultVoiceSubId(); 1627 } 1628 1629 /** 1630 * @see android.telephony.TelephonyManager.WifiCallingChoices 1631 */ getWhenToMakeWifiCalls()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 */ setWhenToMakeWifiCalls(int preference)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 getWhenToMakeWifiCallsDefaultPreference()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 iccOpenLogicalChannel(String AID)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 iccCloseLogicalChannel(int channel)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 iccTransmitApduLogicalChannel(int channel, int cla, int command, int p1, int p2, int p3, String data)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 iccTransmitApduBasicChannel(int cla, int command, int p1, int p2, int p3, String data)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 iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3, String filePath)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 sendEnvelopeWithStatus(String content)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 nvReadItem(int itemID)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 nvWriteItem(int itemID, String itemValue)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 nvWriteCdmaPrl(byte[] preferredRoamingList)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 nvResetConfig(int resetType)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 */ getDefaultSim()1845 public int getDefaultSim() { 1846 //TODO Need to get it from Telephony Devcontroller 1847 return 0; 1848 } 1849 getPcscfAddress(String apnType)1850 public String[] getPcscfAddress(String apnType) { 1851 enforceReadPermission(); 1852 return mPhone.getPcscfAddress(apnType); 1853 } 1854 setImsRegistrationState(boolean registered)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 getCalculatedPreferredNetworkType()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 getPreferredNetworkType()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 setPreferredNetworkType(int networkType)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 getTetherApnRequired()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 setDataEnabled(int subId, boolean enable)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 getDataEnabled(int subId)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 getCarrierPrivilegeStatus()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 checkCarrierPrivilegesForPackage(String pkgname)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 getCarrierPackageNamesForIntent(Intent intent)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 getIccId(int subId)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 setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, String number)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 getLine1NumberForDisplay(int subId)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 getLine1AlphaTagForDisplay(int subId)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 getMergedSubscriberIds()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 setOperatorBrandOverride(String brand)2157 public boolean setOperatorBrandOverride(String brand) { 2158 enforceCarrierPrivilege(); 2159 return mPhone.setOperatorBrandOverride(brand); 2160 } 2161 2162 @Override setRoamingOverride(List<String> gsmRoamingList, List<String> gsmNonRoamingList, List<String> cdmaRoamingList, List<String> cdmaNonRoamingList)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 invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp)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 setRadioCapability(RadioAccessFamily[] rafs)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 getRadioAccessFamily(int phoneId)2213 public int getRadioAccessFamily(int phoneId) { 2214 return ProxyController.getInstance().getRadioAccessFamily(phoneId); 2215 } 2216 2217 @Override enableVideoCalling(boolean enable)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 isVideoCallingEnabled()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 getDeviceId()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 */ isImsRegistered()2259 public boolean isImsRegistered() { 2260 return mPhone.isImsRegistered(); 2261 } 2262 } 2263