1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.phone; 18 19 import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY; 20 21 import android.Manifest.permission; 22 import android.app.AppOpsManager; 23 import android.app.PendingIntent; 24 import android.content.ComponentName; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.content.SharedPreferences; 28 import android.content.pm.ComponentInfo; 29 import android.content.pm.PackageInfo; 30 import android.content.pm.PackageManager; 31 import android.net.NetworkStats; 32 import android.net.Uri; 33 import android.os.AsyncResult; 34 import android.os.Binder; 35 import android.os.Bundle; 36 import android.os.Handler; 37 import android.os.IBinder; 38 import android.os.Looper; 39 import android.os.Message; 40 import android.os.Messenger; 41 import android.os.Process; 42 import android.os.PersistableBundle; 43 import android.os.ResultReceiver; 44 import android.os.ServiceManager; 45 import android.os.UserHandle; 46 import android.os.UserManager; 47 import android.os.WorkSource; 48 import android.preference.PreferenceManager; 49 import android.provider.Settings; 50 import android.service.carrier.CarrierIdentifier; 51 import android.telecom.PhoneAccount; 52 import android.telecom.PhoneAccountHandle; 53 import android.telecom.TelecomManager; 54 import android.telephony.CarrierConfigManager; 55 import android.telephony.CellInfo; 56 import android.telephony.ClientRequestStats; 57 import android.telephony.IccOpenLogicalChannelResponse; 58 import android.telephony.ModemActivityInfo; 59 import android.telephony.NeighboringCellInfo; 60 import android.telephony.NetworkScanRequest; 61 import android.telephony.RadioAccessFamily; 62 import android.telephony.Rlog; 63 import android.telephony.ServiceState; 64 import android.telephony.SignalStrength; 65 import android.telephony.SmsManager; 66 import android.telephony.SubscriptionInfo; 67 import android.telephony.SubscriptionManager; 68 import android.telephony.TelephonyHistogram; 69 import android.telephony.TelephonyManager; 70 import android.telephony.UssdResponse; 71 import android.telephony.VisualVoicemailSmsFilterSettings; 72 import android.text.TextUtils; 73 import android.util.ArraySet; 74 import android.util.Log; 75 import android.util.Pair; 76 import android.util.Slog; 77 78 import com.android.ims.ImsManager; 79 import com.android.ims.internal.IImsServiceController; 80 import com.android.ims.internal.IImsServiceFeatureListener; 81 import com.android.internal.telephony.CallManager; 82 import com.android.internal.telephony.CallStateException; 83 import com.android.internal.telephony.CellNetworkScanResult; 84 import com.android.internal.telephony.CommandException; 85 import com.android.internal.telephony.DefaultPhoneNotifier; 86 import com.android.internal.telephony.ITelephony; 87 import com.android.internal.telephony.IccCard; 88 import com.android.internal.telephony.MccTable; 89 import com.android.internal.telephony.NetworkScanRequestTracker; 90 import com.android.internal.telephony.OperatorInfo; 91 import com.android.internal.telephony.Phone; 92 import com.android.internal.telephony.PhoneConstantConversions; 93 import com.android.internal.telephony.PhoneConstants; 94 import com.android.internal.telephony.PhoneFactory; 95 import com.android.internal.telephony.ProxyController; 96 import com.android.internal.telephony.RIL; 97 import com.android.internal.telephony.RILConstants; 98 import com.android.internal.telephony.SubscriptionController; 99 import com.android.internal.telephony.TelephonyProperties; 100 import com.android.internal.telephony.euicc.EuiccConnector; 101 import com.android.internal.telephony.uicc.IccIoResult; 102 import com.android.internal.telephony.uicc.IccUtils; 103 import com.android.internal.telephony.uicc.SIMRecords; 104 import com.android.internal.telephony.uicc.UiccCard; 105 import com.android.internal.telephony.uicc.UiccCardApplication; 106 import com.android.internal.telephony.uicc.UiccController; 107 import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil; 108 import com.android.internal.util.HexDump; 109 import com.android.phone.vvm.PhoneAccountHandleConverter; 110 import com.android.phone.vvm.RemoteVvmTaskManager; 111 import com.android.phone.vvm.VisualVoicemailSettingsUtil; 112 import com.android.phone.vvm.VisualVoicemailSmsFilterConfig; 113 114 import java.io.FileDescriptor; 115 import java.io.PrintWriter; 116 import java.nio.charset.StandardCharsets; 117 import java.util.ArrayList; 118 import java.util.Arrays; 119 import java.util.List; 120 import java.util.Locale; 121 import java.util.Map; 122 123 /** 124 * Implementation of the ITelephony interface. 125 */ 126 public class PhoneInterfaceManager extends ITelephony.Stub { 127 private static final String LOG_TAG = "PhoneInterfaceManager"; 128 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2); 129 private static final boolean DBG_LOC = false; 130 private static final boolean DBG_MERGE = false; 131 132 // Message codes used with mMainThreadHandler 133 private static final int CMD_HANDLE_PIN_MMI = 1; 134 private static final int CMD_HANDLE_NEIGHBORING_CELL = 2; 135 private static final int EVENT_NEIGHBORING_CELL_DONE = 3; 136 private static final int CMD_ANSWER_RINGING_CALL = 4; 137 private static final int CMD_END_CALL = 5; // not used yet 138 private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7; 139 private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8; 140 private static final int CMD_OPEN_CHANNEL = 9; 141 private static final int EVENT_OPEN_CHANNEL_DONE = 10; 142 private static final int CMD_CLOSE_CHANNEL = 11; 143 private static final int EVENT_CLOSE_CHANNEL_DONE = 12; 144 private static final int CMD_NV_READ_ITEM = 13; 145 private static final int EVENT_NV_READ_ITEM_DONE = 14; 146 private static final int CMD_NV_WRITE_ITEM = 15; 147 private static final int EVENT_NV_WRITE_ITEM_DONE = 16; 148 private static final int CMD_NV_WRITE_CDMA_PRL = 17; 149 private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18; 150 private static final int CMD_NV_RESET_CONFIG = 19; 151 private static final int EVENT_NV_RESET_CONFIG_DONE = 20; 152 private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21; 153 private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22; 154 private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23; 155 private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24; 156 private static final int CMD_SEND_ENVELOPE = 25; 157 private static final int EVENT_SEND_ENVELOPE_DONE = 26; 158 private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27; 159 private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28; 160 private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29; 161 private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30; 162 private static final int CMD_EXCHANGE_SIM_IO = 31; 163 private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32; 164 private static final int CMD_SET_VOICEMAIL_NUMBER = 33; 165 private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34; 166 private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35; 167 private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36; 168 private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37; 169 private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38; 170 private static final int CMD_PERFORM_NETWORK_SCAN = 39; 171 private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40; 172 private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41; 173 private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42; 174 private static final int CMD_SET_ALLOWED_CARRIERS = 43; 175 private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44; 176 private static final int CMD_GET_ALLOWED_CARRIERS = 45; 177 private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46; 178 private static final int CMD_HANDLE_USSD_REQUEST = 47; 179 private static final int CMD_GET_FORBIDDEN_PLMNS = 48; 180 private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49; 181 182 /** The singleton instance. */ 183 private static PhoneInterfaceManager sInstance; 184 185 private PhoneGlobals mApp; 186 private Phone mPhone; 187 private CallManager mCM; 188 private UserManager mUserManager; 189 private AppOpsManager mAppOps; 190 private MainThreadHandler mMainThreadHandler; 191 private SubscriptionController mSubscriptionController; 192 private SharedPreferences mTelephonySharedPreferences; 193 194 private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_"; 195 private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_"; 196 private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_"; 197 198 // The AID of ISD-R. 199 private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100"; 200 201 private NetworkScanRequestTracker mNetworkScanRequestTracker; 202 203 /** 204 * A request object to use for transmitting data to an ICC. 205 */ 206 private static final class IccAPDUArgument { 207 public int channel, cla, command, p1, p2, p3; 208 public String data; 209 210 public IccAPDUArgument(int channel, int cla, int command, 211 int p1, int p2, int p3, String data) { 212 this.channel = channel; 213 this.cla = cla; 214 this.command = command; 215 this.p1 = p1; 216 this.p2 = p2; 217 this.p3 = p3; 218 this.data = data; 219 } 220 } 221 222 /** 223 * A request object to use for transmitting data to an ICC. 224 */ 225 private static final class ManualNetworkSelectionArgument { 226 public OperatorInfo operatorInfo; 227 public boolean persistSelection; 228 229 public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) { 230 this.operatorInfo = operatorInfo; 231 this.persistSelection = persistSelection; 232 } 233 } 234 235 /** 236 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the 237 * request after sending. The main thread will notify the request when it is complete. 238 */ 239 private static final class MainThreadRequest { 240 /** The argument to use for the request */ 241 public Object argument; 242 /** The result of the request that is run on the main thread */ 243 public Object result; 244 // The subscriber id that this request applies to. Defaults to 245 // SubscriptionManager.INVALID_SUBSCRIPTION_ID 246 public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 247 248 public MainThreadRequest(Object argument) { 249 this.argument = argument; 250 } 251 252 public MainThreadRequest(Object argument, Integer subId) { 253 this.argument = argument; 254 if (subId != null) { 255 this.subId = subId; 256 } 257 } 258 } 259 260 private static final class IncomingThirdPartyCallArgs { 261 public final ComponentName component; 262 public final String callId; 263 public final String callerDisplayName; 264 265 public IncomingThirdPartyCallArgs(ComponentName component, String callId, 266 String callerDisplayName) { 267 this.component = component; 268 this.callId = callId; 269 this.callerDisplayName = callerDisplayName; 270 } 271 } 272 273 /** 274 * A handler that processes messages on the main thread in the phone process. Since many 275 * of the Phone calls are not thread safe this is needed to shuttle the requests from the 276 * inbound binder threads to the main thread in the phone process. The Binder thread 277 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting 278 * on, which will be notified when the operation completes and will contain the result of the 279 * request. 280 * 281 * <p>If a MainThreadRequest object is provided in the msg.obj field, 282 * note that request.result must be set to something non-null for the calling thread to 283 * unblock. 284 */ 285 private final class MainThreadHandler extends Handler { 286 @Override 287 public void handleMessage(Message msg) { 288 MainThreadRequest request; 289 Message onCompleted; 290 AsyncResult ar; 291 UiccCard uiccCard; 292 IccAPDUArgument iccArgument; 293 294 switch (msg.what) { 295 case CMD_HANDLE_USSD_REQUEST: { 296 request = (MainThreadRequest) msg.obj; 297 final Phone phone = getPhoneFromRequest(request); 298 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument; 299 String ussdRequest = ussdObject.first; 300 ResultReceiver wrappedCallback = ussdObject.second; 301 302 if (!isUssdApiAllowed(request.subId)) { 303 // Carrier does not support use of this API, return failure. 304 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis."); 305 UssdResponse response = new UssdResponse(ussdRequest, null); 306 Bundle returnData = new Bundle(); 307 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response); 308 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData); 309 310 request.result = true; 311 synchronized (request) { 312 request.notifyAll(); 313 } 314 return; 315 } 316 317 try { 318 request.result = phone != null ? 319 phone.handleUssdRequest(ussdRequest, wrappedCallback) 320 : false; 321 } catch (CallStateException cse) { 322 request.result = false; 323 } 324 // Wake up the requesting thread 325 synchronized (request) { 326 request.notifyAll(); 327 } 328 break; 329 } 330 331 case CMD_HANDLE_PIN_MMI: { 332 request = (MainThreadRequest) msg.obj; 333 final Phone phone = getPhoneFromRequest(request); 334 request.result = phone != null ? 335 getPhoneFromRequest(request).handlePinMmi((String) request.argument) 336 : false; 337 // Wake up the requesting thread 338 synchronized (request) { 339 request.notifyAll(); 340 } 341 break; 342 } 343 344 case CMD_HANDLE_NEIGHBORING_CELL: 345 request = (MainThreadRequest) msg.obj; 346 onCompleted = obtainMessage(EVENT_NEIGHBORING_CELL_DONE, 347 request); 348 mPhone.getNeighboringCids(onCompleted, (WorkSource)request.argument); 349 break; 350 351 case EVENT_NEIGHBORING_CELL_DONE: 352 ar = (AsyncResult) msg.obj; 353 request = (MainThreadRequest) ar.userObj; 354 if (ar.exception == null && ar.result != null) { 355 request.result = ar.result; 356 } else { 357 // create an empty list to notify the waiting thread 358 request.result = new ArrayList<NeighboringCellInfo>(0); 359 } 360 // Wake up the requesting thread 361 synchronized (request) { 362 request.notifyAll(); 363 } 364 break; 365 366 case CMD_ANSWER_RINGING_CALL: 367 request = (MainThreadRequest) msg.obj; 368 int answer_subId = request.subId; 369 answerRingingCallInternal(answer_subId); 370 break; 371 372 case CMD_END_CALL: 373 request = (MainThreadRequest) msg.obj; 374 int end_subId = request.subId; 375 final boolean hungUp; 376 Phone phone = getPhone(end_subId); 377 if (phone == null) { 378 if (DBG) log("CMD_END_CALL: no phone for id: " + end_subId); 379 break; 380 } 381 int phoneType = phone.getPhoneType(); 382 if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) { 383 // CDMA: If the user presses the Power button we treat it as 384 // ending the complete call session 385 hungUp = PhoneUtils.hangupRingingAndActive(getPhone(end_subId)); 386 } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) { 387 // GSM: End the call as per the Phone state 388 hungUp = PhoneUtils.hangup(mCM); 389 } else { 390 throw new IllegalStateException("Unexpected phone type: " + phoneType); 391 } 392 if (DBG) log("CMD_END_CALL: " + (hungUp ? "hung up!" : "no call to hang up")); 393 request.result = hungUp; 394 // Wake up the requesting thread 395 synchronized (request) { 396 request.notifyAll(); 397 } 398 break; 399 400 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL: 401 request = (MainThreadRequest) msg.obj; 402 iccArgument = (IccAPDUArgument) request.argument; 403 uiccCard = getUiccCardFromRequest(request); 404 if (uiccCard == null) { 405 loge("iccTransmitApduLogicalChannel: No UICC"); 406 request.result = new IccIoResult(0x6F, 0, (byte[])null); 407 synchronized (request) { 408 request.notifyAll(); 409 } 410 } else { 411 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE, 412 request); 413 uiccCard.iccTransmitApduLogicalChannel( 414 iccArgument.channel, iccArgument.cla, iccArgument.command, 415 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data, 416 onCompleted); 417 } 418 break; 419 420 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE: 421 ar = (AsyncResult) msg.obj; 422 request = (MainThreadRequest) ar.userObj; 423 if (ar.exception == null && ar.result != null) { 424 request.result = ar.result; 425 } else { 426 request.result = new IccIoResult(0x6F, 0, (byte[])null); 427 if (ar.result == null) { 428 loge("iccTransmitApduLogicalChannel: Empty response"); 429 } else if (ar.exception instanceof CommandException) { 430 loge("iccTransmitApduLogicalChannel: CommandException: " + 431 ar.exception); 432 } else { 433 loge("iccTransmitApduLogicalChannel: Unknown exception"); 434 } 435 } 436 synchronized (request) { 437 request.notifyAll(); 438 } 439 break; 440 441 case CMD_TRANSMIT_APDU_BASIC_CHANNEL: 442 request = (MainThreadRequest) msg.obj; 443 iccArgument = (IccAPDUArgument) request.argument; 444 uiccCard = getUiccCardFromRequest(request); 445 if (uiccCard == null) { 446 loge("iccTransmitApduBasicChannel: No UICC"); 447 request.result = new IccIoResult(0x6F, 0, (byte[])null); 448 synchronized (request) { 449 request.notifyAll(); 450 } 451 } else { 452 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE, 453 request); 454 uiccCard.iccTransmitApduBasicChannel( 455 iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2, 456 iccArgument.p3, iccArgument.data, onCompleted); 457 } 458 break; 459 460 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE: 461 ar = (AsyncResult) msg.obj; 462 request = (MainThreadRequest) ar.userObj; 463 if (ar.exception == null && ar.result != null) { 464 request.result = ar.result; 465 } else { 466 request.result = new IccIoResult(0x6F, 0, (byte[])null); 467 if (ar.result == null) { 468 loge("iccTransmitApduBasicChannel: Empty response"); 469 } else if (ar.exception instanceof CommandException) { 470 loge("iccTransmitApduBasicChannel: CommandException: " + 471 ar.exception); 472 } else { 473 loge("iccTransmitApduBasicChannel: Unknown exception"); 474 } 475 } 476 synchronized (request) { 477 request.notifyAll(); 478 } 479 break; 480 481 case CMD_EXCHANGE_SIM_IO: 482 request = (MainThreadRequest) msg.obj; 483 iccArgument = (IccAPDUArgument) request.argument; 484 uiccCard = getUiccCardFromRequest(request); 485 if (uiccCard == null) { 486 loge("iccExchangeSimIO: No UICC"); 487 request.result = new IccIoResult(0x6F, 0, (byte[])null); 488 synchronized (request) { 489 request.notifyAll(); 490 } 491 } else { 492 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE, 493 request); 494 uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */ 495 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3, 496 iccArgument.data, onCompleted); 497 } 498 break; 499 500 case EVENT_EXCHANGE_SIM_IO_DONE: 501 ar = (AsyncResult) msg.obj; 502 request = (MainThreadRequest) ar.userObj; 503 if (ar.exception == null && ar.result != null) { 504 request.result = ar.result; 505 } else { 506 request.result = new IccIoResult(0x6f, 0, (byte[])null); 507 } 508 synchronized (request) { 509 request.notifyAll(); 510 } 511 break; 512 513 case CMD_SEND_ENVELOPE: 514 request = (MainThreadRequest) msg.obj; 515 uiccCard = getUiccCardFromRequest(request); 516 if (uiccCard == null) { 517 loge("sendEnvelopeWithStatus: No UICC"); 518 request.result = new IccIoResult(0x6F, 0, (byte[])null); 519 synchronized (request) { 520 request.notifyAll(); 521 } 522 } else { 523 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request); 524 uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted); 525 } 526 break; 527 528 case EVENT_SEND_ENVELOPE_DONE: 529 ar = (AsyncResult) msg.obj; 530 request = (MainThreadRequest) ar.userObj; 531 if (ar.exception == null && ar.result != null) { 532 request.result = ar.result; 533 } else { 534 request.result = new IccIoResult(0x6F, 0, (byte[])null); 535 if (ar.result == null) { 536 loge("sendEnvelopeWithStatus: Empty response"); 537 } else if (ar.exception instanceof CommandException) { 538 loge("sendEnvelopeWithStatus: CommandException: " + 539 ar.exception); 540 } else { 541 loge("sendEnvelopeWithStatus: exception:" + ar.exception); 542 } 543 } 544 synchronized (request) { 545 request.notifyAll(); 546 } 547 break; 548 549 case CMD_OPEN_CHANNEL: 550 request = (MainThreadRequest) msg.obj; 551 uiccCard = getUiccCardFromRequest(request); 552 Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument; 553 if (uiccCard == null) { 554 loge("iccOpenLogicalChannel: No UICC"); 555 request.result = new IccOpenLogicalChannelResponse(-1, 556 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null); 557 synchronized (request) { 558 request.notifyAll(); 559 } 560 } else { 561 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request); 562 uiccCard.iccOpenLogicalChannel(openChannelArgs.first, 563 openChannelArgs.second, onCompleted); 564 } 565 break; 566 567 case EVENT_OPEN_CHANNEL_DONE: 568 ar = (AsyncResult) msg.obj; 569 request = (MainThreadRequest) ar.userObj; 570 IccOpenLogicalChannelResponse openChannelResp; 571 if (ar.exception == null && ar.result != null) { 572 int[] result = (int[]) ar.result; 573 int channelId = result[0]; 574 byte[] selectResponse = null; 575 if (result.length > 1) { 576 selectResponse = new byte[result.length - 1]; 577 for (int i = 1; i < result.length; ++i) { 578 selectResponse[i - 1] = (byte) result[i]; 579 } 580 } 581 openChannelResp = new IccOpenLogicalChannelResponse(channelId, 582 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse); 583 } else { 584 if (ar.result == null) { 585 loge("iccOpenLogicalChannel: Empty response"); 586 } 587 if (ar.exception != null) { 588 loge("iccOpenLogicalChannel: Exception: " + ar.exception); 589 } 590 591 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR; 592 if (ar.exception instanceof CommandException) { 593 CommandException.Error error = 594 ((CommandException) (ar.exception)).getCommandError(); 595 if (error == CommandException.Error.MISSING_RESOURCE) { 596 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE; 597 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) { 598 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT; 599 } 600 } 601 openChannelResp = new IccOpenLogicalChannelResponse( 602 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null); 603 } 604 request.result = openChannelResp; 605 synchronized (request) { 606 request.notifyAll(); 607 } 608 break; 609 610 case CMD_CLOSE_CHANNEL: 611 request = (MainThreadRequest) msg.obj; 612 uiccCard = getUiccCardFromRequest(request); 613 if (uiccCard == null) { 614 loge("iccCloseLogicalChannel: No UICC"); 615 request.result = new IccIoResult(0x6F, 0, (byte[])null); 616 synchronized (request) { 617 request.notifyAll(); 618 } 619 } else { 620 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request); 621 uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted); 622 } 623 break; 624 625 case EVENT_CLOSE_CHANNEL_DONE: 626 handleNullReturnEvent(msg, "iccCloseLogicalChannel"); 627 break; 628 629 case CMD_NV_READ_ITEM: 630 request = (MainThreadRequest) msg.obj; 631 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request); 632 mPhone.nvReadItem((Integer) request.argument, onCompleted); 633 break; 634 635 case EVENT_NV_READ_ITEM_DONE: 636 ar = (AsyncResult) msg.obj; 637 request = (MainThreadRequest) ar.userObj; 638 if (ar.exception == null && ar.result != null) { 639 request.result = ar.result; // String 640 } else { 641 request.result = ""; 642 if (ar.result == null) { 643 loge("nvReadItem: Empty response"); 644 } else if (ar.exception instanceof CommandException) { 645 loge("nvReadItem: CommandException: " + 646 ar.exception); 647 } else { 648 loge("nvReadItem: Unknown exception"); 649 } 650 } 651 synchronized (request) { 652 request.notifyAll(); 653 } 654 break; 655 656 case CMD_NV_WRITE_ITEM: 657 request = (MainThreadRequest) msg.obj; 658 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request); 659 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument; 660 mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted); 661 break; 662 663 case EVENT_NV_WRITE_ITEM_DONE: 664 handleNullReturnEvent(msg, "nvWriteItem"); 665 break; 666 667 case CMD_NV_WRITE_CDMA_PRL: 668 request = (MainThreadRequest) msg.obj; 669 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request); 670 mPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted); 671 break; 672 673 case EVENT_NV_WRITE_CDMA_PRL_DONE: 674 handleNullReturnEvent(msg, "nvWriteCdmaPrl"); 675 break; 676 677 case CMD_NV_RESET_CONFIG: 678 request = (MainThreadRequest) msg.obj; 679 onCompleted = obtainMessage(EVENT_NV_RESET_CONFIG_DONE, request); 680 mPhone.nvResetConfig((Integer) request.argument, onCompleted); 681 break; 682 683 case EVENT_NV_RESET_CONFIG_DONE: 684 handleNullReturnEvent(msg, "nvResetConfig"); 685 break; 686 687 case CMD_GET_PREFERRED_NETWORK_TYPE: 688 request = (MainThreadRequest) msg.obj; 689 onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request); 690 getPhoneFromRequest(request).getPreferredNetworkType(onCompleted); 691 break; 692 693 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE: 694 ar = (AsyncResult) msg.obj; 695 request = (MainThreadRequest) ar.userObj; 696 if (ar.exception == null && ar.result != null) { 697 request.result = ar.result; // Integer 698 } else { 699 request.result = null; 700 if (ar.result == null) { 701 loge("getPreferredNetworkType: Empty response"); 702 } else if (ar.exception instanceof CommandException) { 703 loge("getPreferredNetworkType: CommandException: " + 704 ar.exception); 705 } else { 706 loge("getPreferredNetworkType: Unknown exception"); 707 } 708 } 709 synchronized (request) { 710 request.notifyAll(); 711 } 712 break; 713 714 case CMD_SET_PREFERRED_NETWORK_TYPE: 715 request = (MainThreadRequest) msg.obj; 716 onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request); 717 int networkType = (Integer) request.argument; 718 getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted); 719 break; 720 721 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE: 722 handleNullReturnEvent(msg, "setPreferredNetworkType"); 723 break; 724 725 case CMD_INVOKE_OEM_RIL_REQUEST_RAW: 726 request = (MainThreadRequest)msg.obj; 727 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request); 728 mPhone.invokeOemRilRequestRaw((byte[])request.argument, onCompleted); 729 break; 730 731 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE: 732 ar = (AsyncResult)msg.obj; 733 request = (MainThreadRequest)ar.userObj; 734 request.result = ar; 735 synchronized (request) { 736 request.notifyAll(); 737 } 738 break; 739 740 case CMD_SET_VOICEMAIL_NUMBER: 741 request = (MainThreadRequest) msg.obj; 742 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request); 743 Pair<String, String> tagNum = (Pair<String, String>) request.argument; 744 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second, 745 onCompleted); 746 break; 747 748 case EVENT_SET_VOICEMAIL_NUMBER_DONE: 749 handleNullReturnEvent(msg, "setVoicemailNumber"); 750 break; 751 752 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC: 753 request = (MainThreadRequest) msg.obj; 754 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE, 755 request); 756 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted); 757 break; 758 759 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE: 760 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic"); 761 break; 762 763 case CMD_PERFORM_NETWORK_SCAN: 764 request = (MainThreadRequest) msg.obj; 765 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request); 766 getPhoneFromRequest(request).getAvailableNetworks(onCompleted); 767 break; 768 769 case EVENT_PERFORM_NETWORK_SCAN_DONE: 770 ar = (AsyncResult) msg.obj; 771 request = (MainThreadRequest) ar.userObj; 772 CellNetworkScanResult cellScanResult; 773 if (ar.exception == null && ar.result != null) { 774 cellScanResult = new CellNetworkScanResult( 775 CellNetworkScanResult.STATUS_SUCCESS, 776 (List<OperatorInfo>) ar.result); 777 } else { 778 if (ar.result == null) { 779 loge("getCellNetworkScanResults: Empty response"); 780 } 781 if (ar.exception != null) { 782 loge("getCellNetworkScanResults: Exception: " + ar.exception); 783 } 784 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR; 785 if (ar.exception instanceof CommandException) { 786 CommandException.Error error = 787 ((CommandException) (ar.exception)).getCommandError(); 788 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) { 789 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE; 790 } else if (error == CommandException.Error.GENERIC_FAILURE) { 791 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE; 792 } 793 } 794 cellScanResult = new CellNetworkScanResult(errorCode, null); 795 } 796 request.result = cellScanResult; 797 synchronized (request) { 798 request.notifyAll(); 799 } 800 break; 801 802 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL: 803 request = (MainThreadRequest) msg.obj; 804 ManualNetworkSelectionArgument selArg = 805 (ManualNetworkSelectionArgument) request.argument; 806 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE, 807 request); 808 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo, 809 selArg.persistSelection, onCompleted); 810 break; 811 812 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE: 813 handleNullReturnEvent(msg, "setNetworkSelectionModeManual"); 814 break; 815 816 case CMD_GET_MODEM_ACTIVITY_INFO: 817 request = (MainThreadRequest) msg.obj; 818 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request); 819 mPhone.getModemActivityInfo(onCompleted); 820 break; 821 822 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE: 823 ar = (AsyncResult) msg.obj; 824 request = (MainThreadRequest) ar.userObj; 825 if (ar.exception == null && ar.result != null) { 826 request.result = ar.result; 827 } else { 828 if (ar.result == null) { 829 loge("queryModemActivityInfo: Empty response"); 830 } else if (ar.exception instanceof CommandException) { 831 loge("queryModemActivityInfo: CommandException: " + 832 ar.exception); 833 } else { 834 loge("queryModemActivityInfo: Unknown exception"); 835 } 836 } 837 // Result cannot be null. Return ModemActivityInfo with all fields set to 0. 838 if (request.result == null) { 839 request.result = new ModemActivityInfo(0, 0, 0, null, 0, 0); 840 } 841 synchronized (request) { 842 request.notifyAll(); 843 } 844 break; 845 846 case CMD_SET_ALLOWED_CARRIERS: 847 request = (MainThreadRequest) msg.obj; 848 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request); 849 mPhone.setAllowedCarriers( 850 (List<CarrierIdentifier>) request.argument, 851 onCompleted); 852 break; 853 854 case EVENT_SET_ALLOWED_CARRIERS_DONE: 855 ar = (AsyncResult) msg.obj; 856 request = (MainThreadRequest) ar.userObj; 857 if (ar.exception == null && ar.result != null) { 858 request.result = ar.result; 859 } else { 860 if (ar.result == null) { 861 loge("setAllowedCarriers: Empty response"); 862 } else if (ar.exception instanceof CommandException) { 863 loge("setAllowedCarriers: CommandException: " + 864 ar.exception); 865 } else { 866 loge("setAllowedCarriers: Unknown exception"); 867 } 868 } 869 // Result cannot be null. Return -1 on error. 870 if (request.result == null) { 871 request.result = new int[]{-1}; 872 } 873 synchronized (request) { 874 request.notifyAll(); 875 } 876 break; 877 878 case CMD_GET_ALLOWED_CARRIERS: 879 request = (MainThreadRequest) msg.obj; 880 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request); 881 mPhone.getAllowedCarriers(onCompleted); 882 break; 883 884 case EVENT_GET_ALLOWED_CARRIERS_DONE: 885 ar = (AsyncResult) msg.obj; 886 request = (MainThreadRequest) ar.userObj; 887 if (ar.exception == null && ar.result != null) { 888 request.result = ar.result; 889 } else { 890 if (ar.result == null) { 891 loge("getAllowedCarriers: Empty response"); 892 } else if (ar.exception instanceof CommandException) { 893 loge("getAllowedCarriers: CommandException: " + 894 ar.exception); 895 } else { 896 loge("getAllowedCarriers: Unknown exception"); 897 } 898 } 899 // Result cannot be null. Return empty list of CarrierIdentifier. 900 if (request.result == null) { 901 request.result = new ArrayList<CarrierIdentifier>(0); 902 } 903 synchronized (request) { 904 request.notifyAll(); 905 } 906 break; 907 908 case EVENT_GET_FORBIDDEN_PLMNS_DONE: 909 ar = (AsyncResult) msg.obj; 910 request = (MainThreadRequest) ar.userObj; 911 if (ar.exception == null && ar.result != null) { 912 request.result = ar.result; 913 } else { 914 request.result = new IllegalArgumentException( 915 "Failed to retrieve Forbidden Plmns"); 916 if (ar.result == null) { 917 loge("getForbiddenPlmns: Empty response"); 918 } else { 919 loge("getForbiddenPlmns: Unknown exception"); 920 } 921 } 922 synchronized (request) { 923 request.notifyAll(); 924 } 925 break; 926 927 case CMD_GET_FORBIDDEN_PLMNS: 928 request = (MainThreadRequest) msg.obj; 929 uiccCard = getUiccCardFromRequest(request); 930 if (uiccCard == null) { 931 loge("getForbiddenPlmns() UiccCard is null"); 932 request.result = new IllegalArgumentException( 933 "getForbiddenPlmns() UiccCard is null"); 934 synchronized (request) { 935 request.notifyAll(); 936 } 937 break; 938 } 939 Integer appType = (Integer) request.argument; 940 UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType); 941 if (uiccApp == null) { 942 loge("getForbiddenPlmns() no app with specified type -- " 943 + appType); 944 request.result = new IllegalArgumentException("Failed to get UICC App"); 945 synchronized (request) { 946 request.notifyAll(); 947 } 948 break; 949 } else { 950 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid() 951 + " specified type -- " + appType); 952 } 953 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request); 954 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns( 955 onCompleted); 956 break; 957 958 default: 959 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what); 960 break; 961 } 962 } 963 964 private void handleNullReturnEvent(Message msg, String command) { 965 AsyncResult ar = (AsyncResult) msg.obj; 966 MainThreadRequest request = (MainThreadRequest) ar.userObj; 967 if (ar.exception == null) { 968 request.result = true; 969 } else { 970 request.result = false; 971 if (ar.exception instanceof CommandException) { 972 loge(command + ": CommandException: " + ar.exception); 973 } else { 974 loge(command + ": Unknown exception"); 975 } 976 } 977 synchronized (request) { 978 request.notifyAll(); 979 } 980 } 981 } 982 983 /** 984 * Posts the specified command to be executed on the main thread, 985 * waits for the request to complete, and returns the result. 986 * @see #sendRequestAsync 987 */ 988 private Object sendRequest(int command, Object argument) { 989 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID); 990 } 991 992 /** 993 * Posts the specified command to be executed on the main thread, 994 * waits for the request to complete, and returns the result. 995 * @see #sendRequestAsync 996 */ 997 private Object sendRequest(int command, Object argument, Integer subId) { 998 if (Looper.myLooper() == mMainThreadHandler.getLooper()) { 999 throw new RuntimeException("This method will deadlock if called from the main thread."); 1000 } 1001 1002 MainThreadRequest request = new MainThreadRequest(argument, subId); 1003 Message msg = mMainThreadHandler.obtainMessage(command, request); 1004 msg.sendToTarget(); 1005 1006 // Wait for the request to complete 1007 synchronized (request) { 1008 while (request.result == null) { 1009 try { 1010 request.wait(); 1011 } catch (InterruptedException e) { 1012 // Do nothing, go back and wait until the request is complete 1013 } 1014 } 1015 } 1016 return request.result; 1017 } 1018 1019 /** 1020 * Asynchronous ("fire and forget") version of sendRequest(): 1021 * Posts the specified command to be executed on the main thread, and 1022 * returns immediately. 1023 * @see #sendRequest 1024 */ 1025 private void sendRequestAsync(int command) { 1026 mMainThreadHandler.sendEmptyMessage(command); 1027 } 1028 1029 /** 1030 * Same as {@link #sendRequestAsync(int)} except it takes an argument. 1031 * @see {@link #sendRequest(int,Object)} 1032 */ 1033 private void sendRequestAsync(int command, Object argument) { 1034 MainThreadRequest request = new MainThreadRequest(argument); 1035 Message msg = mMainThreadHandler.obtainMessage(command, request); 1036 msg.sendToTarget(); 1037 } 1038 1039 /** 1040 * Initialize the singleton PhoneInterfaceManager instance. 1041 * This is only done once, at startup, from PhoneApp.onCreate(). 1042 */ 1043 /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) { 1044 synchronized (PhoneInterfaceManager.class) { 1045 if (sInstance == null) { 1046 sInstance = new PhoneInterfaceManager(app, phone); 1047 } else { 1048 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance); 1049 } 1050 return sInstance; 1051 } 1052 } 1053 1054 /** Private constructor; @see init() */ 1055 private PhoneInterfaceManager(PhoneGlobals app, Phone phone) { 1056 mApp = app; 1057 mPhone = phone; 1058 mCM = PhoneGlobals.getInstance().mCM; 1059 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE); 1060 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE); 1061 mMainThreadHandler = new MainThreadHandler(); 1062 mTelephonySharedPreferences = 1063 PreferenceManager.getDefaultSharedPreferences(mPhone.getContext()); 1064 mSubscriptionController = SubscriptionController.getInstance(); 1065 mNetworkScanRequestTracker = new NetworkScanRequestTracker(); 1066 1067 publish(); 1068 } 1069 1070 private void publish() { 1071 if (DBG) log("publish: " + this); 1072 1073 ServiceManager.addService("phone", this); 1074 } 1075 1076 private Phone getPhoneFromRequest(MainThreadRequest request) { 1077 return (request.subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) 1078 ? mPhone : getPhone(request.subId); 1079 } 1080 1081 private UiccCard getUiccCardFromRequest(MainThreadRequest request) { 1082 Phone phone = getPhoneFromRequest(request); 1083 return phone == null ? null : 1084 UiccController.getInstance().getUiccCard(phone.getPhoneId()); 1085 } 1086 1087 // returns phone associated with the subId. 1088 private Phone getPhone(int subId) { 1089 return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId)); 1090 } 1091 // 1092 // Implementation of the ITelephony interface. 1093 // 1094 1095 public void dial(String number) { 1096 dialForSubscriber(getPreferredVoiceSubscription(), number); 1097 } 1098 1099 public void dialForSubscriber(int subId, String number) { 1100 if (DBG) log("dial: " + number); 1101 // No permission check needed here: This is just a wrapper around the 1102 // ACTION_DIAL intent, which is available to any app since it puts up 1103 // the UI before it does anything. 1104 1105 String url = createTelUrl(number); 1106 if (url == null) { 1107 return; 1108 } 1109 1110 // PENDING: should we just silently fail if phone is offhook or ringing? 1111 PhoneConstants.State state = mCM.getState(subId); 1112 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) { 1113 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url)); 1114 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1115 mApp.startActivity(intent); 1116 } 1117 } 1118 1119 public void call(String callingPackage, String number) { 1120 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number); 1121 } 1122 1123 public void callForSubscriber(int subId, String callingPackage, String number) { 1124 if (DBG) log("call: " + number); 1125 1126 // This is just a wrapper around the ACTION_CALL intent, but we still 1127 // need to do a permission check since we're calling startActivity() 1128 // from the context of the phone app. 1129 enforceCallPermission(); 1130 1131 if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage) 1132 != AppOpsManager.MODE_ALLOWED) { 1133 return; 1134 } 1135 1136 String url = createTelUrl(number); 1137 if (url == null) { 1138 return; 1139 } 1140 1141 boolean isValid = false; 1142 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoList(); 1143 if (slist != null) { 1144 for (SubscriptionInfo subInfoRecord : slist) { 1145 if (subInfoRecord.getSubscriptionId() == subId) { 1146 isValid = true; 1147 break; 1148 } 1149 } 1150 } 1151 if (isValid == false) { 1152 return; 1153 } 1154 1155 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url)); 1156 intent.putExtra(SUBSCRIPTION_KEY, subId); 1157 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1158 mApp.startActivity(intent); 1159 } 1160 1161 /** 1162 * End a call based on call state 1163 * @return true is a call was ended 1164 */ 1165 public boolean endCall() { 1166 return endCallForSubscriber(getDefaultSubscription()); 1167 } 1168 1169 /** 1170 * End a call based on the call state of the subId 1171 * @return true is a call was ended 1172 */ 1173 public boolean endCallForSubscriber(int subId) { 1174 enforceCallPermission(); 1175 return (Boolean) sendRequest(CMD_END_CALL, null, new Integer(subId)); 1176 } 1177 1178 public void answerRingingCall() { 1179 answerRingingCallForSubscriber(getDefaultSubscription()); 1180 } 1181 1182 public void answerRingingCallForSubscriber(int subId) { 1183 if (DBG) log("answerRingingCall..."); 1184 // TODO: there should eventually be a separate "ANSWER_PHONE" permission, 1185 // but that can probably wait till the big TelephonyManager API overhaul. 1186 // For now, protect this call with the MODIFY_PHONE_STATE permission. 1187 enforceModifyPermission(); 1188 sendRequest(CMD_ANSWER_RINGING_CALL, null, new Integer(subId)); 1189 } 1190 1191 /** 1192 * Make the actual telephony calls to implement answerRingingCall(). 1193 * This should only be called from the main thread of the Phone app. 1194 * @see #answerRingingCall 1195 * 1196 * TODO: it would be nice to return true if we answered the call, or 1197 * false if there wasn't actually a ringing incoming call, or some 1198 * other error occurred. (In other words, pass back the return value 1199 * from PhoneUtils.answerCall() or PhoneUtils.answerAndEndActive().) 1200 * But that would require calling this method via sendRequest() rather 1201 * than sendRequestAsync(), and right now we don't actually *need* that 1202 * return value, so let's just return void for now. 1203 */ 1204 private void answerRingingCallInternal(int subId) { 1205 final boolean hasRingingCall = !getPhone(subId).getRingingCall().isIdle(); 1206 if (hasRingingCall) { 1207 final boolean hasActiveCall = !getPhone(subId).getForegroundCall().isIdle(); 1208 final boolean hasHoldingCall = !getPhone(subId).getBackgroundCall().isIdle(); 1209 if (hasActiveCall && hasHoldingCall) { 1210 // Both lines are in use! 1211 // TODO: provide a flag to let the caller specify what 1212 // policy to use if both lines are in use. (The current 1213 // behavior is hardwired to "answer incoming, end ongoing", 1214 // which is how the CALL button is specced to behave.) 1215 PhoneUtils.answerAndEndActive(mCM, mCM.getFirstActiveRingingCall()); 1216 return; 1217 } else { 1218 // answerCall() will automatically hold the current active 1219 // call, if there is one. 1220 PhoneUtils.answerCall(mCM.getFirstActiveRingingCall()); 1221 return; 1222 } 1223 } else { 1224 // No call was ringing. 1225 return; 1226 } 1227 } 1228 1229 /** 1230 * This method is no longer used and can be removed once TelephonyManager stops referring to it. 1231 */ 1232 public void silenceRinger() { 1233 Log.e(LOG_TAG, "silenseRinger not supported"); 1234 } 1235 1236 @Override 1237 public boolean isOffhook(String callingPackage) { 1238 return isOffhookForSubscriber(getDefaultSubscription(), callingPackage); 1239 } 1240 1241 @Override 1242 public boolean isOffhookForSubscriber(int subId, String callingPackage) { 1243 if (!canReadPhoneState(callingPackage, "isOffhookForSubscriber")) { 1244 return false; 1245 } 1246 1247 final Phone phone = getPhone(subId); 1248 if (phone != null) { 1249 return (phone.getState() == PhoneConstants.State.OFFHOOK); 1250 } else { 1251 return false; 1252 } 1253 } 1254 1255 @Override 1256 public boolean isRinging(String callingPackage) { 1257 return (isRingingForSubscriber(getDefaultSubscription(), callingPackage)); 1258 } 1259 1260 @Override 1261 public boolean isRingingForSubscriber(int subId, String callingPackage) { 1262 if (!canReadPhoneState(callingPackage, "isRingingForSubscriber")) { 1263 return false; 1264 } 1265 1266 final Phone phone = getPhone(subId); 1267 if (phone != null) { 1268 return (phone.getState() == PhoneConstants.State.RINGING); 1269 } else { 1270 return false; 1271 } 1272 } 1273 1274 @Override 1275 public boolean isIdle(String callingPackage) { 1276 return isIdleForSubscriber(getDefaultSubscription(), callingPackage); 1277 } 1278 1279 @Override 1280 public boolean isIdleForSubscriber(int subId, String callingPackage) { 1281 if (!canReadPhoneState(callingPackage, "isIdleForSubscriber")) { 1282 return false; 1283 } 1284 1285 final Phone phone = getPhone(subId); 1286 if (phone != null) { 1287 return (phone.getState() == PhoneConstants.State.IDLE); 1288 } else { 1289 return false; 1290 } 1291 } 1292 1293 public boolean supplyPin(String pin) { 1294 return supplyPinForSubscriber(getDefaultSubscription(), pin); 1295 } 1296 1297 public boolean supplyPinForSubscriber(int subId, String pin) { 1298 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin); 1299 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false; 1300 } 1301 1302 public boolean supplyPuk(String puk, String pin) { 1303 return supplyPukForSubscriber(getDefaultSubscription(), puk, pin); 1304 } 1305 1306 public boolean supplyPukForSubscriber(int subId, String puk, String pin) { 1307 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin); 1308 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false; 1309 } 1310 1311 /** {@hide} */ 1312 public int[] supplyPinReportResult(String pin) { 1313 return supplyPinReportResultForSubscriber(getDefaultSubscription(), pin); 1314 } 1315 1316 public int[] supplyPinReportResultForSubscriber(int subId, String pin) { 1317 enforceModifyPermission(); 1318 final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard()); 1319 checkSimPin.start(); 1320 return checkSimPin.unlockSim(null, pin); 1321 } 1322 1323 /** {@hide} */ 1324 public int[] supplyPukReportResult(String puk, String pin) { 1325 return supplyPukReportResultForSubscriber(getDefaultSubscription(), puk, pin); 1326 } 1327 1328 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) { 1329 enforceModifyPermission(); 1330 final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard()); 1331 checkSimPuk.start(); 1332 return checkSimPuk.unlockSim(puk, pin); 1333 } 1334 1335 /** 1336 * Helper thread to turn async call to SimCard#supplyPin into 1337 * a synchronous one. 1338 */ 1339 private static class UnlockSim extends Thread { 1340 1341 private final IccCard mSimCard; 1342 1343 private boolean mDone = false; 1344 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE; 1345 private int mRetryCount = -1; 1346 1347 // For replies from SimCard interface 1348 private Handler mHandler; 1349 1350 // For async handler to identify request type 1351 private static final int SUPPLY_PIN_COMPLETE = 100; 1352 1353 public UnlockSim(IccCard simCard) { 1354 mSimCard = simCard; 1355 } 1356 1357 @Override 1358 public void run() { 1359 Looper.prepare(); 1360 synchronized (UnlockSim.this) { 1361 mHandler = new Handler() { 1362 @Override 1363 public void handleMessage(Message msg) { 1364 AsyncResult ar = (AsyncResult) msg.obj; 1365 switch (msg.what) { 1366 case SUPPLY_PIN_COMPLETE: 1367 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE"); 1368 synchronized (UnlockSim.this) { 1369 mRetryCount = msg.arg1; 1370 if (ar.exception != null) { 1371 if (ar.exception instanceof CommandException && 1372 ((CommandException)(ar.exception)).getCommandError() 1373 == CommandException.Error.PASSWORD_INCORRECT) { 1374 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT; 1375 } else { 1376 mResult = PhoneConstants.PIN_GENERAL_FAILURE; 1377 } 1378 } else { 1379 mResult = PhoneConstants.PIN_RESULT_SUCCESS; 1380 } 1381 mDone = true; 1382 UnlockSim.this.notifyAll(); 1383 } 1384 break; 1385 } 1386 } 1387 }; 1388 UnlockSim.this.notifyAll(); 1389 } 1390 Looper.loop(); 1391 } 1392 1393 /* 1394 * Use PIN or PUK to unlock SIM card 1395 * 1396 * If PUK is null, unlock SIM card with PIN 1397 * 1398 * If PUK is not null, unlock SIM card with PUK and set PIN code 1399 */ 1400 synchronized int[] unlockSim(String puk, String pin) { 1401 1402 while (mHandler == null) { 1403 try { 1404 wait(); 1405 } catch (InterruptedException e) { 1406 Thread.currentThread().interrupt(); 1407 } 1408 } 1409 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE); 1410 1411 if (puk == null) { 1412 mSimCard.supplyPin(pin, callback); 1413 } else { 1414 mSimCard.supplyPuk(puk, pin, callback); 1415 } 1416 1417 while (!mDone) { 1418 try { 1419 Log.d(LOG_TAG, "wait for done"); 1420 wait(); 1421 } catch (InterruptedException e) { 1422 // Restore the interrupted status 1423 Thread.currentThread().interrupt(); 1424 } 1425 } 1426 Log.d(LOG_TAG, "done"); 1427 int[] resultArray = new int[2]; 1428 resultArray[0] = mResult; 1429 resultArray[1] = mRetryCount; 1430 return resultArray; 1431 } 1432 } 1433 1434 public void updateServiceLocation() { 1435 updateServiceLocationForSubscriber(getDefaultSubscription()); 1436 1437 } 1438 1439 public void updateServiceLocationForSubscriber(int subId) { 1440 // No permission check needed here: this call is harmless, and it's 1441 // needed for the ServiceState.requestStateUpdate() call (which is 1442 // already intentionally exposed to 3rd parties.) 1443 final Phone phone = getPhone(subId); 1444 if (phone != null) { 1445 phone.updateServiceLocation(); 1446 } 1447 } 1448 1449 @Override 1450 public boolean isRadioOn(String callingPackage) { 1451 return isRadioOnForSubscriber(getDefaultSubscription(), callingPackage); 1452 } 1453 1454 @Override 1455 public boolean isRadioOnForSubscriber(int subId, String callingPackage) { 1456 if (!canReadPhoneState(callingPackage, "isRadioOnForSubscriber")) { 1457 return false; 1458 } 1459 return isRadioOnForSubscriber(subId); 1460 } 1461 1462 private boolean isRadioOnForSubscriber(int subId) { 1463 final Phone phone = getPhone(subId); 1464 if (phone != null) { 1465 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF; 1466 } else { 1467 return false; 1468 } 1469 } 1470 1471 public void toggleRadioOnOff() { 1472 toggleRadioOnOffForSubscriber(getDefaultSubscription()); 1473 1474 } 1475 1476 public void toggleRadioOnOffForSubscriber(int subId) { 1477 enforceModifyPermission(); 1478 final Phone phone = getPhone(subId); 1479 if (phone != null) { 1480 phone.setRadioPower(!isRadioOnForSubscriber(subId)); 1481 } 1482 } 1483 1484 public boolean setRadio(boolean turnOn) { 1485 return setRadioForSubscriber(getDefaultSubscription(), turnOn); 1486 } 1487 1488 public boolean setRadioForSubscriber(int subId, boolean turnOn) { 1489 enforceModifyPermission(); 1490 final Phone phone = getPhone(subId); 1491 if (phone == null) { 1492 return false; 1493 } 1494 if ((phone.getServiceState().getState() != 1495 ServiceState.STATE_POWER_OFF) != turnOn) { 1496 toggleRadioOnOffForSubscriber(subId); 1497 } 1498 return true; 1499 } 1500 1501 public boolean needMobileRadioShutdown() { 1502 /* 1503 * If any of the Radios are available, it will need to be 1504 * shutdown. So return true if any Radio is available. 1505 */ 1506 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 1507 Phone phone = PhoneFactory.getPhone(i); 1508 if (phone != null && phone.isRadioAvailable()) return true; 1509 } 1510 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown."); 1511 return false; 1512 } 1513 1514 public void shutdownMobileRadios() { 1515 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 1516 logv("Shutting down Phone " + i); 1517 shutdownRadioUsingPhoneId(i); 1518 } 1519 } 1520 1521 private void shutdownRadioUsingPhoneId(int phoneId) { 1522 enforceModifyPermission(); 1523 Phone phone = PhoneFactory.getPhone(phoneId); 1524 if (phone != null && phone.isRadioAvailable()) { 1525 phone.shutdownRadio(); 1526 } 1527 } 1528 1529 public boolean setRadioPower(boolean turnOn) { 1530 enforceModifyPermission(); 1531 final Phone defaultPhone = PhoneFactory.getDefaultPhone(); 1532 if (defaultPhone != null) { 1533 defaultPhone.setRadioPower(turnOn); 1534 return true; 1535 } else { 1536 loge("There's no default phone."); 1537 return false; 1538 } 1539 } 1540 1541 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) { 1542 enforceModifyPermission(); 1543 final Phone phone = getPhone(subId); 1544 if (phone != null) { 1545 phone.setRadioPower(turnOn); 1546 return true; 1547 } else { 1548 return false; 1549 } 1550 } 1551 1552 // FIXME: subId version needed 1553 @Override 1554 public boolean enableDataConnectivity() { 1555 enforceModifyPermission(); 1556 int subId = mSubscriptionController.getDefaultDataSubId(); 1557 final Phone phone = getPhone(subId); 1558 if (phone != null) { 1559 phone.setDataEnabled(true); 1560 return true; 1561 } else { 1562 return false; 1563 } 1564 } 1565 1566 // FIXME: subId version needed 1567 @Override 1568 public boolean disableDataConnectivity() { 1569 enforceModifyPermission(); 1570 int subId = mSubscriptionController.getDefaultDataSubId(); 1571 final Phone phone = getPhone(subId); 1572 if (phone != null) { 1573 phone.setDataEnabled(false); 1574 return true; 1575 } else { 1576 return false; 1577 } 1578 } 1579 1580 @Override 1581 public boolean isDataConnectivityPossible(int subId) { 1582 final Phone phone = getPhone(subId); 1583 if (phone != null) { 1584 return phone.isDataAllowed(); 1585 } else { 1586 return false; 1587 } 1588 } 1589 1590 public boolean handlePinMmi(String dialString) { 1591 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString); 1592 } 1593 1594 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) { 1595 enforceCallPermission(); 1596 if (!SubscriptionManager.isValidSubscriptionId(subId)) { 1597 return; 1598 } 1599 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback); 1600 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId); 1601 }; 1602 1603 public boolean handlePinMmiForSubscriber(int subId, String dialString) { 1604 enforceModifyPermission(); 1605 if (!SubscriptionManager.isValidSubscriptionId(subId)) { 1606 return false; 1607 } 1608 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId); 1609 } 1610 1611 public int getCallState() { 1612 return getCallStateForSlot(getSlotForDefaultSubscription()); 1613 } 1614 1615 public int getCallStateForSlot(int slotIndex) { 1616 Phone phone = PhoneFactory.getPhone(slotIndex); 1617 return phone == null ? TelephonyManager.CALL_STATE_IDLE : 1618 PhoneConstantConversions.convertCallState(phone.getState()); 1619 } 1620 1621 @Override 1622 public int getDataState() { 1623 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId()); 1624 if (phone != null) { 1625 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState()); 1626 } else { 1627 return PhoneConstantConversions.convertDataState(PhoneConstants.DataState.DISCONNECTED); 1628 } 1629 } 1630 1631 @Override 1632 public int getDataActivity() { 1633 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId()); 1634 if (phone != null) { 1635 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState()); 1636 } else { 1637 return TelephonyManager.DATA_ACTIVITY_NONE; 1638 } 1639 } 1640 1641 @Override 1642 public Bundle getCellLocation(String callingPackage) { 1643 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(), 1644 callingPackage, Binder.getCallingUid(), "getCellLocation")) { 1645 return null; 1646 } 1647 1648 if (DBG_LOC) log("getCellLocation: is active user"); 1649 Bundle data = new Bundle(); 1650 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId()); 1651 if (phone == null) { 1652 return null; 1653 } 1654 1655 WorkSource workSource = getWorkSource(null, Binder.getCallingUid()); 1656 phone.getCellLocation(workSource).fillInNotifierBundle(data); 1657 return data; 1658 } 1659 1660 @Override 1661 public String getNetworkCountryIsoForPhone(int phoneId) { 1662 // Reporting the correct network country is ambiguous when IWLAN could conflict with 1663 // registered cell info, so return a NULL country instead. 1664 final long identity = Binder.clearCallingIdentity(); 1665 try { 1666 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId); 1667 if (TelephonyManager.NETWORK_TYPE_IWLAN 1668 == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName())) { 1669 return ""; 1670 } 1671 } finally { 1672 Binder.restoreCallingIdentity(identity); 1673 } 1674 return TelephonyManager.getTelephonyProperty( 1675 phoneId, TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, ""); 1676 } 1677 1678 @Override 1679 public void enableLocationUpdates() { 1680 enableLocationUpdatesForSubscriber(getDefaultSubscription()); 1681 } 1682 1683 @Override 1684 public void enableLocationUpdatesForSubscriber(int subId) { 1685 mApp.enforceCallingOrSelfPermission( 1686 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 1687 final Phone phone = getPhone(subId); 1688 if (phone != null) { 1689 phone.enableLocationUpdates(); 1690 } 1691 } 1692 1693 @Override 1694 public void disableLocationUpdates() { 1695 disableLocationUpdatesForSubscriber(getDefaultSubscription()); 1696 } 1697 1698 @Override 1699 public void disableLocationUpdatesForSubscriber(int subId) { 1700 mApp.enforceCallingOrSelfPermission( 1701 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null); 1702 final Phone phone = getPhone(subId); 1703 if (phone != null) { 1704 phone.disableLocationUpdates(); 1705 } 1706 } 1707 1708 @Override 1709 @SuppressWarnings("unchecked") 1710 public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) { 1711 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(), 1712 callingPackage, Binder.getCallingUid(), "getNeighboringCellInfo")) { 1713 return null; 1714 } 1715 1716 if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(), 1717 callingPackage) != AppOpsManager.MODE_ALLOWED) { 1718 return null; 1719 } 1720 1721 if (DBG_LOC) log("getNeighboringCellInfo: is active user"); 1722 1723 ArrayList<NeighboringCellInfo> cells = null; 1724 1725 WorkSource workSource = getWorkSource(null, Binder.getCallingUid()); 1726 try { 1727 cells = (ArrayList<NeighboringCellInfo>) sendRequest( 1728 CMD_HANDLE_NEIGHBORING_CELL, workSource, 1729 SubscriptionManager.INVALID_SUBSCRIPTION_ID); 1730 } catch (RuntimeException e) { 1731 Log.e(LOG_TAG, "getNeighboringCellInfo " + e); 1732 } 1733 return cells; 1734 } 1735 1736 1737 @Override 1738 public List<CellInfo> getAllCellInfo(String callingPackage) { 1739 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(), 1740 callingPackage, Binder.getCallingUid(), "getAllCellInfo")) { 1741 return null; 1742 } 1743 1744 if (DBG_LOC) log("getAllCellInfo: is active user"); 1745 WorkSource workSource = getWorkSource(null, Binder.getCallingUid()); 1746 List<CellInfo> cellInfos = new ArrayList<CellInfo>(); 1747 for (Phone phone : PhoneFactory.getPhones()) { 1748 final List<CellInfo> info = phone.getAllCellInfo(workSource); 1749 if (info != null) cellInfos.addAll(info); 1750 } 1751 return cellInfos; 1752 } 1753 1754 @Override 1755 public void setCellInfoListRate(int rateInMillis) { 1756 enforceModifyPermission(); 1757 WorkSource workSource = getWorkSource(null, Binder.getCallingUid()); 1758 mPhone.setCellInfoListRate(rateInMillis, workSource); 1759 } 1760 1761 @Override 1762 public String getImeiForSlot(int slotIndex, String callingPackage) { 1763 if (!canReadPhoneState(callingPackage, "getImeiForSlot")) { 1764 return null; 1765 } 1766 Phone phone = PhoneFactory.getPhone(slotIndex); 1767 return phone == null ? null : phone.getImei(); 1768 } 1769 1770 @Override 1771 public String getMeidForSlot(int slotIndex, String callingPackage) { 1772 if (!canReadPhoneState(callingPackage, "getMeidForSlot")) { 1773 return null; 1774 } 1775 Phone phone = PhoneFactory.getPhone(slotIndex); 1776 return phone == null ? null : phone.getMeid(); 1777 } 1778 1779 @Override 1780 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) { 1781 if (!canReadPhoneState(callingPackage, "getDeviceSoftwareVersionForSlot")) { 1782 return null; 1783 } 1784 Phone phone = PhoneFactory.getPhone(slotIndex); 1785 return phone == null ? null : phone.getDeviceSvn(); 1786 } 1787 1788 // 1789 // Internal helper methods. 1790 // 1791 1792 /** 1793 * Make sure the caller has the MODIFY_PHONE_STATE permission. 1794 * 1795 * @throws SecurityException if the caller does not have the required permission 1796 */ 1797 private void enforceModifyPermission() { 1798 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null); 1799 } 1800 1801 /** 1802 * Make sure either system app or the caller has carrier privilege. 1803 * 1804 * @throws SecurityException if the caller does not have the required permission/privilege 1805 */ 1806 private void enforceModifyPermissionOrCarrierPrivilege(int subId) { 1807 int permission = mApp.checkCallingOrSelfPermission( 1808 android.Manifest.permission.MODIFY_PHONE_STATE); 1809 if (permission == PackageManager.PERMISSION_GRANTED) { 1810 return; 1811 } 1812 1813 log("No modify permission, check carrier privilege next."); 1814 enforceCarrierPrivilege(subId); 1815 } 1816 1817 /** 1818 * Make sure the caller has carrier privilege. 1819 * 1820 * @throws SecurityException if the caller does not have the required permission 1821 */ 1822 private void enforceCarrierPrivilege(int subId) { 1823 if (getCarrierPrivilegeStatus(subId) != 1824 TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 1825 loge("No Carrier Privilege."); 1826 throw new SecurityException("No Carrier Privilege."); 1827 } 1828 } 1829 1830 /** 1831 * Make sure the caller has the CALL_PHONE permission. 1832 * 1833 * @throws SecurityException if the caller does not have the required permission 1834 */ 1835 private void enforceCallPermission() { 1836 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null); 1837 } 1838 1839 private void enforceConnectivityInternalPermission() { 1840 mApp.enforceCallingOrSelfPermission( 1841 android.Manifest.permission.CONNECTIVITY_INTERNAL, 1842 "ConnectivityService"); 1843 } 1844 1845 private String createTelUrl(String number) { 1846 if (TextUtils.isEmpty(number)) { 1847 return null; 1848 } 1849 1850 return "tel:" + number; 1851 } 1852 1853 private static void log(String msg) { 1854 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg); 1855 } 1856 1857 private static void logv(String msg) { 1858 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg); 1859 } 1860 1861 private static void loge(String msg) { 1862 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg); 1863 } 1864 1865 @Override 1866 public int getActivePhoneType() { 1867 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription()); 1868 } 1869 1870 @Override 1871 public int getActivePhoneTypeForSlot(int slotIndex) { 1872 final Phone phone = PhoneFactory.getPhone(slotIndex); 1873 if (phone == null) { 1874 return PhoneConstants.PHONE_TYPE_NONE; 1875 } else { 1876 return phone.getPhoneType(); 1877 } 1878 } 1879 1880 /** 1881 * Returns the CDMA ERI icon index to display 1882 */ 1883 @Override 1884 public int getCdmaEriIconIndex(String callingPackage) { 1885 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage); 1886 } 1887 1888 @Override 1889 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) { 1890 if (!canReadPhoneState(callingPackage, "getCdmaEriIconIndexForSubscriber")) { 1891 return -1; 1892 } 1893 final Phone phone = getPhone(subId); 1894 if (phone != null) { 1895 return phone.getCdmaEriIconIndex(); 1896 } else { 1897 return -1; 1898 } 1899 } 1900 1901 /** 1902 * Returns the CDMA ERI icon mode, 1903 * 0 - ON 1904 * 1 - FLASHING 1905 */ 1906 @Override 1907 public int getCdmaEriIconMode(String callingPackage) { 1908 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage); 1909 } 1910 1911 @Override 1912 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) { 1913 if (!canReadPhoneState(callingPackage, "getCdmaEriIconModeForSubscriber")) { 1914 return -1; 1915 } 1916 final Phone phone = getPhone(subId); 1917 if (phone != null) { 1918 return phone.getCdmaEriIconMode(); 1919 } else { 1920 return -1; 1921 } 1922 } 1923 1924 /** 1925 * Returns the CDMA ERI text, 1926 */ 1927 @Override 1928 public String getCdmaEriText(String callingPackage) { 1929 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage); 1930 } 1931 1932 @Override 1933 public String getCdmaEriTextForSubscriber(int subId, String callingPackage) { 1934 if (!canReadPhoneState(callingPackage, "getCdmaEriIconTextForSubscriber")) { 1935 return null; 1936 } 1937 final Phone phone = getPhone(subId); 1938 if (phone != null) { 1939 return phone.getCdmaEriText(); 1940 } else { 1941 return null; 1942 } 1943 } 1944 1945 /** 1946 * Returns the CDMA MDN. 1947 */ 1948 @Override 1949 public String getCdmaMdn(int subId) { 1950 enforceModifyPermissionOrCarrierPrivilege(subId); 1951 final Phone phone = getPhone(subId); 1952 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA && phone != null) { 1953 return phone.getLine1Number(); 1954 } else { 1955 return null; 1956 } 1957 } 1958 1959 /** 1960 * Returns the CDMA MIN. 1961 */ 1962 @Override 1963 public String getCdmaMin(int subId) { 1964 enforceModifyPermissionOrCarrierPrivilege(subId); 1965 final Phone phone = getPhone(subId); 1966 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { 1967 return phone.getCdmaMin(); 1968 } else { 1969 return null; 1970 } 1971 } 1972 1973 /** 1974 * Returns true if CDMA provisioning needs to run. 1975 */ 1976 public boolean needsOtaServiceProvisioning() { 1977 return mPhone.needsOtaServiceProvisioning(); 1978 } 1979 1980 /** 1981 * Sets the voice mail number of a given subId. 1982 */ 1983 @Override 1984 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) { 1985 enforceCarrierPrivilege(subId); 1986 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER, 1987 new Pair<String, String>(alphaTag, number), new Integer(subId)); 1988 return success; 1989 } 1990 1991 @Override 1992 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) { 1993 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 1994 String systemDialer = TelecomManager.from(mPhone.getContext()).getSystemDialerPackage(); 1995 if (!TextUtils.equals(callingPackage, systemDialer)) { 1996 throw new SecurityException("caller must be system dialer"); 1997 } 1998 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId); 1999 if (phoneAccountHandle == null){ 2000 return null; 2001 } 2002 return VisualVoicemailSettingsUtil.dump(mPhone.getContext(), phoneAccountHandle); 2003 } 2004 2005 @Override 2006 public String getVisualVoicemailPackageName(String callingPackage, int subId) { 2007 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 2008 if (!canReadPhoneState(callingPackage, "getVisualVoicemailPackageName")) { 2009 return null; 2010 } 2011 return RemoteVvmTaskManager.getRemotePackage(mPhone.getContext(), subId).getPackageName(); 2012 } 2013 2014 @Override 2015 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId, 2016 VisualVoicemailSmsFilterSettings settings) { 2017 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 2018 VisualVoicemailSmsFilterConfig 2019 .enableVisualVoicemailSmsFilter(mPhone.getContext(), callingPackage, subId, 2020 settings); 2021 } 2022 2023 @Override 2024 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) { 2025 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 2026 VisualVoicemailSmsFilterConfig 2027 .disableVisualVoicemailSmsFilter(mPhone.getContext(), callingPackage, subId); 2028 } 2029 2030 @Override 2031 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings( 2032 String callingPackage, int subId) { 2033 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 2034 return VisualVoicemailSmsFilterConfig 2035 .getVisualVoicemailSmsFilterSettings(mPhone.getContext(), callingPackage, subId); 2036 } 2037 2038 @Override 2039 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) { 2040 enforceReadPrivilegedPermission(); 2041 return VisualVoicemailSmsFilterConfig 2042 .getActiveVisualVoicemailSmsFilterSettings(mPhone.getContext(), subId); 2043 } 2044 2045 @Override 2046 public void sendVisualVoicemailSmsForSubscriber(String callingPackage, int subId, 2047 String number, int port, String text, PendingIntent sentIntent) { 2048 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 2049 enforceVisualVoicemailPackage(callingPackage, subId); 2050 enforceSendSmsPermission(); 2051 // Make the calls as the phone process. 2052 final long identity = Binder.clearCallingIdentity(); 2053 try { 2054 SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId); 2055 if (port == 0) { 2056 smsManager.sendTextMessageWithSelfPermissions(number, null, text, 2057 sentIntent, null, false); 2058 } else { 2059 byte[] data = text.getBytes(StandardCharsets.UTF_8); 2060 smsManager.sendDataMessageWithSelfPermissions(number, null, 2061 (short) port, data, sentIntent, null); 2062 } 2063 } finally { 2064 Binder.restoreCallingIdentity(identity); 2065 } 2066 } 2067 /** 2068 * Sets the voice activation state of a given subId. 2069 */ 2070 @Override 2071 public void setVoiceActivationState(int subId, int activationState) { 2072 enforceModifyPermissionOrCarrierPrivilege(subId); 2073 final Phone phone = getPhone(subId); 2074 if (phone != null) { 2075 phone.setVoiceActivationState(activationState); 2076 } else { 2077 loge("setVoiceActivationState fails with invalid subId: " + subId); 2078 } 2079 } 2080 2081 /** 2082 * Sets the data activation state of a given subId. 2083 */ 2084 @Override 2085 public void setDataActivationState(int subId, int activationState) { 2086 enforceModifyPermissionOrCarrierPrivilege(subId); 2087 final Phone phone = getPhone(subId); 2088 if (phone != null) { 2089 phone.setDataActivationState(activationState); 2090 } else { 2091 loge("setVoiceActivationState fails with invalid subId: " + subId); 2092 } 2093 } 2094 2095 /** 2096 * Returns the voice activation state of a given subId. 2097 */ 2098 @Override 2099 public int getVoiceActivationState(int subId, String callingPackage) { 2100 if (!canReadPhoneState(callingPackage, "getVoiceActivationStateForSubscriber")) { 2101 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; 2102 } 2103 final Phone phone = getPhone(subId); 2104 if (phone != null) { 2105 return phone.getVoiceActivationState(); 2106 } else { 2107 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; 2108 } 2109 } 2110 2111 /** 2112 * Returns the data activation state of a given subId. 2113 */ 2114 @Override 2115 public int getDataActivationState(int subId, String callingPackage) { 2116 if (!canReadPhoneState(callingPackage, "getDataActivationStateForSubscriber")) { 2117 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; 2118 } 2119 final Phone phone = getPhone(subId); 2120 if (phone != null) { 2121 return phone.getDataActivationState(); 2122 } else { 2123 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN; 2124 } 2125 } 2126 2127 /** 2128 * Returns the unread count of voicemails 2129 */ 2130 public int getVoiceMessageCount() { 2131 return getVoiceMessageCountForSubscriber(getDefaultSubscription()); 2132 } 2133 2134 /** 2135 * Returns the unread count of voicemails for a subId 2136 */ 2137 @Override 2138 public int getVoiceMessageCountForSubscriber( int subId) { 2139 final Phone phone = getPhone(subId); 2140 if (phone != null) { 2141 return phone.getVoiceMessageCount(); 2142 } else { 2143 return 0; 2144 } 2145 } 2146 2147 /** 2148 * returns true, if the device is in a state where both voice and data 2149 * are supported simultaneously. This can change based on location or network condition. 2150 */ 2151 @Override 2152 public boolean isConcurrentVoiceAndDataAllowed(int subId) { 2153 final Phone phone = getPhone(subId); 2154 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed()); 2155 } 2156 2157 /** 2158 * Send the dialer code if called from the current default dialer or the caller has 2159 * carrier privilege. 2160 * @param inputCode The dialer code to send 2161 */ 2162 @Override 2163 public void sendDialerSpecialCode(String callingPackage, String inputCode) { 2164 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 2165 String defaultDialer = TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage(); 2166 if (!TextUtils.equals(callingPackage, defaultDialer)) { 2167 enforceCarrierPrivilege(getDefaultSubscription()); 2168 } 2169 mPhone.sendDialerSpecialCode(inputCode); 2170 } 2171 2172 /** 2173 * Returns the data network type. 2174 * Legacy call, permission-free. 2175 * 2176 * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}. 2177 */ 2178 @Override 2179 public int getNetworkType() { 2180 final Phone phone = getPhone(getDefaultSubscription()); 2181 if (phone != null) { 2182 return phone.getServiceState().getDataNetworkType(); 2183 } else { 2184 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 2185 } 2186 } 2187 2188 /** 2189 * Returns the network type for a subId 2190 */ 2191 @Override 2192 public int getNetworkTypeForSubscriber(int subId, String callingPackage) { 2193 if (!canReadPhoneState(callingPackage, "getNetworkTypeForSubscriber")) { 2194 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 2195 } 2196 2197 final Phone phone = getPhone(subId); 2198 if (phone != null) { 2199 return phone.getServiceState().getDataNetworkType(); 2200 } else { 2201 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 2202 } 2203 } 2204 2205 /** 2206 * Returns the data network type 2207 */ 2208 @Override 2209 public int getDataNetworkType(String callingPackage) { 2210 return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage); 2211 } 2212 2213 /** 2214 * Returns the data network type for a subId 2215 */ 2216 @Override 2217 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) { 2218 if (!canReadPhoneState(callingPackage, "getDataNetworkTypeForSubscriber")) { 2219 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 2220 } 2221 2222 final Phone phone = getPhone(subId); 2223 if (phone != null) { 2224 return phone.getServiceState().getDataNetworkType(); 2225 } else { 2226 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 2227 } 2228 } 2229 2230 /** 2231 * Returns the Voice network type for a subId 2232 */ 2233 @Override 2234 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) { 2235 if (!canReadPhoneState(callingPackage, "getDataNetworkTypeForSubscriber")) { 2236 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 2237 } 2238 2239 final Phone phone = getPhone(subId); 2240 if (phone != null) { 2241 return phone.getServiceState().getVoiceNetworkType(); 2242 } else { 2243 return TelephonyManager.NETWORK_TYPE_UNKNOWN; 2244 } 2245 } 2246 2247 /** 2248 * @return true if a ICC card is present 2249 */ 2250 public boolean hasIccCard() { 2251 // FIXME Make changes to pass defaultSimId of type int 2252 return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex( 2253 getDefaultSubscription())); 2254 } 2255 2256 /** 2257 * @return true if a ICC card is present for a slotIndex 2258 */ 2259 @Override 2260 public boolean hasIccCardUsingSlotIndex(int slotIndex) { 2261 final Phone phone = PhoneFactory.getPhone(slotIndex); 2262 if (phone != null) { 2263 return phone.getIccCard().hasIccCard(); 2264 } else { 2265 return false; 2266 } 2267 } 2268 2269 /** 2270 * Return if the current radio is LTE on CDMA. This 2271 * is a tri-state return value as for a period of time 2272 * the mode may be unknown. 2273 * 2274 * @param callingPackage the name of the package making the call. 2275 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE} 2276 * or {@link Phone#LTE_ON_CDMA_TRUE} 2277 */ 2278 @Override 2279 public int getLteOnCdmaMode(String callingPackage) { 2280 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage); 2281 } 2282 2283 @Override 2284 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) { 2285 if (!canReadPhoneState(callingPackage, "getLteOnCdmaModeForSubscriber")) { 2286 return PhoneConstants.LTE_ON_CDMA_UNKNOWN; 2287 } 2288 2289 final Phone phone = getPhone(subId); 2290 if (phone == null) { 2291 return PhoneConstants.LTE_ON_CDMA_UNKNOWN; 2292 } else { 2293 return phone.getLteOnCdmaMode(); 2294 } 2295 } 2296 2297 public void setPhone(Phone phone) { 2298 mPhone = phone; 2299 } 2300 2301 /** 2302 * {@hide} 2303 * Returns Default subId, 0 in the case of single standby. 2304 */ 2305 private int getDefaultSubscription() { 2306 return mSubscriptionController.getDefaultSubId(); 2307 } 2308 2309 private int getSlotForDefaultSubscription() { 2310 return mSubscriptionController.getPhoneId(getDefaultSubscription()); 2311 } 2312 2313 private int getPreferredVoiceSubscription() { 2314 return mSubscriptionController.getDefaultVoiceSubId(); 2315 } 2316 2317 /** 2318 * @see android.telephony.TelephonyManager.WifiCallingChoices 2319 */ 2320 public int getWhenToMakeWifiCalls() { 2321 return Settings.System.getInt(mPhone.getContext().getContentResolver(), 2322 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, getWhenToMakeWifiCallsDefaultPreference()); 2323 } 2324 2325 /** 2326 * @see android.telephony.TelephonyManager.WifiCallingChoices 2327 */ 2328 public void setWhenToMakeWifiCalls(int preference) { 2329 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference); 2330 Settings.System.putInt(mPhone.getContext().getContentResolver(), 2331 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference); 2332 } 2333 2334 private static int getWhenToMakeWifiCallsDefaultPreference() { 2335 // TODO: Use a build property to choose this value. 2336 return TelephonyManager.WifiCallingChoices.ALWAYS_USE; 2337 } 2338 2339 @Override 2340 public IccOpenLogicalChannelResponse iccOpenLogicalChannel( 2341 int subId, String callingPackage, String aid, int p2) { 2342 enforceModifyPermissionOrCarrierPrivilege(subId); 2343 2344 if (TextUtils.equals(ISDR_AID, aid)) { 2345 // Only allows LPA to open logical channel to ISD-R. 2346 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 2347 ComponentInfo bestComponent = 2348 EuiccConnector.findBestComponent(mPhone.getContext().getPackageManager()); 2349 if (bestComponent == null 2350 || !TextUtils.equals(callingPackage, bestComponent.packageName)) { 2351 loge("The calling package is not allowed to access ISD-R."); 2352 throw new SecurityException("The calling package is not allowed to access ISD-R."); 2353 } 2354 } 2355 2356 if (DBG) log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2); 2357 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse)sendRequest( 2358 CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), subId); 2359 if (DBG) log("iccOpenLogicalChannel: " + response); 2360 return response; 2361 } 2362 2363 @Override 2364 public boolean iccCloseLogicalChannel(int subId, int channel) { 2365 enforceModifyPermissionOrCarrierPrivilege(subId); 2366 2367 if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel); 2368 if (channel < 0) { 2369 return false; 2370 } 2371 Boolean success = (Boolean)sendRequest(CMD_CLOSE_CHANNEL, channel, subId); 2372 if (DBG) log("iccCloseLogicalChannel: " + success); 2373 return success; 2374 } 2375 2376 @Override 2377 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla, 2378 int command, int p1, int p2, int p3, String data) { 2379 enforceModifyPermissionOrCarrierPrivilege(subId); 2380 2381 if (DBG) { 2382 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel + 2383 " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + 2384 " data=" + data); 2385 } 2386 2387 if (channel < 0) { 2388 return ""; 2389 } 2390 2391 IccIoResult response = (IccIoResult)sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL, 2392 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), subId); 2393 if (DBG) log("iccTransmitApduLogicalChannel: " + response); 2394 2395 // Append the returned status code to the end of the response payload. 2396 String s = Integer.toHexString( 2397 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 2398 if (response.payload != null) { 2399 s = IccUtils.bytesToHexString(response.payload) + s; 2400 } 2401 return s; 2402 } 2403 2404 @Override 2405 public String iccTransmitApduBasicChannel(int subId, int cla, int command, int p1, int p2, 2406 int p3, String data) { 2407 enforceModifyPermissionOrCarrierPrivilege(subId); 2408 2409 if (DBG) { 2410 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd=" + command 2411 + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data); 2412 } 2413 2414 IccIoResult response = (IccIoResult)sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL, 2415 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), subId); 2416 if (DBG) log("iccTransmitApduBasicChannel: " + response); 2417 2418 // Append the returned status code to the end of the response payload. 2419 String s = Integer.toHexString( 2420 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 2421 if (response.payload != null) { 2422 s = IccUtils.bytesToHexString(response.payload) + s; 2423 } 2424 return s; 2425 } 2426 2427 @Override 2428 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3, 2429 String filePath) { 2430 enforceModifyPermissionOrCarrierPrivilege(subId); 2431 2432 if (DBG) { 2433 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " " + 2434 p1 + " " + p2 + " " + p3 + ":" + filePath); 2435 } 2436 2437 IccIoResult response = 2438 (IccIoResult)sendRequest(CMD_EXCHANGE_SIM_IO, 2439 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath), 2440 subId); 2441 2442 if (DBG) { 2443 log("Exchange SIM_IO [R]" + response); 2444 } 2445 2446 byte[] result = null; 2447 int length = 2; 2448 if (response.payload != null) { 2449 length = 2 + response.payload.length; 2450 result = new byte[length]; 2451 System.arraycopy(response.payload, 0, result, 0, response.payload.length); 2452 } else { 2453 result = new byte[length]; 2454 } 2455 2456 result[length - 1] = (byte) response.sw2; 2457 result[length - 2] = (byte) response.sw1; 2458 return result; 2459 } 2460 2461 /** 2462 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM) 2463 * on a particular subscription 2464 */ 2465 public String[] getForbiddenPlmns(int subId, int appType) { 2466 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE, 2467 "Requires READ_PHONE_STATE"); 2468 if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) { 2469 loge("getForbiddenPlmnList(): App Type must be USIM or SIM"); 2470 return null; 2471 } 2472 Object response = sendRequest( 2473 CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId); 2474 if (response instanceof String[]) { 2475 return (String[]) response; 2476 } 2477 // Response is an Exception of some kind, which is signalled to the user as a NULL retval 2478 return null; 2479 } 2480 2481 @Override 2482 public String sendEnvelopeWithStatus(int subId, String content) { 2483 enforceModifyPermissionOrCarrierPrivilege(subId); 2484 2485 IccIoResult response = (IccIoResult)sendRequest(CMD_SEND_ENVELOPE, content, subId); 2486 if (response.payload == null) { 2487 return ""; 2488 } 2489 2490 // Append the returned status code to the end of the response payload. 2491 String s = Integer.toHexString( 2492 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1); 2493 s = IccUtils.bytesToHexString(response.payload) + s; 2494 return s; 2495 } 2496 2497 /** 2498 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems} 2499 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators. 2500 * 2501 * @param itemID the ID of the item to read 2502 * @return the NV item as a String, or null on error. 2503 */ 2504 @Override 2505 public String nvReadItem(int itemID) { 2506 enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription()); 2507 if (DBG) log("nvReadItem: item " + itemID); 2508 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID); 2509 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"'); 2510 return value; 2511 } 2512 2513 /** 2514 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems} 2515 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators. 2516 * 2517 * @param itemID the ID of the item to read 2518 * @param itemValue the value to write, as a String 2519 * @return true on success; false on any failure 2520 */ 2521 @Override 2522 public boolean nvWriteItem(int itemID, String itemValue) { 2523 enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription()); 2524 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"'); 2525 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM, 2526 new Pair<Integer, String>(itemID, itemValue)); 2527 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail")); 2528 return success; 2529 } 2530 2531 /** 2532 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage. 2533 * Used for device configuration by some CDMA operators. 2534 * 2535 * @param preferredRoamingList byte array containing the new PRL 2536 * @return true on success; false on any failure 2537 */ 2538 @Override 2539 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) { 2540 enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription()); 2541 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList)); 2542 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList); 2543 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail")); 2544 return success; 2545 } 2546 2547 /** 2548 * Perform the specified type of NV config reset. 2549 * Used for device configuration by some CDMA operators. 2550 * 2551 * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset) 2552 * @return true on success; false on any failure 2553 */ 2554 @Override 2555 public boolean nvResetConfig(int resetType) { 2556 enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription()); 2557 if (DBG) log("nvResetConfig: type " + resetType); 2558 Boolean success = (Boolean) sendRequest(CMD_NV_RESET_CONFIG, resetType); 2559 if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail")); 2560 return success; 2561 } 2562 2563 /** 2564 * {@hide} 2565 * Returns Default sim, 0 in the case of single standby. 2566 */ 2567 public int getDefaultSim() { 2568 //TODO Need to get it from Telephony Devcontroller 2569 return 0; 2570 } 2571 2572 public String[] getPcscfAddress(String apnType, String callingPackage) { 2573 if (!canReadPhoneState(callingPackage, "getPcscfAddress")) { 2574 return new String[0]; 2575 } 2576 2577 2578 return mPhone.getPcscfAddress(apnType); 2579 } 2580 2581 /** 2582 * Returns the {@link IImsServiceController} that corresponds to the given slot Id and IMS 2583 * feature or {@link null} if the service is not available. If an ImsServiceController is 2584 * available, the {@link IImsServiceFeatureListener} callback is registered as a listener for 2585 * feature updates. 2586 */ 2587 public IImsServiceController getImsServiceControllerAndListen(int slotIndex, int feature, 2588 IImsServiceFeatureListener callback) { 2589 enforceModifyPermission(); 2590 return PhoneFactory.getImsResolver().getImsServiceControllerAndListen(slotIndex, feature, 2591 callback); 2592 } 2593 2594 public void setImsRegistrationState(boolean registered) { 2595 enforceModifyPermission(); 2596 mPhone.setImsRegistrationState(registered); 2597 } 2598 2599 /** 2600 * Set the network selection mode to automatic. 2601 * 2602 */ 2603 @Override 2604 public void setNetworkSelectionModeAutomatic(int subId) { 2605 enforceModifyPermissionOrCarrierPrivilege(subId); 2606 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId); 2607 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId); 2608 } 2609 2610 /** 2611 * Set the network selection mode to manual with the selected carrier. 2612 */ 2613 @Override 2614 public boolean setNetworkSelectionModeManual(int subId, OperatorInfo operator, 2615 boolean persistSelection) { 2616 enforceModifyPermissionOrCarrierPrivilege(subId); 2617 if (DBG) log("setNetworkSelectionModeManual: subId:" + subId + " operator:" + operator); 2618 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operator, 2619 persistSelection); 2620 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId); 2621 } 2622 2623 /** 2624 * Scans for available networks. 2625 */ 2626 @Override 2627 public CellNetworkScanResult getCellNetworkScanResults(int subId) { 2628 enforceModifyPermissionOrCarrierPrivilege(subId); 2629 if (DBG) log("getCellNetworkScanResults: subId " + subId); 2630 CellNetworkScanResult result = (CellNetworkScanResult) sendRequest( 2631 CMD_PERFORM_NETWORK_SCAN, null, subId); 2632 return result; 2633 } 2634 2635 /** 2636 * Starts a new network scan and returns the id of this scan. 2637 * 2638 * @param subId id of the subscription 2639 * @param request contains the radio access networks with bands/channels to scan 2640 * @param messenger callback messenger for scan results or errors 2641 * @param binder for the purpose of auto clean when the user thread crashes 2642 * @return the id of the requested scan which can be used to stop the scan. 2643 */ 2644 @Override 2645 public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger, 2646 IBinder binder) { 2647 enforceModifyPermissionOrCarrierPrivilege(subId); 2648 return mNetworkScanRequestTracker.startNetworkScan( 2649 request, messenger, binder, getPhone(subId)); 2650 } 2651 2652 /** 2653 * Stops an existing network scan with the given scanId. 2654 * 2655 * @param subId id of the subscription 2656 * @param scanId id of the scan that needs to be stopped 2657 */ 2658 @Override 2659 public void stopNetworkScan(int subId, int scanId) { 2660 enforceModifyPermissionOrCarrierPrivilege(subId); 2661 mNetworkScanRequestTracker.stopNetworkScan(scanId); 2662 } 2663 2664 /** 2665 * Get the calculated preferred network type. 2666 * Used for debugging incorrect network type. 2667 * 2668 * @return the preferred network type, defined in RILConstants.java. 2669 */ 2670 @Override 2671 public int getCalculatedPreferredNetworkType(String callingPackage) { 2672 if (!canReadPhoneState(callingPackage, "getCalculatedPreferredNetworkType")) { 2673 return RILConstants.PREFERRED_NETWORK_MODE; 2674 } 2675 2676 return PhoneFactory.calculatePreferredNetworkType(mPhone.getContext(), 0); // wink FIXME: need to get SubId from somewhere. 2677 } 2678 2679 /** 2680 * Get the preferred network type. 2681 * Used for device configuration by some CDMA operators. 2682 * 2683 * @return the preferred network type, defined in RILConstants.java. 2684 */ 2685 @Override 2686 public int getPreferredNetworkType(int subId) { 2687 enforceModifyPermissionOrCarrierPrivilege(subId); 2688 if (DBG) log("getPreferredNetworkType"); 2689 int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId); 2690 int networkType = (result != null ? result[0] : -1); 2691 if (DBG) log("getPreferredNetworkType: " + networkType); 2692 return networkType; 2693 } 2694 2695 /** 2696 * Set the preferred network type. 2697 * Used for device configuration by some CDMA operators. 2698 * 2699 * @param networkType the preferred network type, defined in RILConstants.java. 2700 * @return true on success; false on any failure. 2701 */ 2702 @Override 2703 public boolean setPreferredNetworkType(int subId, int networkType) { 2704 enforceModifyPermissionOrCarrierPrivilege(subId); 2705 if (DBG) log("setPreferredNetworkType: subId " + subId + " type " + networkType); 2706 Boolean success = (Boolean) sendRequest(CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId); 2707 if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail")); 2708 if (success) { 2709 Settings.Global.putInt(mPhone.getContext().getContentResolver(), 2710 Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType); 2711 } 2712 return success; 2713 } 2714 2715 /** 2716 * Check TETHER_DUN_REQUIRED and TETHER_DUN_APN settings, net.tethering.noprovisioning 2717 * SystemProperty, and config_tether_apndata to decide whether DUN APN is required for 2718 * tethering. 2719 * 2720 * @return 0: Not required. 1: required. 2: Not set. 2721 * @hide 2722 */ 2723 @Override 2724 public int getTetherApnRequired() { 2725 enforceModifyPermission(); 2726 int dunRequired = Settings.Global.getInt(mPhone.getContext().getContentResolver(), 2727 Settings.Global.TETHER_DUN_REQUIRED, 2); 2728 // If not set, check net.tethering.noprovisioning, TETHER_DUN_APN setting and 2729 // config_tether_apndata. 2730 if (dunRequired == 2 && mPhone.hasMatchedTetherApnSetting()) { 2731 dunRequired = 1; 2732 } 2733 return dunRequired; 2734 } 2735 2736 /** 2737 * Set mobile data enabled 2738 * Used by the user through settings etc to turn on/off mobile data 2739 * 2740 * @param enable {@code true} turn turn data on, else {@code false} 2741 */ 2742 @Override 2743 public void setDataEnabled(int subId, boolean enable) { 2744 enforceModifyPermissionOrCarrierPrivilege(subId); 2745 int phoneId = mSubscriptionController.getPhoneId(subId); 2746 if (DBG) log("getDataEnabled: subId=" + subId + " phoneId=" + phoneId); 2747 Phone phone = PhoneFactory.getPhone(phoneId); 2748 if (phone != null) { 2749 if (DBG) log("setDataEnabled: subId=" + subId + " enable=" + enable); 2750 phone.setDataEnabled(enable); 2751 } else { 2752 loge("setDataEnabled: no phone for subId=" + subId); 2753 } 2754 } 2755 2756 /** 2757 * Get whether mobile data is enabled. 2758 * 2759 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges. 2760 * 2761 * @return {@code true} if data is enabled else {@code false} 2762 */ 2763 @Override 2764 public boolean getDataEnabled(int subId) { 2765 try { 2766 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE, 2767 null); 2768 } catch (Exception e) { 2769 enforceModifyPermissionOrCarrierPrivilege(subId); 2770 } 2771 int phoneId = mSubscriptionController.getPhoneId(subId); 2772 if (DBG) log("getDataEnabled: subId=" + subId + " phoneId=" + phoneId); 2773 Phone phone = PhoneFactory.getPhone(phoneId); 2774 if (phone != null) { 2775 boolean retVal = phone.getDataEnabled(); 2776 if (DBG) log("getDataEnabled: subId=" + subId + " retVal=" + retVal); 2777 return retVal; 2778 } else { 2779 if (DBG) loge("getDataEnabled: no phone subId=" + subId + " retVal=false"); 2780 return false; 2781 } 2782 } 2783 2784 @Override 2785 public int getCarrierPrivilegeStatus(int subId) { 2786 final Phone phone = getPhone(subId); 2787 if (phone == null) { 2788 loge("getCarrierPrivilegeStatus: Invalid subId"); 2789 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 2790 } 2791 UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId()); 2792 if (card == null) { 2793 loge("getCarrierPrivilegeStatus: No UICC"); 2794 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 2795 } 2796 return card.getCarrierPrivilegeStatusForCurrentTransaction( 2797 phone.getContext().getPackageManager()); 2798 } 2799 2800 @Override 2801 public int checkCarrierPrivilegesForPackage(String pkgName) { 2802 if (TextUtils.isEmpty(pkgName)) 2803 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 2804 UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId()); 2805 if (card == null) { 2806 loge("checkCarrierPrivilegesForPackage: No UICC"); 2807 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 2808 } 2809 return card.getCarrierPrivilegeStatus(mPhone.getContext().getPackageManager(), pkgName); 2810 } 2811 2812 @Override 2813 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) { 2814 if (TextUtils.isEmpty(pkgName)) 2815 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; 2816 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED; 2817 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 2818 UiccCard card = UiccController.getInstance().getUiccCard(i); 2819 if (card == null) { 2820 // No UICC in that slot. 2821 continue; 2822 } 2823 2824 result = card.getCarrierPrivilegeStatus( 2825 mPhone.getContext().getPackageManager(), pkgName); 2826 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 2827 break; 2828 } 2829 } 2830 2831 return result; 2832 } 2833 2834 @Override 2835 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) { 2836 if (!SubscriptionManager.isValidPhoneId(phoneId)) { 2837 loge("phoneId " + phoneId + " is not valid."); 2838 return null; 2839 } 2840 UiccCard card = UiccController.getInstance().getUiccCard(phoneId); 2841 if (card == null) { 2842 loge("getCarrierPackageNamesForIntent: No UICC"); 2843 return null ; 2844 } 2845 return card.getCarrierPackageNamesForIntent( 2846 mPhone.getContext().getPackageManager(), intent); 2847 } 2848 2849 @Override 2850 public List<String> getPackagesWithCarrierPrivileges() { 2851 PackageManager pm = mPhone.getContext().getPackageManager(); 2852 List<String> privilegedPackages = new ArrayList<>(); 2853 List<PackageInfo> packages = null; 2854 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) { 2855 UiccCard card = UiccController.getInstance().getUiccCard(i); 2856 if (card == null) { 2857 // No UICC in that slot. 2858 continue; 2859 } 2860 if (card.hasCarrierPrivilegeRules()) { 2861 if (packages == null) { 2862 // Only check packages in user 0 for now 2863 packages = pm.getInstalledPackagesAsUser( 2864 PackageManager.MATCH_DISABLED_COMPONENTS 2865 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS 2866 | PackageManager.GET_SIGNATURES, UserHandle.USER_SYSTEM); 2867 } 2868 for (int p = packages.size() - 1; p >= 0; p--) { 2869 PackageInfo pkgInfo = packages.get(p); 2870 if (pkgInfo != null && pkgInfo.packageName != null 2871 && card.getCarrierPrivilegeStatus(pkgInfo) 2872 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { 2873 privilegedPackages.add(pkgInfo.packageName); 2874 } 2875 } 2876 } 2877 } 2878 return privilegedPackages; 2879 } 2880 2881 private String getIccId(int subId) { 2882 final Phone phone = getPhone(subId); 2883 UiccCard card = phone == null ? null : phone.getUiccCard(); 2884 if (card == null) { 2885 loge("getIccId: No UICC"); 2886 return null; 2887 } 2888 String iccId = card.getIccId(); 2889 if (TextUtils.isEmpty(iccId)) { 2890 loge("getIccId: ICC ID is null or empty."); 2891 return null; 2892 } 2893 return iccId; 2894 } 2895 2896 @Override 2897 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, 2898 String number) { 2899 enforceCarrierPrivilege(subId); 2900 2901 final String iccId = getIccId(subId); 2902 final Phone phone = getPhone(subId); 2903 if (phone == null) { 2904 return false; 2905 } 2906 final String subscriberId = phone.getSubscriberId(); 2907 2908 if (DBG_MERGE) { 2909 Slog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId=" 2910 + subscriberId + " to " + number); 2911 } 2912 2913 if (TextUtils.isEmpty(iccId)) { 2914 return false; 2915 } 2916 2917 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit(); 2918 2919 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId; 2920 if (alphaTag == null) { 2921 editor.remove(alphaTagPrefKey); 2922 } else { 2923 editor.putString(alphaTagPrefKey, alphaTag); 2924 } 2925 2926 // Record both the line number and IMSI for this ICCID, since we need to 2927 // track all merged IMSIs based on line number 2928 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId; 2929 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId; 2930 if (number == null) { 2931 editor.remove(numberPrefKey); 2932 editor.remove(subscriberPrefKey); 2933 } else { 2934 editor.putString(numberPrefKey, number); 2935 editor.putString(subscriberPrefKey, subscriberId); 2936 } 2937 2938 editor.commit(); 2939 return true; 2940 } 2941 2942 @Override 2943 public String getLine1NumberForDisplay(int subId, String callingPackage) { 2944 // This is open to apps with WRITE_SMS. 2945 if (!canReadPhoneNumber(callingPackage, "getLine1NumberForDisplay")) { 2946 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission"); 2947 return null; 2948 } 2949 2950 String iccId = getIccId(subId); 2951 if (iccId != null) { 2952 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId; 2953 if (DBG_MERGE) { 2954 log("getLine1NumberForDisplay returning " + 2955 mTelephonySharedPreferences.getString(numberPrefKey, null)); 2956 } 2957 return mTelephonySharedPreferences.getString(numberPrefKey, null); 2958 } 2959 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null"); 2960 return null; 2961 } 2962 2963 @Override 2964 public String getLine1AlphaTagForDisplay(int subId, String callingPackage) { 2965 if (!canReadPhoneState(callingPackage, "getLine1AlphaTagForDisplay")) { 2966 return null; 2967 } 2968 2969 String iccId = getIccId(subId); 2970 if (iccId != null) { 2971 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId; 2972 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null); 2973 } 2974 return null; 2975 } 2976 2977 @Override 2978 public String[] getMergedSubscriberIds(String callingPackage) { 2979 if (!canReadPhoneState(callingPackage, "getMergedSubscriberIds")) { 2980 return null; 2981 } 2982 final Context context = mPhone.getContext(); 2983 final TelephonyManager tele = TelephonyManager.from(context); 2984 final SubscriptionManager sub = SubscriptionManager.from(context); 2985 2986 // Figure out what subscribers are currently active 2987 final ArraySet<String> activeSubscriberIds = new ArraySet<>(); 2988 // Clear calling identity, when calling TelephonyManager, because callerUid must be 2989 // the process, where TelephonyManager was instantiated. Otherwise AppOps check will fail. 2990 final long identity = Binder.clearCallingIdentity(); 2991 try { 2992 final int[] subIds = sub.getActiveSubscriptionIdList(); 2993 for (int subId : subIds) { 2994 activeSubscriberIds.add(tele.getSubscriberId(subId)); 2995 } 2996 } finally { 2997 Binder.restoreCallingIdentity(identity); 2998 } 2999 3000 // First pass, find a number override for an active subscriber 3001 String mergeNumber = null; 3002 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll(); 3003 for (String key : prefs.keySet()) { 3004 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) { 3005 final String subscriberId = (String) prefs.get(key); 3006 if (activeSubscriberIds.contains(subscriberId)) { 3007 final String iccId = key.substring(PREF_CARRIERS_SUBSCRIBER_PREFIX.length()); 3008 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId; 3009 mergeNumber = (String) prefs.get(numberKey); 3010 if (DBG_MERGE) { 3011 Slog.d(LOG_TAG, "Found line number " + mergeNumber 3012 + " for active subscriber " + subscriberId); 3013 } 3014 if (!TextUtils.isEmpty(mergeNumber)) { 3015 break; 3016 } 3017 } 3018 } 3019 } 3020 3021 // Shortcut when no active merged subscribers 3022 if (TextUtils.isEmpty(mergeNumber)) { 3023 return null; 3024 } 3025 3026 // Second pass, find all subscribers under that line override 3027 final ArraySet<String> result = new ArraySet<>(); 3028 for (String key : prefs.keySet()) { 3029 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) { 3030 final String number = (String) prefs.get(key); 3031 if (mergeNumber.equals(number)) { 3032 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length()); 3033 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId; 3034 final String subscriberId = (String) prefs.get(subscriberKey); 3035 if (!TextUtils.isEmpty(subscriberId)) { 3036 result.add(subscriberId); 3037 } 3038 } 3039 } 3040 } 3041 3042 final String[] resultArray = result.toArray(new String[result.size()]); 3043 Arrays.sort(resultArray); 3044 if (DBG_MERGE) { 3045 Slog.d(LOG_TAG, "Found subscribers " + Arrays.toString(resultArray) + " after merge"); 3046 } 3047 return resultArray; 3048 } 3049 3050 @Override 3051 public boolean setOperatorBrandOverride(int subId, String brand) { 3052 enforceCarrierPrivilege(subId); 3053 final Phone phone = getPhone(subId); 3054 return phone == null ? false : phone.setOperatorBrandOverride(brand); 3055 } 3056 3057 @Override 3058 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList, 3059 List<String> gsmNonRoamingList, List<String> cdmaRoamingList, 3060 List<String> cdmaNonRoamingList) { 3061 enforceCarrierPrivilege(subId); 3062 final Phone phone = getPhone(subId); 3063 if (phone == null) { 3064 return false; 3065 } 3066 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList, 3067 cdmaNonRoamingList); 3068 } 3069 3070 @Override 3071 @Deprecated 3072 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) { 3073 enforceModifyPermission(); 3074 3075 int returnValue = 0; 3076 try { 3077 AsyncResult result = (AsyncResult)sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq); 3078 if(result.exception == null) { 3079 if (result.result != null) { 3080 byte[] responseData = (byte[])(result.result); 3081 if(responseData.length > oemResp.length) { 3082 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " + 3083 responseData.length + "bytes. Buffer Size is " + 3084 oemResp.length + "bytes."); 3085 } 3086 System.arraycopy(responseData, 0, oemResp, 0, responseData.length); 3087 returnValue = responseData.length; 3088 } 3089 } else { 3090 CommandException ex = (CommandException) result.exception; 3091 returnValue = ex.getCommandError().ordinal(); 3092 if(returnValue > 0) returnValue *= -1; 3093 } 3094 } catch (RuntimeException e) { 3095 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception"); 3096 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal()); 3097 if(returnValue > 0) returnValue *= -1; 3098 } 3099 3100 return returnValue; 3101 } 3102 3103 @Override 3104 public void setRadioCapability(RadioAccessFamily[] rafs) { 3105 try { 3106 ProxyController.getInstance().setRadioCapability(rafs); 3107 } catch (RuntimeException e) { 3108 Log.w(LOG_TAG, "setRadioCapability: Runtime Exception"); 3109 } 3110 } 3111 3112 @Override 3113 public int getRadioAccessFamily(int phoneId, String callingPackage) { 3114 if (!canReadPhoneState(callingPackage, "getRadioAccessFamily")) { 3115 return RadioAccessFamily.RAF_UNKNOWN; 3116 } 3117 3118 return ProxyController.getInstance().getRadioAccessFamily(phoneId); 3119 } 3120 3121 @Override 3122 public void enableVideoCalling(boolean enable) { 3123 enforceModifyPermission(); 3124 ImsManager.setVtSetting(mPhone.getContext(), enable); 3125 } 3126 3127 @Override 3128 public boolean isVideoCallingEnabled(String callingPackage) { 3129 if (!canReadPhoneState(callingPackage, "isVideoCallingEnabled")) { 3130 return false; 3131 } 3132 3133 // Check the user preference and the system-level IMS setting. Even if the user has 3134 // enabled video calling, if IMS is disabled we aren't able to support video calling. 3135 // In the long run, we may instead need to check if there exists a connection service 3136 // which can support video calling. 3137 return ImsManager.isVtEnabledByPlatform(mPhone.getContext()) 3138 && ImsManager.isEnhanced4gLteModeSettingEnabledByUser(mPhone.getContext()) 3139 && ImsManager.isVtEnabledByUser(mPhone.getContext()); 3140 } 3141 3142 @Override 3143 public boolean canChangeDtmfToneLength() { 3144 return mApp.getCarrierConfig().getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL); 3145 } 3146 3147 @Override 3148 public boolean isWorldPhone() { 3149 return mApp.getCarrierConfig().getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL); 3150 } 3151 3152 @Override 3153 public boolean isTtyModeSupported() { 3154 TelecomManager telecomManager = TelecomManager.from(mPhone.getContext()); 3155 TelephonyManager telephonyManager = 3156 (TelephonyManager) mPhone.getContext().getSystemService(Context.TELEPHONY_SERVICE); 3157 return telecomManager.isTtySupported(); 3158 } 3159 3160 @Override 3161 public boolean isHearingAidCompatibilitySupported() { 3162 return mPhone.getContext().getResources().getBoolean(R.bool.hac_enabled); 3163 } 3164 3165 /** 3166 * Returns the unique device ID of phone, for example, the IMEI for 3167 * GSM and the MEID for CDMA phones. Return null if device ID is not available. 3168 * 3169 * <p>Requires Permission: 3170 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} 3171 */ 3172 @Override 3173 public String getDeviceId(String callingPackage) { 3174 if (!canReadPhoneState(callingPackage, "getDeviceId")) { 3175 return null; 3176 } 3177 3178 final Phone phone = PhoneFactory.getPhone(0); 3179 if (phone != null) { 3180 return phone.getDeviceId(); 3181 } else { 3182 return null; 3183 } 3184 } 3185 3186 /* 3187 * {@hide} 3188 * Returns the IMS Registration Status 3189 */ 3190 @Override 3191 public boolean isImsRegistered() { 3192 return mPhone.isImsRegistered(); 3193 } 3194 3195 @Override 3196 public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) { 3197 return PhoneUtils.getSubIdForPhoneAccount(phoneAccount); 3198 } 3199 3200 /* 3201 * {@hide} 3202 * Returns the IMS Registration Status 3203 */ 3204 public boolean isWifiCallingAvailable() { 3205 return mPhone.isWifiCallingEnabled(); 3206 } 3207 3208 /* 3209 * {@hide} 3210 * Returns the IMS Registration Status 3211 */ 3212 public boolean isVolteAvailable() { 3213 return mPhone.isVolteEnabled(); 3214 } 3215 3216 /* 3217 * {@hide} Returns the IMS Registration Status 3218 */ 3219 public boolean isVideoTelephonyAvailable() { 3220 return mPhone.isVideoEnabled(); 3221 } 3222 3223 private boolean canReadPhoneState(String callingPackage, String message) { 3224 try { 3225 mApp.enforceCallingOrSelfPermission( 3226 android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, message); 3227 3228 // SKIP checking for run-time permission since caller or self has PRIVILEDGED permission 3229 return true; 3230 } catch (SecurityException e) { 3231 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE, 3232 message); 3233 } 3234 3235 if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(), 3236 callingPackage) != AppOpsManager.MODE_ALLOWED) { 3237 return false; 3238 } 3239 3240 return true; 3241 } 3242 3243 /** 3244 * Besides READ_PHONE_STATE, WRITE_SMS and READ_SMS also allow apps to get phone numbers. 3245 */ 3246 private boolean canReadPhoneNumber(String callingPackage, String message) { 3247 // Default SMS app can always read it. 3248 if (mAppOps.noteOp(AppOpsManager.OP_WRITE_SMS, 3249 Binder.getCallingUid(), callingPackage) == AppOpsManager.MODE_ALLOWED) { 3250 return true; 3251 } 3252 3253 try { 3254 return canReadPhoneState(callingPackage, message); 3255 } catch (SecurityException readPhoneStateSecurityException) { 3256 } 3257 // Can be read with READ_SMS too. 3258 try { 3259 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_SMS, message); 3260 int opCode = mAppOps.permissionToOpCode(android.Manifest.permission.READ_SMS); 3261 if (opCode != AppOpsManager.OP_NONE) { 3262 return mAppOps.noteOp(opCode, Binder.getCallingUid(), callingPackage) 3263 == AppOpsManager.MODE_ALLOWED; 3264 } else { 3265 return true; 3266 } 3267 } catch (SecurityException readSmsSecurityException) { 3268 } 3269 // Can be read with READ_PHONE_NUMBERS too. 3270 try { 3271 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_NUMBERS, 3272 message); 3273 int opCode = mAppOps.permissionToOpCode(android.Manifest.permission.READ_PHONE_NUMBERS); 3274 if (opCode != AppOpsManager.OP_NONE) { 3275 return mAppOps.noteOp(opCode, Binder.getCallingUid(), callingPackage) 3276 == AppOpsManager.MODE_ALLOWED; 3277 } else { 3278 return true; 3279 } 3280 } catch (SecurityException readPhoneNumberSecurityException) { 3281 } 3282 3283 throw new SecurityException(message + ": Neither user " + Binder.getCallingUid() + 3284 " nor current process has" + android.Manifest.permission.READ_PHONE_STATE + 3285 ", " + android.Manifest.permission.READ_SMS + ", or " + 3286 android.Manifest.permission.READ_PHONE_NUMBERS); 3287 } 3288 3289 @Override 3290 public void factoryReset(int subId) { 3291 enforceConnectivityInternalPermission(); 3292 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) { 3293 return; 3294 } 3295 3296 final long identity = Binder.clearCallingIdentity(); 3297 try { 3298 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction( 3299 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) { 3300 // Enable data 3301 setDataEnabled(subId, true); 3302 // Set network selection mode to automatic 3303 setNetworkSelectionModeAutomatic(subId); 3304 // Set preferred mobile network type to the best available 3305 setPreferredNetworkType(subId, Phone.PREFERRED_NT_MODE); 3306 // Turn off roaming 3307 mPhone.setDataRoamingEnabled(false); 3308 } 3309 } finally { 3310 Binder.restoreCallingIdentity(identity); 3311 } 3312 } 3313 3314 @Override 3315 public String getLocaleFromDefaultSim() { 3316 // We query all subscriptions instead of just the active ones, because 3317 // this might be called early on in the provisioning flow when the 3318 // subscriptions potentially aren't active yet. 3319 final List<SubscriptionInfo> slist = getAllSubscriptionInfoList(); 3320 if (slist == null || slist.isEmpty()) { 3321 return null; 3322 } 3323 3324 // This function may be called very early, say, from the setup wizard, at 3325 // which point we won't have a default subscription set. If that's the case 3326 // we just choose the first, which will be valid in "most cases". 3327 final int defaultSubId = getDefaultSubscription(); 3328 SubscriptionInfo info = null; 3329 if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 3330 info = slist.get(0); 3331 } else { 3332 for (SubscriptionInfo item : slist) { 3333 if (item.getSubscriptionId() == defaultSubId) { 3334 info = item; 3335 break; 3336 } 3337 } 3338 3339 if (info == null) { 3340 return null; 3341 } 3342 } 3343 3344 // Try and fetch the locale from the carrier properties or from the SIM language 3345 // preferences (EF-PL and EF-LI)... 3346 final int mcc = info.getMcc(); 3347 final Phone defaultPhone = getPhone(info.getSubscriptionId()); 3348 String simLanguage = null; 3349 if (defaultPhone != null) { 3350 final Locale localeFromDefaultSim = defaultPhone.getLocaleFromSimAndCarrierPrefs(); 3351 if (localeFromDefaultSim != null) { 3352 if (!localeFromDefaultSim.getCountry().isEmpty()) { 3353 if (DBG) log("Using locale from default SIM:" + localeFromDefaultSim); 3354 return localeFromDefaultSim.toLanguageTag(); 3355 } else { 3356 simLanguage = localeFromDefaultSim.getLanguage(); 3357 } 3358 } 3359 } 3360 3361 // The SIM language preferences only store a language (e.g. fr = French), not an 3362 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from 3363 // the SIM and carrier preferences does not include a country we add the country 3364 // determined from the SIM MCC to provide an exact locale. 3365 final Locale mccLocale = MccTable.getLocaleFromMcc(mPhone.getContext(), mcc, simLanguage); 3366 if (mccLocale != null) { 3367 if (DBG) log("No locale from default SIM, using mcc locale:" + mccLocale); 3368 return mccLocale.toLanguageTag(); 3369 } 3370 3371 if (DBG) log("No locale found - returning null"); 3372 return null; 3373 } 3374 3375 private List<SubscriptionInfo> getAllSubscriptionInfoList() { 3376 final long identity = Binder.clearCallingIdentity(); 3377 try { 3378 return mSubscriptionController.getAllSubInfoList( 3379 mPhone.getContext().getOpPackageName()); 3380 } finally { 3381 Binder.restoreCallingIdentity(identity); 3382 } 3383 } 3384 3385 private List<SubscriptionInfo> getActiveSubscriptionInfoList() { 3386 final long identity = Binder.clearCallingIdentity(); 3387 try { 3388 return mSubscriptionController.getActiveSubscriptionInfoList( 3389 mPhone.getContext().getOpPackageName()); 3390 } finally { 3391 Binder.restoreCallingIdentity(identity); 3392 } 3393 } 3394 3395 /** 3396 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object 3397 * representing the state of the modem. 3398 * 3399 * NOTE: This clears the modem state, so there should only every be one caller. 3400 * @hide 3401 */ 3402 @Override 3403 public void requestModemActivityInfo(ResultReceiver result) { 3404 enforceModifyPermission(); 3405 3406 ModemActivityInfo info = (ModemActivityInfo) sendRequest(CMD_GET_MODEM_ACTIVITY_INFO, null); 3407 Bundle bundle = new Bundle(); 3408 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, info); 3409 result.send(0, bundle); 3410 } 3411 3412 /** 3413 * {@hide} 3414 * Returns the service state information on specified subscription. 3415 */ 3416 @Override 3417 public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) { 3418 3419 if (!canReadPhoneState(callingPackage, "getServiceStateForSubscriber")) { 3420 return null; 3421 } 3422 3423 final Phone phone = getPhone(subId); 3424 if (phone == null) { 3425 return null; 3426 } 3427 3428 return phone.getServiceState(); 3429 } 3430 3431 /** 3432 * Returns the URI for the per-account voicemail ringtone set in Phone settings. 3433 * 3434 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the 3435 * voicemail ringtone. 3436 * @return The URI for the ringtone to play when receiving a voicemail from a specific 3437 * PhoneAccount. 3438 */ 3439 @Override 3440 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) { 3441 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle); 3442 if (phone == null) { 3443 phone = mPhone; 3444 } 3445 3446 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext()); 3447 } 3448 3449 /** 3450 * Sets the per-account voicemail ringtone. 3451 * 3452 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or 3453 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}. 3454 * 3455 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the 3456 * voicemail ringtone. 3457 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific 3458 * PhoneAccount. 3459 */ 3460 @Override 3461 public void setVoicemailRingtoneUri(String callingPackage, 3462 PhoneAccountHandle phoneAccountHandle, Uri uri) { 3463 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 3464 if (!TextUtils.equals(callingPackage, 3465 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) { 3466 enforceModifyPermissionOrCarrierPrivilege( 3467 PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle)); 3468 } 3469 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle); 3470 if (phone == null){ 3471 phone = mPhone; 3472 } 3473 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri); 3474 } 3475 3476 /** 3477 * Returns whether vibration is set for voicemail notification in Phone settings. 3478 * 3479 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the 3480 * voicemail vibration setting. 3481 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise. 3482 */ 3483 @Override 3484 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) { 3485 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle); 3486 if (phone == null) { 3487 phone = mPhone; 3488 } 3489 3490 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext()); 3491 } 3492 3493 /** 3494 * Sets the per-account voicemail vibration. 3495 * 3496 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or 3497 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}. 3498 * 3499 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the 3500 * voicemail vibration setting. 3501 * @param enabled Whether to enable or disable vibration for voicemail notifications from a 3502 * specific PhoneAccount. 3503 */ 3504 @Override 3505 public void setVoicemailVibrationEnabled(String callingPackage, 3506 PhoneAccountHandle phoneAccountHandle, boolean enabled) { 3507 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 3508 if (!TextUtils.equals(callingPackage, 3509 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) { 3510 enforceModifyPermissionOrCarrierPrivilege( 3511 PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle)); 3512 } 3513 3514 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle); 3515 if (phone == null){ 3516 phone = mPhone; 3517 } 3518 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled); 3519 } 3520 3521 /** 3522 * Make sure either called from same process as self (phone) or IPC caller has read privilege. 3523 * 3524 * @throws SecurityException if the caller does not have the required permission 3525 */ 3526 private void enforceReadPrivilegedPermission() { 3527 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, 3528 null); 3529 } 3530 3531 /** 3532 * Make sure either called from same process as self (phone) or IPC caller has send SMS 3533 * permission. 3534 * 3535 * @throws SecurityException if the caller does not have the required permission 3536 */ 3537 private void enforceSendSmsPermission() { 3538 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null); 3539 } 3540 3541 /** 3542 * Make sure called from the package in charge of visual voicemail. 3543 * 3544 * @throws SecurityException if the caller is not the visual voicemail package. 3545 */ 3546 private void enforceVisualVoicemailPackage(String callingPackage, int subId) { 3547 ComponentName componentName = 3548 RemoteVvmTaskManager.getRemotePackage(mPhone.getContext(), subId); 3549 if(componentName == null) { 3550 throw new SecurityException("Caller not current active visual voicemail package[null]"); 3551 } 3552 String vvmPackage = componentName.getPackageName(); 3553 if (!callingPackage.equals(vvmPackage)) { 3554 throw new SecurityException("Caller not current active visual voicemail package[" + 3555 vvmPackage + "]"); 3556 } 3557 } 3558 3559 /** 3560 * Return the application ID for the app type. 3561 * 3562 * @param subId the subscription ID that this request applies to. 3563 * @param appType the uicc app type. 3564 * @return Application ID for specificied app type, or null if no uicc. 3565 */ 3566 @Override 3567 public String getAidForAppType(int subId, int appType) { 3568 enforceReadPrivilegedPermission(); 3569 Phone phone = getPhone(subId); 3570 if (phone == null) { 3571 return null; 3572 } 3573 String aid = null; 3574 try { 3575 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId()) 3576 .getApplicationByType(appType).getAid(); 3577 } catch (Exception e) { 3578 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e); 3579 } 3580 return aid; 3581 } 3582 3583 /** 3584 * Return the Electronic Serial Number. 3585 * 3586 * @param subId the subscription ID that this request applies to. 3587 * @return ESN or null if error. 3588 */ 3589 @Override 3590 public String getEsn(int subId) { 3591 enforceReadPrivilegedPermission(); 3592 Phone phone = getPhone(subId); 3593 if (phone == null) { 3594 return null; 3595 } 3596 String esn = null; 3597 try { 3598 esn = phone.getEsn(); 3599 } catch (Exception e) { 3600 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e); 3601 } 3602 return esn; 3603 } 3604 3605 /** 3606 * Return the Preferred Roaming List Version. 3607 * 3608 * @param subId the subscription ID that this request applies to. 3609 * @return PRLVersion or null if error. 3610 */ 3611 @Override 3612 public String getCdmaPrlVersion(int subId) { 3613 enforceReadPrivilegedPermission(); 3614 Phone phone = getPhone(subId); 3615 if (phone == null) { 3616 return null; 3617 } 3618 String cdmaPrlVersion = null; 3619 try { 3620 cdmaPrlVersion = phone.getCdmaPrlVersion(); 3621 } catch (Exception e) { 3622 Log.e(LOG_TAG, "Not getting PRLVersion", e); 3623 } 3624 return cdmaPrlVersion; 3625 } 3626 3627 /** 3628 * Get snapshot of Telephony histograms 3629 * @return List of Telephony histograms 3630 * @hide 3631 */ 3632 @Override 3633 public List<TelephonyHistogram> getTelephonyHistograms() { 3634 enforceModifyPermissionOrCarrierPrivilege(getDefaultSubscription()); 3635 return RIL.getTelephonyRILTimingHistograms(); 3636 } 3637 3638 /** 3639 * {@hide} 3640 * Set the allowed carrier list for slotIndex 3641 * Require system privileges. In the future we may add this to carrier APIs. 3642 * 3643 * @return The number of carriers set successfully, should match length of carriers 3644 */ 3645 @Override 3646 public int setAllowedCarriers(int slotIndex, List<CarrierIdentifier> carriers) { 3647 enforceModifyPermission(); 3648 3649 if (carriers == null) { 3650 throw new NullPointerException("carriers cannot be null"); 3651 } 3652 3653 int subId = SubscriptionManager.getSubId(slotIndex)[0]; 3654 int[] retVal = (int[]) sendRequest(CMD_SET_ALLOWED_CARRIERS, carriers, subId); 3655 return retVal[0]; 3656 } 3657 3658 /** 3659 * {@hide} 3660 * Get the allowed carrier list for slotIndex. 3661 * Require system privileges. In the future we may add this to carrier APIs. 3662 * 3663 * @return List of {@link android.service.telephony.CarrierIdentifier}; empty list 3664 * means all carriers are allowed. 3665 */ 3666 @Override 3667 public List<CarrierIdentifier> getAllowedCarriers(int slotIndex) { 3668 enforceReadPrivilegedPermission(); 3669 int subId = SubscriptionManager.getSubId(slotIndex)[0]; 3670 return (List<CarrierIdentifier>) sendRequest(CMD_GET_ALLOWED_CARRIERS, null, subId); 3671 } 3672 3673 /** 3674 * Action set from carrier signalling broadcast receivers to enable/disable metered apns 3675 * @param subId the subscription ID that this action applies to. 3676 * @param enabled control enable or disable metered apns. 3677 * {@hide} 3678 */ 3679 @Override 3680 public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) { 3681 enforceModifyPermission(); 3682 final Phone phone = getPhone(subId); 3683 if (phone == null) { 3684 loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId); 3685 return; 3686 } 3687 try { 3688 phone.carrierActionSetMeteredApnsEnabled(enabled); 3689 } catch (Exception e) { 3690 Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e); 3691 } 3692 } 3693 3694 /** 3695 * Action set from carrier signalling broadcast receivers to enable/disable radio 3696 * @param subId the subscription ID that this action applies to. 3697 * @param enabled control enable or disable radio. 3698 * {@hide} 3699 */ 3700 @Override 3701 public void carrierActionSetRadioEnabled(int subId, boolean enabled) { 3702 enforceModifyPermission(); 3703 final Phone phone = getPhone(subId); 3704 if (phone == null) { 3705 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId); 3706 return; 3707 } 3708 try { 3709 phone.carrierActionSetRadioEnabled(enabled); 3710 } catch (Exception e) { 3711 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e); 3712 } 3713 } 3714 3715 /** 3716 * Action set from carrier signalling broadcast receivers to start/stop reporting the default 3717 * network status based on which carrier apps could apply actions accordingly, 3718 * enable/disable default url handler for example. 3719 * 3720 * @param subId the subscription ID that this action applies to. 3721 * @param report control start/stop reporting the default network status. 3722 * {@hide} 3723 */ 3724 @Override 3725 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) { 3726 enforceModifyPermission(); 3727 final Phone phone = getPhone(subId); 3728 if (phone == null) { 3729 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId); 3730 return; 3731 } 3732 try { 3733 phone.carrierActionReportDefaultNetworkStatus(report); 3734 } catch (Exception e) { 3735 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e); 3736 } 3737 } 3738 3739 /** 3740 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a 3741 * bug report is being generated. 3742 */ 3743 @Override 3744 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 3745 if (mPhone.getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 3746 != PackageManager.PERMISSION_GRANTED) { 3747 writer.println("Permission Denial: can't dump Phone from pid=" 3748 + Binder.getCallingPid() 3749 + ", uid=" + Binder.getCallingUid() 3750 + "without permission " 3751 + android.Manifest.permission.DUMP); 3752 return; 3753 } 3754 DumpsysHandler.dump(mPhone.getContext(), fd, writer, args); 3755 } 3756 3757 /** 3758 * Get aggregated video call data usage since boot. 3759 * 3760 * @param perUidStats True if requesting data usage per uid, otherwise overall usage. 3761 * @return Snapshot of video call data usage 3762 * {@hide} 3763 */ 3764 @Override 3765 public NetworkStats getVtDataUsage(int subId, boolean perUidStats) { 3766 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_NETWORK_USAGE_HISTORY, 3767 null); 3768 3769 // NetworkStatsService keeps tracking the active network interface and identity. It 3770 // records the delta with the corresponding network identity. We just return the total video 3771 // call data usage snapshot since boot. 3772 Phone phone = getPhone(subId); 3773 if (phone != null) { 3774 return phone.getVtDataUsage(perUidStats); 3775 } 3776 return null; 3777 } 3778 3779 /** 3780 * Policy control of data connection. Usually used when data limit is passed. 3781 * @param enabled True if enabling the data, otherwise disabling. 3782 * @param subId Subscription index 3783 * {@hide} 3784 */ 3785 @Override 3786 public void setPolicyDataEnabled(boolean enabled, int subId) { 3787 enforceModifyPermission(); 3788 Phone phone = getPhone(subId); 3789 if (phone != null) { 3790 phone.setPolicyDataEnabled(enabled); 3791 } 3792 } 3793 3794 /** 3795 * Get Client request stats 3796 * @return List of Client Request Stats 3797 * @hide 3798 */ 3799 @Override 3800 public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) { 3801 if (!canReadPhoneState(callingPackage, "getClientRequestStats")) { 3802 return null; 3803 } 3804 3805 Phone phone = getPhone(subId); 3806 if (phone != null) { 3807 return phone.getClientRequestStats(); 3808 } 3809 3810 return null; 3811 } 3812 3813 private WorkSource getWorkSource(WorkSource workSource, int uid) { 3814 if (workSource != null) { 3815 return workSource; 3816 } 3817 3818 String packageName = mPhone.getContext().getPackageManager().getNameForUid(uid); 3819 workSource = new WorkSource(uid, packageName); 3820 return workSource; 3821 } 3822 3823 /** 3824 * Set SIM card power state. 3825 * 3826 * @param slotIndex SIM slot id. 3827 * @param state State of SIM (power down, power up, pass through) 3828 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN} 3829 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP} 3830 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH} 3831 * 3832 **/ 3833 @Override 3834 public void setSimPowerStateForSlot(int slotIndex, int state) { 3835 enforceModifyPermission(); 3836 Phone phone = PhoneFactory.getPhone(slotIndex); 3837 3838 if (phone != null) { 3839 phone.setSimPowerState(state); 3840 } 3841 } 3842 3843 private boolean isUssdApiAllowed(int subId) { 3844 CarrierConfigManager configManager = 3845 (CarrierConfigManager) mPhone.getContext().getSystemService( 3846 Context.CARRIER_CONFIG_SERVICE); 3847 if (configManager == null) { 3848 return false; 3849 } 3850 PersistableBundle pb = configManager.getConfigForSubId(subId); 3851 if (pb == null) { 3852 return false; 3853 } 3854 return pb.getBoolean( 3855 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL); 3856 } 3857 3858 /** 3859 * Check if phone is in emergency callback mode 3860 * @return true if phone is in emergency callback mode 3861 * @param subId sub id 3862 */ 3863 public boolean getEmergencyCallbackMode(int subId) { 3864 final Phone phone = getPhone(subId); 3865 if (phone != null) { 3866 return phone.isInEcm(); 3867 } else { 3868 return false; 3869 } 3870 } 3871 3872 /** 3873 * Get the current signal strength information for the given subscription. 3874 * Because this information is not updated when the device is in a low power state 3875 * it should not be relied-upon to be current. 3876 * @param subId Subscription index 3877 * @return the most recent cached signal strength info from the modem 3878 */ 3879 @Override 3880 public SignalStrength getSignalStrength(int subId) { 3881 Phone p = getPhone(subId); 3882 if (p == null) { 3883 return null; 3884 } 3885 3886 return p.getSignalStrength(); 3887 } 3888 } 3889