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