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