1 /* 2 * Copyright (C) 2019 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 package android.telephony; 17 18 import android.annotation.CallbackExecutor; 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.RequiresPermission; 22 import android.compat.Compatibility; 23 import android.compat.annotation.ChangeId; 24 import android.compat.annotation.EnabledAfter; 25 import android.content.Context; 26 import android.os.Binder; 27 import android.os.Build; 28 import android.os.RemoteException; 29 import android.os.ServiceManager; 30 import android.service.carrier.CarrierService; 31 import android.telephony.Annotation.CallState; 32 import android.telephony.Annotation.DataActivityType; 33 import android.telephony.Annotation.DisconnectCauses; 34 import android.telephony.Annotation.NetworkType; 35 import android.telephony.Annotation.PreciseDisconnectCauses; 36 import android.telephony.Annotation.RadioPowerState; 37 import android.telephony.Annotation.SimActivationState; 38 import android.telephony.Annotation.SrvccState; 39 import android.telephony.TelephonyManager.CarrierPrivilegesCallback; 40 import android.telephony.emergency.EmergencyNumber; 41 import android.telephony.ims.ImsCallSession; 42 import android.telephony.ims.ImsReasonInfo; 43 import android.telephony.ims.MediaQualityStatus; 44 import android.util.ArraySet; 45 import android.util.Log; 46 47 import com.android.internal.annotations.GuardedBy; 48 import com.android.internal.listeners.ListenerExecutor; 49 import com.android.internal.telephony.ICarrierConfigChangeListener; 50 import com.android.internal.telephony.ICarrierPrivilegesCallback; 51 import com.android.internal.telephony.IOnSubscriptionsChangedListener; 52 import com.android.internal.telephony.ITelephonyRegistry; 53 54 import java.lang.ref.WeakReference; 55 import java.util.Arrays; 56 import java.util.List; 57 import java.util.Objects; 58 import java.util.Set; 59 import java.util.WeakHashMap; 60 import java.util.concurrent.ConcurrentHashMap; 61 import java.util.concurrent.Executor; 62 import java.util.stream.Collectors; 63 64 /** 65 * A centralized place to notify telephony related status changes, e.g, {@link ServiceState} update 66 * or {@link PhoneCapability} changed. This might trigger callback from applications side through 67 * {@link android.telephony.PhoneStateListener} 68 * 69 * TODO: limit API access to only carrier apps with certain permissions or apps running on 70 * privileged UID. 71 * 72 * @hide 73 */ 74 public class TelephonyRegistryManager { 75 76 private static final String TAG = "TelephonyRegistryManager"; 77 private static ITelephonyRegistry sRegistry; 78 private final Context mContext; 79 80 /** 81 * A mapping between {@link SubscriptionManager.OnSubscriptionsChangedListener} and 82 * its callback IOnSubscriptionsChangedListener. 83 */ 84 private final ConcurrentHashMap<SubscriptionManager.OnSubscriptionsChangedListener, 85 IOnSubscriptionsChangedListener> 86 mSubscriptionChangedListenerMap = new ConcurrentHashMap<>(); 87 /** 88 * A mapping between {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} and 89 * its callback IOnSubscriptionsChangedListener. 90 */ 91 private final ConcurrentHashMap<SubscriptionManager.OnOpportunisticSubscriptionsChangedListener, 92 IOnSubscriptionsChangedListener> 93 mOpportunisticSubscriptionChangedListenerMap = new ConcurrentHashMap<>(); 94 95 /** 96 * A mapping between {@link CarrierConfigManager.CarrierConfigChangeListener} and its callback 97 * ICarrierConfigChangeListener. 98 */ 99 private final ConcurrentHashMap<CarrierConfigManager.CarrierConfigChangeListener, 100 ICarrierConfigChangeListener> 101 mCarrierConfigChangeListenerMap = new ConcurrentHashMap<>(); 102 103 104 /** @hide **/ TelephonyRegistryManager(@onNull Context context)105 public TelephonyRegistryManager(@NonNull Context context) { 106 mContext = context; 107 if (sRegistry == null) { 108 sRegistry = ITelephonyRegistry.Stub.asInterface( 109 ServiceManager.getService("telephony.registry")); 110 } 111 } 112 113 /** 114 * Register for changes to the list of active {@link SubscriptionInfo} records or to the 115 * individual records themselves. When a change occurs the onSubscriptionsChanged method of 116 * the listener will be invoked immediately if there has been a notification. The 117 * onSubscriptionChanged method will also be triggered once initially when calling this 118 * function. 119 * 120 * @param listener an instance of {@link SubscriptionManager.OnSubscriptionsChangedListener} 121 * with onSubscriptionsChanged overridden. 122 * @param executor the executor that will execute callbacks. 123 */ addOnSubscriptionsChangedListener( @onNull SubscriptionManager.OnSubscriptionsChangedListener listener, @NonNull Executor executor)124 public void addOnSubscriptionsChangedListener( 125 @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener, 126 @NonNull Executor executor) { 127 if (mSubscriptionChangedListenerMap.get(listener) != null) { 128 Log.d(TAG, "addOnSubscriptionsChangedListener listener already present"); 129 return; 130 } 131 IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { 132 @Override 133 public void onSubscriptionsChanged () { 134 final long identity = Binder.clearCallingIdentity(); 135 try { 136 executor.execute(() -> listener.onSubscriptionsChanged()); 137 } finally { 138 Binder.restoreCallingIdentity(identity); 139 } 140 } 141 }; 142 mSubscriptionChangedListenerMap.put(listener, callback); 143 try { 144 sRegistry.addOnSubscriptionsChangedListener(mContext.getOpPackageName(), 145 mContext.getAttributionTag(), callback); 146 } catch (RemoteException ex) { 147 // system server crash 148 throw ex.rethrowFromSystemServer(); 149 } 150 } 151 152 /** 153 * Unregister the {@link SubscriptionManager.OnSubscriptionsChangedListener}. This is not 154 * strictly necessary as the listener will automatically be unregistered if an attempt to 155 * invoke the listener fails. 156 * 157 * @param listener that is to be unregistered. 158 */ removeOnSubscriptionsChangedListener( @onNull SubscriptionManager.OnSubscriptionsChangedListener listener)159 public void removeOnSubscriptionsChangedListener( 160 @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener) { 161 if (mSubscriptionChangedListenerMap.get(listener) == null) { 162 return; 163 } 164 try { 165 sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(), 166 mSubscriptionChangedListenerMap.get(listener)); 167 mSubscriptionChangedListenerMap.remove(listener); 168 } catch (RemoteException ex) { 169 // system server crash 170 throw ex.rethrowFromSystemServer(); 171 } 172 } 173 174 /** 175 * Register for changes to the list of opportunistic subscription records or to the 176 * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged 177 * method of the listener will be invoked immediately if there has been a notification. 178 * 179 * @param listener an instance of 180 * {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} with 181 * onOpportunisticSubscriptionsChanged overridden. 182 * @param executor an Executor that will execute callbacks. 183 */ addOnOpportunisticSubscriptionsChangedListener( @onNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener, @NonNull Executor executor)184 public void addOnOpportunisticSubscriptionsChangedListener( 185 @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener, 186 @NonNull Executor executor) { 187 if (mOpportunisticSubscriptionChangedListenerMap.get(listener) != null) { 188 Log.d(TAG, "addOnOpportunisticSubscriptionsChangedListener listener already present"); 189 return; 190 } 191 /** 192 * The callback methods need to be called on the executor thread where 193 * this object was created. If the binder did that for us it'd be nice. 194 */ 195 IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { 196 @Override 197 public void onSubscriptionsChanged() { 198 final long identity = Binder.clearCallingIdentity(); 199 try { 200 Log.d(TAG, "onOpportunisticSubscriptionsChanged callback received."); 201 executor.execute(() -> listener.onOpportunisticSubscriptionsChanged()); 202 } finally { 203 Binder.restoreCallingIdentity(identity); 204 } 205 } 206 }; 207 mOpportunisticSubscriptionChangedListenerMap.put(listener, callback); 208 try { 209 sRegistry.addOnOpportunisticSubscriptionsChangedListener(mContext.getOpPackageName(), 210 mContext.getAttributionTag(), callback); 211 } catch (RemoteException ex) { 212 // system server crash 213 throw ex.rethrowFromSystemServer(); 214 } 215 } 216 217 /** 218 * Unregister the {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} 219 * that is currently listening opportunistic subscriptions change. This is not strictly 220 * necessary as the listener will automatically be unregistered if an attempt to invoke the 221 * listener fails. 222 * 223 * @param listener that is to be unregistered. 224 */ removeOnOpportunisticSubscriptionsChangedListener( @onNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener)225 public void removeOnOpportunisticSubscriptionsChangedListener( 226 @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener) { 227 if (mOpportunisticSubscriptionChangedListenerMap.get(listener) == null) { 228 return; 229 } 230 try { 231 sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(), 232 mOpportunisticSubscriptionChangedListenerMap.get(listener)); 233 mOpportunisticSubscriptionChangedListenerMap.remove(listener); 234 } catch (RemoteException ex) { 235 // system server crash 236 throw ex.rethrowFromSystemServer(); 237 } 238 } 239 240 /** 241 * To check the SDK version for {@link #listenFromListener}. 242 */ 243 @ChangeId 244 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.P) 245 private static final long LISTEN_CODE_CHANGE = 147600208L; 246 247 /** 248 * Listen for incoming subscriptions 249 * @param subId Subscription ID 250 * @param pkg Package name 251 * @param featureId Feature ID 252 * @param listener Listener providing callback 253 * @param events Events 254 * @param notifyNow Whether to notify instantly 255 */ listenFromListener(int subId, @NonNull boolean renounceFineLocationAccess, @NonNull boolean renounceCoarseLocationAccess, @NonNull String pkg, @NonNull String featureId, @NonNull PhoneStateListener listener, @NonNull int events, boolean notifyNow)256 public void listenFromListener(int subId, @NonNull boolean renounceFineLocationAccess, 257 @NonNull boolean renounceCoarseLocationAccess, @NonNull String pkg, 258 @NonNull String featureId, @NonNull PhoneStateListener listener, 259 @NonNull int events, boolean notifyNow) { 260 if (listener == null) { 261 throw new IllegalStateException("telephony service is null."); 262 } 263 264 try { 265 int[] eventsList = getEventsFromBitmask(events).stream().mapToInt(i -> i).toArray(); 266 // subId from PhoneStateListener is deprecated Q on forward, use the subId from 267 // TelephonyManager instance. Keep using subId from PhoneStateListener for pre-Q. 268 if (Compatibility.isChangeEnabled(LISTEN_CODE_CHANGE)) { 269 // Since mSubId in PhoneStateListener is deprecated from Q on forward, this is 270 // the only place to set mSubId and its for "informational" only. 271 listener.mSubId = (eventsList.length == 0) 272 ? SubscriptionManager.INVALID_SUBSCRIPTION_ID : subId; 273 } else if (listener.mSubId != null) { 274 subId = listener.mSubId; 275 } 276 sRegistry.listenWithEventList(renounceFineLocationAccess, renounceCoarseLocationAccess, 277 subId, pkg, featureId, listener.callback, eventsList, notifyNow); 278 } catch (RemoteException e) { 279 throw e.rethrowFromSystemServer(); 280 } 281 } 282 283 /** 284 * Listen for incoming subscriptions 285 * @param subId Subscription ID 286 * @param pkg Package name 287 * @param featureId Feature ID 288 * @param telephonyCallback Listener providing callback 289 * @param events List events 290 * @param notifyNow Whether to notify instantly 291 */ listenFromCallback(boolean renounceFineLocationAccess, boolean renounceCoarseLocationAccess, int subId, @NonNull String pkg, @NonNull String featureId, @NonNull TelephonyCallback telephonyCallback, @NonNull int[] events, boolean notifyNow)292 private void listenFromCallback(boolean renounceFineLocationAccess, 293 boolean renounceCoarseLocationAccess, int subId, 294 @NonNull String pkg, @NonNull String featureId, 295 @NonNull TelephonyCallback telephonyCallback, @NonNull int[] events, 296 boolean notifyNow) { 297 try { 298 sRegistry.listenWithEventList(renounceFineLocationAccess, renounceCoarseLocationAccess, 299 subId, pkg, featureId, telephonyCallback.callback, events, notifyNow); 300 } catch (RemoteException e) { 301 throw e.rethrowFromSystemServer(); 302 } 303 } 304 305 /** 306 * Informs the system of an intentional upcoming carrier network change by a carrier app. 307 * This call only used to allow the system to provide alternative UI while telephony is 308 * performing an action that may result in intentional, temporary network lack of connectivity. 309 * <p> 310 * Based on the active parameter passed in, this method will either show or hide the alternative 311 * UI. There is no timeout associated with showing this UX, so a carrier app must be sure to 312 * call with active set to false sometime after calling with it set to {@code true}. 313 * <p> 314 * This will apply to all subscriptions the carrier app has carrier privileges on. 315 * <p> 316 * Requires Permission: calling app has carrier privileges. 317 * 318 * @param active Whether the carrier network change is or shortly will be 319 * active. Set this value to true to begin showing alternative UI and false to stop. 320 * @see TelephonyManager#hasCarrierPrivileges 321 */ notifyCarrierNetworkChange(boolean active)322 public void notifyCarrierNetworkChange(boolean active) { 323 try { 324 sRegistry.notifyCarrierNetworkChange(active); 325 } catch (RemoteException ex) { 326 // system server crash 327 throw ex.rethrowFromSystemServer(); 328 } 329 } 330 331 /** 332 * Informs the system of an intentional upcoming carrier network change by a carrier app on the 333 * given {@code subscriptionId}. This call only used to allow the system to provide alternative 334 * UI while telephony is performing an action that may result in intentional, temporary network 335 * lack of connectivity. 336 * <p> 337 * Based on the active parameter passed in, this method will either show or hide the 338 * alternative UI. There is no timeout associated with showing this UX, so a carrier app must be 339 * sure to call with active set to false sometime after calling with it set to {@code true}. 340 * <p> 341 * Requires Permission: calling app has carrier privileges. 342 * 343 * @param subscriptionId the subscription of the carrier network. 344 * @param active whether the carrier network change is or shortly will be active. Set this value 345 * to true to begin showing alternative UI and false to stop. 346 * @see TelephonyManager#hasCarrierPrivileges 347 */ notifyCarrierNetworkChange(int subscriptionId, boolean active)348 public void notifyCarrierNetworkChange(int subscriptionId, boolean active) { 349 try { 350 sRegistry.notifyCarrierNetworkChangeWithSubId(subscriptionId, active); 351 } catch (RemoteException ex) { 352 // system server crash 353 throw ex.rethrowFromSystemServer(); 354 } 355 } 356 357 /** 358 * Notify call state changed on certain subscription. 359 * 360 * @param slotIndex for which call state changed. Can be derived from subId except when subId is 361 * invalid. 362 * @param subId for which call state changed. 363 * @param state latest call state. e.g, offhook, ringing 364 * @param incomingNumber incoming phone number. 365 */ notifyCallStateChanged(int slotIndex, int subId, @CallState int state, @Nullable String incomingNumber)366 public void notifyCallStateChanged(int slotIndex, int subId, @CallState int state, 367 @Nullable String incomingNumber) { 368 try { 369 sRegistry.notifyCallState(slotIndex, subId, state, incomingNumber); 370 } catch (RemoteException ex) { 371 // system server crash 372 throw ex.rethrowFromSystemServer(); 373 } 374 } 375 376 /** 377 * Notify call state changed on all subscriptions. 378 * 379 * @param state latest call state. e.g, offhook, ringing 380 * @param incomingNumber incoming phone number. 381 * @hide 382 */ 383 @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) notifyCallStateChangedForAllSubscriptions(@allState int state, @Nullable String incomingNumber)384 public void notifyCallStateChangedForAllSubscriptions(@CallState int state, 385 @Nullable String incomingNumber) { 386 try { 387 sRegistry.notifyCallStateForAllSubs(state, incomingNumber); 388 } catch (RemoteException ex) { 389 // system server crash 390 throw ex.rethrowFromSystemServer(); 391 } 392 } 393 394 /** 395 * Notify {@link SubscriptionInfo} change. 396 * @hide 397 */ notifySubscriptionInfoChanged()398 public void notifySubscriptionInfoChanged() { 399 try { 400 sRegistry.notifySubscriptionInfoChanged(); 401 } catch (RemoteException ex) { 402 // system server crash 403 throw ex.rethrowFromSystemServer(); 404 } 405 } 406 407 /** 408 * Notify opportunistic {@link SubscriptionInfo} change. 409 * @hide 410 */ notifyOpportunisticSubscriptionInfoChanged()411 public void notifyOpportunisticSubscriptionInfoChanged() { 412 try { 413 sRegistry.notifyOpportunisticSubscriptionInfoChanged(); 414 } catch (RemoteException ex) { 415 // system server crash 416 throw ex.rethrowFromSystemServer(); 417 } 418 } 419 420 /** 421 * Notify {@link ServiceState} update on certain subscription. 422 * 423 * @param slotIndex for which the service state changed. Can be derived from subId except 424 * subId is invalid. 425 * @param subId for which the service state changed. 426 * @param state service state e.g, in service, out of service or roaming status. 427 */ notifyServiceStateChanged(int slotIndex, int subId, @NonNull ServiceState state)428 public void notifyServiceStateChanged(int slotIndex, int subId, @NonNull ServiceState state) { 429 try { 430 sRegistry.notifyServiceStateForPhoneId(slotIndex, subId, state); 431 } catch (RemoteException ex) { 432 // system server crash 433 throw ex.rethrowFromSystemServer(); 434 } 435 } 436 437 /** 438 * Notify {@link SignalStrength} update on certain subscription. 439 * 440 * @param slotIndex for which the signalstrength changed. Can be derived from subId except when 441 * subId is invalid. 442 * @param subId for which the signalstrength changed. 443 * @param signalStrength e.g, signalstrength level {@see SignalStrength#getLevel()} 444 */ notifySignalStrengthChanged(int slotIndex, int subId, @NonNull SignalStrength signalStrength)445 public void notifySignalStrengthChanged(int slotIndex, int subId, 446 @NonNull SignalStrength signalStrength) { 447 try { 448 sRegistry.notifySignalStrengthForPhoneId(slotIndex, subId, signalStrength); 449 } catch (RemoteException ex) { 450 // system server crash 451 throw ex.rethrowFromSystemServer(); 452 } 453 } 454 455 /** 456 * Notify changes to the message-waiting indicator on certain subscription. e.g, The status bar 457 * uses message waiting indicator to determine when to display the voicemail icon. 458 * 459 * @param slotIndex for which message waiting indicator changed. Can be derived from subId 460 * except when subId is invalid. 461 * @param subId for which message waiting indicator changed. 462 * @param msgWaitingInd {@code true} indicates there is message-waiting indicator, {@code false} 463 * otherwise. 464 */ notifyMessageWaitingChanged(int slotIndex, int subId, boolean msgWaitingInd)465 public void notifyMessageWaitingChanged(int slotIndex, int subId, boolean msgWaitingInd) { 466 try { 467 sRegistry.notifyMessageWaitingChangedForPhoneId(slotIndex, subId, msgWaitingInd); 468 } catch (RemoteException ex) { 469 // system process is dead 470 throw ex.rethrowFromSystemServer(); 471 } 472 } 473 474 /** 475 * Notify changes to the call-forwarding status on certain subscription. 476 * 477 * @param subId for which call forwarding status changed. 478 * @param callForwardInd {@code true} indicates there is call forwarding, {@code false} 479 * otherwise. 480 */ notifyCallForwardingChanged(int subId, boolean callForwardInd)481 public void notifyCallForwardingChanged(int subId, boolean callForwardInd) { 482 try { 483 sRegistry.notifyCallForwardingChangedForSubscriber(subId, callForwardInd); 484 } catch (RemoteException ex) { 485 // system process is dead 486 throw ex.rethrowFromSystemServer(); 487 } 488 } 489 490 /** 491 * Notify changes to activity state changes on certain subscription. 492 * 493 * @param subId for which data activity state changed. 494 * @param dataActivityType indicates the latest data activity type e.g, {@link 495 * TelephonyManager#DATA_ACTIVITY_IN} 496 */ notifyDataActivityChanged(int subId, @DataActivityType int dataActivityType)497 public void notifyDataActivityChanged(int subId, @DataActivityType int dataActivityType) { 498 try { 499 sRegistry.notifyDataActivityForSubscriber(subId, dataActivityType); 500 } catch (RemoteException ex) { 501 // system process is dead 502 throw ex.rethrowFromSystemServer(); 503 } 504 } 505 506 /** 507 * Notify changes to default (Internet) data connection state on certain subscription. 508 * 509 * @param slotIndex for which data connections state changed. Can be derived from subId except 510 * when subId is invalid. 511 * @param subId for which data connection state changed. 512 * @param preciseState the PreciseDataConnectionState 513 * 514 * @see PreciseDataConnectionState 515 * @see TelephonyManager#DATA_DISCONNECTED 516 */ notifyDataConnectionForSubscriber(int slotIndex, int subId, @NonNull PreciseDataConnectionState preciseState)517 public void notifyDataConnectionForSubscriber(int slotIndex, int subId, 518 @NonNull PreciseDataConnectionState preciseState) { 519 try { 520 sRegistry.notifyDataConnectionForSubscriber( 521 slotIndex, subId, preciseState); 522 } catch (RemoteException ex) { 523 // system process is dead 524 throw ex.rethrowFromSystemServer(); 525 } 526 } 527 528 /** 529 * Notify {@link CallQuality} change on certain subscription. 530 * 531 * @param slotIndex for which call quality state changed. Can be derived from subId except when 532 * subId is invalid. 533 * @param subId for which call quality state changed. 534 * @param callQuality Information about call quality e.g, call quality level 535 * @param networkType associated with this data connection. e.g, LTE 536 */ notifyCallQualityChanged(int slotIndex, int subId, @NonNull CallQuality callQuality, @NetworkType int networkType)537 public void notifyCallQualityChanged(int slotIndex, int subId, @NonNull CallQuality callQuality, 538 @NetworkType int networkType) { 539 try { 540 sRegistry.notifyCallQualityChanged(callQuality, slotIndex, subId, networkType); 541 } catch (RemoteException ex) { 542 // system process is dead 543 throw ex.rethrowFromSystemServer(); 544 } 545 } 546 547 /** 548 * Notify change of media quality status {@link MediaQualityStatus} crosses media quality 549 * threshold 550 * <p/> 551 * Currently thresholds for this indication can be configurable by CARRIER_CONFIG 552 * {@link CarrierConfigManager#KEY_VOICE_RTP_THRESHOLDS_PACKET_LOSS_RATE_INT} 553 * {@link CarrierConfigManager#KEY_VOICE_RTP_THRESHOLDS_INACTIVITY_TIME_IN_MILLIS_INT} 554 * {@link CarrierConfigManager#KEY_VOICE_RTP_THRESHOLDS_JITTER_INT} 555 * 556 * @param status media quality status 557 */ notifyMediaQualityStatusChanged( int slotIndex, int subId, @NonNull MediaQualityStatus status)558 public void notifyMediaQualityStatusChanged( 559 int slotIndex, int subId, @NonNull MediaQualityStatus status) { 560 try { 561 sRegistry.notifyMediaQualityStatusChanged(slotIndex, subId, status); 562 } catch (RemoteException ex) { 563 // system server crash 564 throw ex.rethrowFromSystemServer(); 565 } 566 } 567 568 /** 569 * Notify emergency number list changed on certain subscription. 570 * 571 * @param slotIndex for which emergency number list changed. Can be derived from subId except 572 * when subId is invalid. 573 * @param subId for which emergency number list changed. 574 */ notifyEmergencyNumberList( int slotIndex, int subId)575 public void notifyEmergencyNumberList( int slotIndex, int subId) { 576 try { 577 sRegistry.notifyEmergencyNumberList(slotIndex, subId); 578 } catch (RemoteException ex) { 579 // system process is dead 580 throw ex.rethrowFromSystemServer(); 581 } 582 } 583 584 /** 585 * Notify outgoing emergency call. 586 * @param phoneId Sender phone ID. 587 * @param subId Sender subscription ID. 588 * @param emergencyNumber Emergency number. 589 */ notifyOutgoingEmergencyCall(int phoneId, int subId, @NonNull EmergencyNumber emergencyNumber)590 public void notifyOutgoingEmergencyCall(int phoneId, int subId, 591 @NonNull EmergencyNumber emergencyNumber) { 592 try { 593 sRegistry.notifyOutgoingEmergencyCall(phoneId, subId, emergencyNumber); 594 } catch (RemoteException ex) { 595 // system process is dead 596 throw ex.rethrowFromSystemServer(); 597 } 598 } 599 600 /** 601 * Notify outgoing emergency SMS. 602 * @param phoneId Sender phone ID. 603 * @param subId Sender subscription ID. 604 * @param emergencyNumber Emergency number. 605 */ notifyOutgoingEmergencySms(int phoneId, int subId, @NonNull EmergencyNumber emergencyNumber)606 public void notifyOutgoingEmergencySms(int phoneId, int subId, 607 @NonNull EmergencyNumber emergencyNumber) { 608 try { 609 sRegistry.notifyOutgoingEmergencySms(phoneId, subId, emergencyNumber); 610 } catch (RemoteException ex) { 611 // system process is dead 612 throw ex.rethrowFromSystemServer(); 613 } 614 } 615 616 /** 617 * Notify radio power state changed on certain subscription. 618 * 619 * @param slotIndex for which radio power state changed. Can be derived from subId except when 620 * subId is invalid. 621 * @param subId for which radio power state changed. 622 * @param radioPowerState the current modem radio state. 623 */ notifyRadioPowerStateChanged(int slotIndex, int subId, @RadioPowerState int radioPowerState)624 public void notifyRadioPowerStateChanged(int slotIndex, int subId, 625 @RadioPowerState int radioPowerState) { 626 try { 627 sRegistry.notifyRadioPowerStateChanged(slotIndex, subId, radioPowerState); 628 } catch (RemoteException ex) { 629 // system process is dead 630 throw ex.rethrowFromSystemServer(); 631 } 632 } 633 634 /** 635 * Notify {@link PhoneCapability} changed. 636 * 637 * @param phoneCapability the capability of the modem group. 638 */ notifyPhoneCapabilityChanged(@onNull PhoneCapability phoneCapability)639 public void notifyPhoneCapabilityChanged(@NonNull PhoneCapability phoneCapability) { 640 try { 641 sRegistry.notifyPhoneCapabilityChanged(phoneCapability); 642 } catch (RemoteException ex) { 643 // system process is dead 644 throw ex.rethrowFromSystemServer(); 645 } 646 } 647 648 /** 649 * Sim activation type: voice 650 * @see #notifyVoiceActivationStateChanged 651 * @hide 652 */ 653 public static final int SIM_ACTIVATION_TYPE_VOICE = 0; 654 /** 655 * Sim activation type: data 656 * @see #notifyDataActivationStateChanged 657 * @hide 658 */ 659 public static final int SIM_ACTIVATION_TYPE_DATA = 1; 660 661 /** 662 * Notify data activation state changed on certain subscription. 663 * @see TelephonyManager#getDataActivationState() 664 * 665 * @param slotIndex for which data activation state changed. Can be derived from subId except 666 * when subId is invalid. 667 * @param subId for which data activation state changed. 668 * @param activationState sim activation state e.g, activated. 669 */ notifyDataActivationStateChanged(int slotIndex, int subId, @SimActivationState int activationState)670 public void notifyDataActivationStateChanged(int slotIndex, int subId, 671 @SimActivationState int activationState) { 672 try { 673 sRegistry.notifySimActivationStateChangedForPhoneId(slotIndex, subId, 674 SIM_ACTIVATION_TYPE_DATA, activationState); 675 } catch (RemoteException ex) { 676 // system process is dead 677 throw ex.rethrowFromSystemServer(); 678 } 679 } 680 681 /** 682 * Notify voice activation state changed on certain subscription. 683 * @see TelephonyManager#getVoiceActivationState() 684 * 685 * @param slotIndex for which voice activation state changed. Can be derived from subId except 686 * subId is invalid. 687 * @param subId for which voice activation state changed. 688 * @param activationState sim activation state e.g, activated. 689 */ notifyVoiceActivationStateChanged(int slotIndex, int subId, @SimActivationState int activationState)690 public void notifyVoiceActivationStateChanged(int slotIndex, int subId, 691 @SimActivationState int activationState) { 692 try { 693 sRegistry.notifySimActivationStateChangedForPhoneId(slotIndex, subId, 694 SIM_ACTIVATION_TYPE_VOICE, activationState); 695 } catch (RemoteException ex) { 696 // system process is dead 697 throw ex.rethrowFromSystemServer(); 698 } 699 } 700 701 /** 702 * Notify User mobile data state changed on certain subscription. e.g, mobile data is enabled 703 * or disabled. 704 * 705 * @param slotIndex for which mobile data state has changed. Can be derived from subId except 706 * when subId is invalid. 707 * @param subId for which mobile data state has changed. 708 * @param state {@code true} indicates mobile data is enabled/on. {@code false} otherwise. 709 */ notifyUserMobileDataStateChanged(int slotIndex, int subId, boolean state)710 public void notifyUserMobileDataStateChanged(int slotIndex, int subId, boolean state) { 711 try { 712 sRegistry.notifyUserMobileDataStateChangedForPhoneId(slotIndex, subId, state); 713 } catch (RemoteException ex) { 714 // system process is dead 715 throw ex.rethrowFromSystemServer(); 716 } 717 } 718 719 /** 720 * Notify display info changed. 721 * 722 * @param slotIndex The SIM slot index for which display info has changed. Can be 723 * derived from {@code subscriptionId} except when {@code subscriptionId} is invalid, such as 724 * when the device is in emergency-only mode. 725 * @param subscriptionId Subscription id for which display network info has changed. 726 * @param telephonyDisplayInfo The display info. 727 */ notifyDisplayInfoChanged(int slotIndex, int subscriptionId, @NonNull TelephonyDisplayInfo telephonyDisplayInfo)728 public void notifyDisplayInfoChanged(int slotIndex, int subscriptionId, 729 @NonNull TelephonyDisplayInfo telephonyDisplayInfo) { 730 try { 731 sRegistry.notifyDisplayInfoChanged(slotIndex, subscriptionId, telephonyDisplayInfo); 732 } catch (RemoteException ex) { 733 // system process is dead 734 throw ex.rethrowFromSystemServer(); 735 } 736 } 737 738 /** 739 * Notify IMS call disconnect causes which contains {@link android.telephony.ims.ImsReasonInfo}. 740 * 741 * @param subId for which ims call disconnect. 742 * @param imsReasonInfo the reason for ims call disconnect. 743 */ notifyImsDisconnectCause(int subId, @NonNull ImsReasonInfo imsReasonInfo)744 public void notifyImsDisconnectCause(int subId, @NonNull ImsReasonInfo imsReasonInfo) { 745 try { 746 sRegistry.notifyImsDisconnectCause(subId, imsReasonInfo); 747 } catch (RemoteException ex) { 748 // system process is dead 749 throw ex.rethrowFromSystemServer(); 750 } 751 } 752 753 /** 754 * Notify single Radio Voice Call Continuity (SRVCC) state change for the currently active call 755 * on certain subscription. 756 * 757 * @param subId for which srvcc state changed. 758 * @param state srvcc state 759 */ notifySrvccStateChanged(int subId, @SrvccState int state)760 public void notifySrvccStateChanged(int subId, @SrvccState int state) { 761 try { 762 sRegistry.notifySrvccStateChanged(subId, state); 763 } catch (RemoteException ex) { 764 // system process is dead 765 throw ex.rethrowFromSystemServer(); 766 } 767 } 768 769 /** 770 * Notify precise call state changed on certain subscription, including foreground, background 771 * and ringcall states. 772 * 773 * @param slotIndex for which precise call state changed. Can be derived from subId except when 774 * subId is invalid. 775 * @param subId for which precise call state changed. 776 * @param callStates Array of PreciseCallState of foreground, background & ringing calls. 777 * @param imsCallIds Array of IMS call session ID{@link ImsCallSession#getCallId} for 778 * ringing, foreground & background calls. 779 * @param imsServiceTypes Array of IMS call service type for ringing, foreground & 780 * background calls. 781 * @param imsCallTypes Array of IMS call type for ringing, foreground & background calls. 782 */ notifyPreciseCallState(int slotIndex, int subId, @Annotation.PreciseCallStates int[] callStates, String[] imsCallIds, @Annotation.ImsCallServiceType int[] imsServiceTypes, @Annotation.ImsCallType int[] imsCallTypes)783 public void notifyPreciseCallState(int slotIndex, int subId, 784 @Annotation.PreciseCallStates int[] callStates, String[] imsCallIds, 785 @Annotation.ImsCallServiceType int[] imsServiceTypes, 786 @Annotation.ImsCallType int[] imsCallTypes) { 787 try { 788 sRegistry.notifyPreciseCallState(slotIndex, subId, callStates, 789 imsCallIds, imsServiceTypes, imsCallTypes); 790 } catch (RemoteException ex) { 791 // system process is dead 792 throw ex.rethrowFromSystemServer(); 793 } 794 } 795 796 /** 797 * Notify call disconnect causes which contains {@link DisconnectCause} and {@link 798 * android.telephony.PreciseDisconnectCause}. 799 * 800 * @param slotIndex for which call disconnected. Can be derived from subId except when subId is 801 * invalid. 802 * @param subId for which call disconnected. 803 * @param cause {@link DisconnectCause} for the disconnected call. 804 * @param preciseCause {@link android.telephony.PreciseDisconnectCause} for the disconnected 805 * call. 806 */ notifyDisconnectCause(int slotIndex, int subId, @DisconnectCauses int cause, @PreciseDisconnectCauses int preciseCause)807 public void notifyDisconnectCause(int slotIndex, int subId, @DisconnectCauses int cause, 808 @PreciseDisconnectCauses int preciseCause) { 809 try { 810 sRegistry.notifyDisconnectCause(slotIndex, subId, cause, preciseCause); 811 } catch (RemoteException ex) { 812 // system process is dead 813 throw ex.rethrowFromSystemServer(); 814 } 815 } 816 817 /** 818 * Notify {@link android.telephony.CellLocation} changed. 819 * 820 * <p>To be compatible with {@link TelephonyRegistry}, use {@link CellIdentity} which is 821 * parcelable, and convert to CellLocation in client code. 822 */ notifyCellLocation(int subId, @NonNull CellIdentity cellLocation)823 public void notifyCellLocation(int subId, @NonNull CellIdentity cellLocation) { 824 try { 825 sRegistry.notifyCellLocationForSubscriber(subId, cellLocation); 826 } catch (RemoteException ex) { 827 // system process is dead 828 throw ex.rethrowFromSystemServer(); 829 } 830 } 831 832 /** 833 * Notify {@link CellInfo} changed on certain subscription. e.g, when an observed cell info has 834 * changed or new cells have been added or removed on the given subscription. 835 * 836 * @param subId for which cellinfo changed. 837 * @param cellInfo A list of cellInfo associated with the given subscription. 838 */ notifyCellInfoChanged(int subId, @NonNull List<CellInfo> cellInfo)839 public void notifyCellInfoChanged(int subId, @NonNull List<CellInfo> cellInfo) { 840 try { 841 sRegistry.notifyCellInfoForSubscriber(subId, cellInfo); 842 } catch (RemoteException ex) { 843 throw ex.rethrowFromSystemServer(); 844 } 845 } 846 847 /** 848 * Notify that the active data subscription ID has changed. 849 * @param activeDataSubId The new subscription ID for active data 850 */ notifyActiveDataSubIdChanged(int activeDataSubId)851 public void notifyActiveDataSubIdChanged(int activeDataSubId) { 852 try { 853 sRegistry.notifyActiveDataSubIdChanged(activeDataSubId); 854 } catch (RemoteException ex) { 855 throw ex.rethrowFromSystemServer(); 856 } 857 } 858 859 /** 860 * Report that Registration or a Location/Routing/Tracking Area update has failed. 861 * 862 * @param slotIndex for which call disconnected. Can be derived from subId except when subId is 863 * invalid. 864 * @param subId for which cellinfo changed. 865 * @param cellIdentity the CellIdentity, which must include the globally unique identifier 866 * for the cell (for example, all components of the CGI or ECGI). 867 * @param chosenPlmn a 5 or 6 digit alphanumeric PLMN (MCC|MNC) among those broadcast by the 868 * cell that was chosen for the failed registration attempt. 869 * @param domain DOMAIN_CS, DOMAIN_PS or both in case of a combined procedure. 870 * @param causeCode the primary failure cause code of the procedure. 871 * For GSM/UMTS (MM), values are in TS 24.008 Sec 10.5.95 872 * For GSM/UMTS (GMM), values are in TS 24.008 Sec 10.5.147 873 * For LTE (EMM), cause codes are TS 24.301 Sec 9.9.3.9 874 * For NR (5GMM), cause codes are TS 24.501 Sec 9.11.3.2 875 * Integer.MAX_VALUE if this value is unused. 876 * @param additionalCauseCode the cause code of any secondary/combined procedure if appropriate. 877 * For UMTS, if a combined attach succeeds for PS only, then the GMM cause code shall be 878 * included as an additionalCauseCode. For LTE (ESM), cause codes are in 879 * TS 24.301 9.9.4.4. Integer.MAX_VALUE if this value is unused. 880 */ notifyRegistrationFailed(int slotIndex, int subId, @NonNull CellIdentity cellIdentity, @NonNull String chosenPlmn, int domain, int causeCode, int additionalCauseCode)881 public void notifyRegistrationFailed(int slotIndex, int subId, 882 @NonNull CellIdentity cellIdentity, @NonNull String chosenPlmn, 883 int domain, int causeCode, int additionalCauseCode) { 884 try { 885 sRegistry.notifyRegistrationFailed(slotIndex, subId, cellIdentity, 886 chosenPlmn, domain, causeCode, additionalCauseCode); 887 } catch (RemoteException ex) { 888 throw ex.rethrowFromSystemServer(); 889 } 890 } 891 892 /** 893 * Notify {@link BarringInfo} has changed for a specific subscription. 894 * 895 * @param slotIndex for the phone object that got updated barring info. 896 * @param subId for which the BarringInfo changed. 897 * @param barringInfo updated BarringInfo. 898 */ notifyBarringInfoChanged( int slotIndex, int subId, @NonNull BarringInfo barringInfo)899 public void notifyBarringInfoChanged( 900 int slotIndex, int subId, @NonNull BarringInfo barringInfo) { 901 try { 902 sRegistry.notifyBarringInfoChanged(slotIndex, subId, barringInfo); 903 } catch (RemoteException ex) { 904 // system server crash 905 throw ex.rethrowFromSystemServer(); 906 } 907 } 908 909 /** 910 * Notify {@link PhysicalChannelConfig} has changed for a specific subscription. 911 * 912 * @param slotIndex for which physical channel configs changed. 913 * @param subId the subId 914 * @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel. 915 */ notifyPhysicalChannelConfigForSubscriber(int slotIndex, int subId, List<PhysicalChannelConfig> configs)916 public void notifyPhysicalChannelConfigForSubscriber(int slotIndex, int subId, 917 List<PhysicalChannelConfig> configs) { 918 try { 919 sRegistry.notifyPhysicalChannelConfigForSubscriber(slotIndex, subId, configs); 920 } catch (RemoteException ex) { 921 // system server crash 922 throw ex.rethrowFromSystemServer(); 923 } 924 } 925 926 /** 927 * Notify that the data enabled has changed. 928 * 929 * @param enabled True if data is enabled, otherwise disabled. 930 * @param reason Reason for data enabled/disabled. See {@code REASON_*} in 931 * {@link TelephonyManager}. 932 */ notifyDataEnabled(int slotIndex, int subId, boolean enabled, @TelephonyManager.DataEnabledReason int reason)933 public void notifyDataEnabled(int slotIndex, int subId, boolean enabled, 934 @TelephonyManager.DataEnabledReason int reason) { 935 try { 936 sRegistry.notifyDataEnabled(slotIndex, subId, enabled, reason); 937 } catch (RemoteException ex) { 938 // system server crash 939 throw ex.rethrowFromSystemServer(); 940 } 941 } 942 943 /** 944 * Notify the allowed network types has changed for a specific subscription and the specific 945 * reason. 946 * @param slotIndex for which allowed network types changed. 947 * @param subId for which allowed network types changed. 948 * @param reason an allowed network type reasons. 949 * @param allowedNetworkType an allowed network type bitmask value. 950 */ notifyAllowedNetworkTypesChanged(int slotIndex, int subId, int reason, long allowedNetworkType)951 public void notifyAllowedNetworkTypesChanged(int slotIndex, int subId, 952 int reason, long allowedNetworkType) { 953 try { 954 sRegistry.notifyAllowedNetworkTypesChanged(slotIndex, subId, reason, 955 allowedNetworkType); 956 } catch (RemoteException ex) { 957 // system process is dead 958 throw ex.rethrowFromSystemServer(); 959 } 960 } 961 962 /** 963 * Notify that the link capacity estimate has changed. 964 * @param slotIndex for the phone object that gets the updated link capacity estimate 965 * @param subId for subscription that gets the updated link capacity estimate 966 * @param linkCapacityEstimateList a list of {@link LinkCapacityEstimate} 967 */ notifyLinkCapacityEstimateChanged(int slotIndex, int subId, List<LinkCapacityEstimate> linkCapacityEstimateList)968 public void notifyLinkCapacityEstimateChanged(int slotIndex, int subId, 969 List<LinkCapacityEstimate> linkCapacityEstimateList) { 970 try { 971 sRegistry.notifyLinkCapacityEstimateChanged(slotIndex, subId, linkCapacityEstimateList); 972 } catch (RemoteException ex) { 973 // system server crash 974 throw ex.rethrowFromSystemServer(); 975 } 976 } 977 getEventsFromCallback( @onNull TelephonyCallback telephonyCallback)978 public @NonNull Set<Integer> getEventsFromCallback( 979 @NonNull TelephonyCallback telephonyCallback) { 980 Set<Integer> eventList = new ArraySet<>(); 981 982 if (telephonyCallback instanceof TelephonyCallback.ServiceStateListener) { 983 eventList.add(TelephonyCallback.EVENT_SERVICE_STATE_CHANGED); 984 } 985 986 if (telephonyCallback instanceof TelephonyCallback.MessageWaitingIndicatorListener) { 987 eventList.add(TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED); 988 } 989 990 if (telephonyCallback instanceof TelephonyCallback.CallForwardingIndicatorListener) { 991 eventList.add(TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED); 992 } 993 994 if (telephonyCallback instanceof TelephonyCallback.CellLocationListener) { 995 eventList.add(TelephonyCallback.EVENT_CELL_LOCATION_CHANGED); 996 } 997 998 // Note: Legacy PhoneStateListeners use EVENT_LEGACY_CALL_STATE_CHANGED 999 if (telephonyCallback instanceof TelephonyCallback.CallStateListener) { 1000 eventList.add(TelephonyCallback.EVENT_CALL_STATE_CHANGED); 1001 } 1002 1003 if (telephonyCallback instanceof TelephonyCallback.DataConnectionStateListener) { 1004 eventList.add(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED); 1005 } 1006 1007 if (telephonyCallback instanceof TelephonyCallback.DataActivityListener) { 1008 eventList.add(TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED); 1009 } 1010 1011 if (telephonyCallback instanceof TelephonyCallback.SignalStrengthsListener) { 1012 eventList.add(TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED); 1013 } 1014 1015 if (telephonyCallback instanceof TelephonyCallback.CellInfoListener) { 1016 eventList.add(TelephonyCallback.EVENT_CELL_INFO_CHANGED); 1017 } 1018 1019 if (telephonyCallback instanceof TelephonyCallback.PreciseCallStateListener) { 1020 eventList.add(TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED); 1021 } 1022 1023 if (telephonyCallback instanceof TelephonyCallback.CallDisconnectCauseListener) { 1024 eventList.add(TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED); 1025 } 1026 1027 if (telephonyCallback instanceof TelephonyCallback.ImsCallDisconnectCauseListener) { 1028 eventList.add(TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED); 1029 } 1030 1031 if (telephonyCallback instanceof TelephonyCallback.PreciseDataConnectionStateListener) { 1032 eventList.add(TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED); 1033 } 1034 1035 if (telephonyCallback instanceof TelephonyCallback.SrvccStateListener) { 1036 eventList.add(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED); 1037 } 1038 1039 if (telephonyCallback instanceof TelephonyCallback.VoiceActivationStateListener) { 1040 eventList.add(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED); 1041 } 1042 1043 if (telephonyCallback instanceof TelephonyCallback.DataActivationStateListener) { 1044 eventList.add(TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED); 1045 } 1046 1047 if (telephonyCallback instanceof TelephonyCallback.UserMobileDataStateListener) { 1048 eventList.add(TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED); 1049 } 1050 1051 if (telephonyCallback instanceof TelephonyCallback.DisplayInfoListener) { 1052 eventList.add(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED); 1053 } 1054 1055 if (telephonyCallback instanceof TelephonyCallback.EmergencyNumberListListener) { 1056 eventList.add(TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED); 1057 } 1058 1059 if (telephonyCallback instanceof TelephonyCallback.OutgoingEmergencyCallListener) { 1060 eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_CALL); 1061 } 1062 1063 if (telephonyCallback instanceof TelephonyCallback.OutgoingEmergencySmsListener) { 1064 eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_SMS); 1065 } 1066 1067 if (telephonyCallback instanceof TelephonyCallback.PhoneCapabilityListener) { 1068 eventList.add(TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED); 1069 } 1070 1071 if (telephonyCallback instanceof TelephonyCallback.ActiveDataSubscriptionIdListener) { 1072 eventList.add(TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED); 1073 } 1074 1075 if (telephonyCallback instanceof TelephonyCallback.RadioPowerStateListener) { 1076 eventList.add(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED); 1077 } 1078 1079 if (telephonyCallback instanceof TelephonyCallback.CarrierNetworkListener) { 1080 eventList.add(TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED); 1081 } 1082 1083 if (telephonyCallback instanceof TelephonyCallback.RegistrationFailedListener) { 1084 eventList.add(TelephonyCallback.EVENT_REGISTRATION_FAILURE); 1085 } 1086 1087 if (telephonyCallback instanceof TelephonyCallback.CallAttributesListener) { 1088 eventList.add(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED); 1089 } 1090 1091 if (telephonyCallback instanceof TelephonyCallback.BarringInfoListener) { 1092 eventList.add(TelephonyCallback.EVENT_BARRING_INFO_CHANGED); 1093 } 1094 1095 if (telephonyCallback instanceof TelephonyCallback.PhysicalChannelConfigListener) { 1096 eventList.add(TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED); 1097 } 1098 1099 if (telephonyCallback instanceof TelephonyCallback.DataEnabledListener) { 1100 eventList.add(TelephonyCallback.EVENT_DATA_ENABLED_CHANGED); 1101 } 1102 1103 if (telephonyCallback instanceof TelephonyCallback.AllowedNetworkTypesListener) { 1104 eventList.add(TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED); 1105 } 1106 1107 if (telephonyCallback instanceof TelephonyCallback.LinkCapacityEstimateChangedListener) { 1108 eventList.add(TelephonyCallback.EVENT_LINK_CAPACITY_ESTIMATE_CHANGED); 1109 } 1110 1111 if (telephonyCallback instanceof TelephonyCallback.MediaQualityStatusChangedListener) { 1112 eventList.add(TelephonyCallback.EVENT_MEDIA_QUALITY_STATUS_CHANGED); 1113 } 1114 1115 if (telephonyCallback instanceof TelephonyCallback.EmergencyCallbackModeListener) { 1116 eventList.add(TelephonyCallback.EVENT_EMERGENCY_CALLBACK_MODE_CHANGED); 1117 } 1118 1119 1120 return eventList; 1121 } 1122 getEventsFromBitmask(int eventMask)1123 private @NonNull Set<Integer> getEventsFromBitmask(int eventMask) { 1124 1125 Set<Integer> eventList = new ArraySet<>(); 1126 1127 if ((eventMask & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { 1128 eventList.add(TelephonyCallback.EVENT_SERVICE_STATE_CHANGED); 1129 } 1130 1131 if ((eventMask & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { 1132 eventList.add(TelephonyCallback.EVENT_SIGNAL_STRENGTH_CHANGED); 1133 } 1134 1135 if ((eventMask & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { 1136 eventList.add(TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED); 1137 } 1138 1139 if ((eventMask & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { 1140 eventList.add(TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED); 1141 } 1142 1143 if ((eventMask & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { 1144 eventList.add(TelephonyCallback.EVENT_CELL_LOCATION_CHANGED); 1145 } 1146 1147 // Note: Legacy call state listeners can get the phone number which is not provided in the 1148 // new version in TelephonyCallback. 1149 if ((eventMask & PhoneStateListener.LISTEN_CALL_STATE) != 0) { 1150 eventList.add(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED); 1151 } 1152 1153 if ((eventMask & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { 1154 eventList.add(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED); 1155 } 1156 1157 if ((eventMask & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) { 1158 eventList.add(TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED); 1159 } 1160 1161 if ((eventMask & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { 1162 eventList.add(TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED); 1163 } 1164 1165 if ((eventMask & PhoneStateListener.LISTEN_CELL_INFO) != 0) { 1166 eventList.add(TelephonyCallback.EVENT_CELL_INFO_CHANGED); 1167 } 1168 1169 if ((eventMask & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) { 1170 eventList.add(TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED); 1171 } 1172 1173 if ((eventMask & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) { 1174 eventList.add(TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED); 1175 } 1176 1177 if ((eventMask & PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO) != 0) { 1178 eventList.add(TelephonyCallback.EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED); 1179 } 1180 1181 if ((eventMask & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) { 1182 eventList.add(TelephonyCallback.EVENT_OEM_HOOK_RAW); 1183 } 1184 1185 if ((eventMask & PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) != 0) { 1186 eventList.add(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED); 1187 } 1188 1189 if ((eventMask & PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE) != 0) { 1190 eventList.add(TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED); 1191 } 1192 1193 if ((eventMask & PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) != 0) { 1194 eventList.add(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED); 1195 } 1196 1197 if ((eventMask & PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE) != 0) { 1198 eventList.add(TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED); 1199 } 1200 1201 if ((eventMask & PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE) != 0) { 1202 eventList.add(TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED); 1203 } 1204 1205 if ((eventMask & PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED) != 0) { 1206 eventList.add(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED); 1207 } 1208 1209 if ((eventMask & PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE) != 0) { 1210 eventList.add(TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED); 1211 } 1212 1213 if ((eventMask & PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE) != 0) { 1214 eventList.add(TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED); 1215 } 1216 1217 if ((eventMask & PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED) != 0) { 1218 eventList.add(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED); 1219 } 1220 1221 if ((eventMask & PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST) != 0) { 1222 eventList.add(TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED); 1223 } 1224 1225 if ((eventMask & PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES) != 0) { 1226 eventList.add(TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED); 1227 } 1228 1229 if ((eventMask & PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED) != 0) { 1230 eventList.add(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED); 1231 } 1232 1233 if ((eventMask & PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES) != 0) { 1234 eventList.add(TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED); 1235 } 1236 1237 if ((eventMask & PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL) != 0) { 1238 eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_CALL); 1239 } 1240 1241 if ((eventMask & PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS) != 0) { 1242 eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_SMS); 1243 } 1244 1245 if ((eventMask & PhoneStateListener.LISTEN_REGISTRATION_FAILURE) != 0) { 1246 eventList.add(TelephonyCallback.EVENT_REGISTRATION_FAILURE); 1247 } 1248 1249 if ((eventMask & PhoneStateListener.LISTEN_BARRING_INFO) != 0) { 1250 eventList.add(TelephonyCallback.EVENT_BARRING_INFO_CHANGED); 1251 } 1252 return eventList; 1253 1254 } 1255 1256 /** 1257 * Registers a callback object to receive notification of changes in specified telephony states. 1258 * <p> 1259 * To register a callback, pass a {@link TelephonyCallback} which implements 1260 * interfaces of events. For example, 1261 * FakeServiceStateCallback extends {@link TelephonyCallback} implements 1262 * {@link TelephonyCallback.ServiceStateListener}. 1263 * 1264 * At registration, and when a specified telephony state changes, the telephony manager invokes 1265 * the appropriate callback method on the callback object and passes the current (updated) 1266 * values. 1267 * <p> 1268 * 1269 * If this TelephonyManager object has been created with 1270 * {@link TelephonyManager#createForSubscriptionId}, applies to the given subId. 1271 * Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}. 1272 * To register events for multiple subIds, pass a separate callback object to 1273 * each TelephonyManager object created with {@link TelephonyManager#createForSubscriptionId}. 1274 * 1275 * Note: if you call this method while in the middle of a binder transaction, you <b>must</b> 1276 * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A 1277 * {@link SecurityException} will be thrown otherwise. 1278 * 1279 * This API should be used sparingly -- large numbers of callbacks will cause system 1280 * instability. If a process has registered too many callbacks without unregistering them, it 1281 * may encounter an {@link IllegalStateException} when trying to register more callbacks. 1282 * 1283 * @param callback The {@link TelephonyCallback} object to register. 1284 */ registerTelephonyCallback(boolean renounceFineLocationAccess, boolean renounceCoarseLocationAccess, @NonNull @CallbackExecutor Executor executor, int subId, String pkgName, String attributionTag, @NonNull TelephonyCallback callback, boolean notifyNow)1285 public void registerTelephonyCallback(boolean renounceFineLocationAccess, 1286 boolean renounceCoarseLocationAccess, 1287 @NonNull @CallbackExecutor Executor executor, 1288 int subId, String pkgName, String attributionTag, @NonNull TelephonyCallback callback, 1289 boolean notifyNow) { 1290 if (callback == null) { 1291 throw new IllegalStateException("telephony service is null."); 1292 } 1293 callback.init(executor); 1294 listenFromCallback(renounceFineLocationAccess, renounceCoarseLocationAccess, subId, 1295 pkgName, attributionTag, callback, 1296 getEventsFromCallback(callback).stream().mapToInt(i -> i).toArray(), notifyNow); 1297 } 1298 1299 /** 1300 * Unregister an existing {@link TelephonyCallback}. 1301 * 1302 * @param callback The {@link TelephonyCallback} object to unregister. 1303 */ unregisterTelephonyCallback(int subId, String pkgName, String attributionTag, @NonNull TelephonyCallback callback, boolean notifyNow)1304 public void unregisterTelephonyCallback(int subId, String pkgName, String attributionTag, 1305 @NonNull TelephonyCallback callback, boolean notifyNow) { 1306 listenFromCallback(false, false, subId, 1307 pkgName, attributionTag, callback, new int[0], notifyNow); 1308 } 1309 1310 private static class CarrierPrivilegesCallbackWrapper extends ICarrierPrivilegesCallback.Stub 1311 implements ListenerExecutor { 1312 @NonNull private final WeakReference<CarrierPrivilegesCallback> mCallback; 1313 @NonNull private final Executor mExecutor; 1314 CarrierPrivilegesCallbackWrapper( @onNull CarrierPrivilegesCallback callback, @NonNull Executor executor)1315 CarrierPrivilegesCallbackWrapper( 1316 @NonNull CarrierPrivilegesCallback callback, @NonNull Executor executor) { 1317 mCallback = new WeakReference<>(callback); 1318 mExecutor = executor; 1319 } 1320 1321 @Override onCarrierPrivilegesChanged( @onNull List<String> privilegedPackageNames, @NonNull int[] privilegedUids)1322 public void onCarrierPrivilegesChanged( 1323 @NonNull List<String> privilegedPackageNames, @NonNull int[] privilegedUids) { 1324 // AIDL interface does not support Set, keep the List/Array and translate them here 1325 Set<String> privilegedPkgNamesSet = Set.copyOf(privilegedPackageNames); 1326 Set<Integer> privilegedUidsSet = Arrays.stream(privilegedUids).boxed().collect( 1327 Collectors.toSet()); 1328 Binder.withCleanCallingIdentity( 1329 () -> 1330 executeSafely( 1331 mExecutor, 1332 mCallback::get, 1333 cpc -> 1334 cpc.onCarrierPrivilegesChanged( 1335 privilegedPkgNamesSet, privilegedUidsSet))); 1336 } 1337 1338 @Override onCarrierServiceChanged(@ullable String packageName, int uid)1339 public void onCarrierServiceChanged(@Nullable String packageName, int uid) { 1340 Binder.withCleanCallingIdentity( 1341 () -> 1342 executeSafely( 1343 mExecutor, 1344 mCallback::get, 1345 cpc -> cpc.onCarrierServiceChanged(packageName, uid))); 1346 } 1347 } 1348 1349 @NonNull 1350 @GuardedBy("sCarrierPrivilegeCallbacks") 1351 private static final WeakHashMap<CarrierPrivilegesCallback, 1352 WeakReference<CarrierPrivilegesCallbackWrapper>> 1353 sCarrierPrivilegeCallbacks = new WeakHashMap<>(); 1354 1355 /** 1356 * Registers a {@link CarrierPrivilegesCallback} on the given {@code logicalSlotIndex} to 1357 * receive callbacks when the set of packages with carrier privileges changes. The callback will 1358 * immediately be called with the latest state. 1359 * 1360 * @param logicalSlotIndex The SIM slot to listen on 1361 * @param executor The executor where {@code listener} will be invoked 1362 * @param callback The callback to register 1363 */ addCarrierPrivilegesCallback( int logicalSlotIndex, @NonNull @CallbackExecutor Executor executor, @NonNull CarrierPrivilegesCallback callback)1364 public void addCarrierPrivilegesCallback( 1365 int logicalSlotIndex, 1366 @NonNull @CallbackExecutor Executor executor, 1367 @NonNull CarrierPrivilegesCallback callback) { 1368 if (callback == null || executor == null) { 1369 throw new IllegalArgumentException("callback and executor must be non-null"); 1370 } 1371 synchronized (sCarrierPrivilegeCallbacks) { 1372 WeakReference<CarrierPrivilegesCallbackWrapper> existing = 1373 sCarrierPrivilegeCallbacks.get(callback); 1374 if (existing != null && existing.get() != null) { 1375 Log.d(TAG, "addCarrierPrivilegesCallback: callback already registered"); 1376 return; 1377 } 1378 CarrierPrivilegesCallbackWrapper wrapper = 1379 new CarrierPrivilegesCallbackWrapper(callback, executor); 1380 sCarrierPrivilegeCallbacks.put(callback, new WeakReference<>(wrapper)); 1381 try { 1382 sRegistry.addCarrierPrivilegesCallback( 1383 logicalSlotIndex, 1384 wrapper, 1385 mContext.getOpPackageName(), 1386 mContext.getAttributionTag()); 1387 } catch (RemoteException e) { 1388 throw e.rethrowFromSystemServer(); 1389 } 1390 } 1391 } 1392 1393 /** 1394 * Unregisters a {@link CarrierPrivilegesCallback}. 1395 * 1396 * @param callback The callback to unregister 1397 */ removeCarrierPrivilegesCallback(@onNull CarrierPrivilegesCallback callback)1398 public void removeCarrierPrivilegesCallback(@NonNull CarrierPrivilegesCallback callback) { 1399 if (callback == null) { 1400 throw new IllegalArgumentException("listener must be non-null"); 1401 } 1402 synchronized (sCarrierPrivilegeCallbacks) { 1403 WeakReference<CarrierPrivilegesCallbackWrapper> ref = 1404 sCarrierPrivilegeCallbacks.remove(callback); 1405 if (ref == null) return; 1406 CarrierPrivilegesCallbackWrapper wrapper = ref.get(); 1407 if (wrapper == null) return; 1408 try { 1409 sRegistry.removeCarrierPrivilegesCallback(wrapper, mContext.getOpPackageName()); 1410 } catch (RemoteException e) { 1411 throw e.rethrowFromSystemServer(); 1412 } 1413 } 1414 } 1415 1416 /** 1417 * Notify listeners that the set of packages with carrier privileges has changed. 1418 * 1419 * @param logicalSlotIndex The SIM slot the change occurred on 1420 * @param privilegedPackageNames The updated set of packages names with carrier privileges 1421 * @param privilegedUids The updated set of UIDs with carrier privileges 1422 */ notifyCarrierPrivilegesChanged( int logicalSlotIndex, @NonNull Set<String> privilegedPackageNames, @NonNull Set<Integer> privilegedUids)1423 public void notifyCarrierPrivilegesChanged( 1424 int logicalSlotIndex, 1425 @NonNull Set<String> privilegedPackageNames, 1426 @NonNull Set<Integer> privilegedUids) { 1427 if (privilegedPackageNames == null || privilegedUids == null) { 1428 throw new IllegalArgumentException( 1429 "privilegedPackageNames and privilegedUids must be non-null"); 1430 } 1431 try { 1432 // AIDL doesn't support Set yet. Convert Set to List/Array 1433 List<String> pkgList = List.copyOf(privilegedPackageNames); 1434 int[] uids = privilegedUids.stream().mapToInt(Number::intValue).toArray(); 1435 sRegistry.notifyCarrierPrivilegesChanged(logicalSlotIndex, pkgList, uids); 1436 } catch (RemoteException e) { 1437 throw e.rethrowFromSystemServer(); 1438 } 1439 } 1440 1441 /** 1442 * Notify listeners that the {@link CarrierService} for current user has changed. 1443 * 1444 * @param logicalSlotIndex the SIM slot the change occurred on 1445 * @param packageName the package name of the changed {@link CarrierService} 1446 * @param uid the UID of the changed {@link CarrierService} 1447 */ notifyCarrierServiceChanged(int logicalSlotIndex, @Nullable String packageName, int uid)1448 public void notifyCarrierServiceChanged(int logicalSlotIndex, @Nullable String packageName, 1449 int uid) { 1450 try { 1451 sRegistry.notifyCarrierServiceChanged(logicalSlotIndex, packageName, uid); 1452 } catch (RemoteException e) { 1453 throw e.rethrowFromSystemServer(); 1454 } 1455 } 1456 1457 /** 1458 * Register a {@link android.telephony.CarrierConfigManager.CarrierConfigChangeListener} to get 1459 * notification when carrier configurations have changed. 1460 * 1461 * @param executor The executor on which the callback will be executed. 1462 * @param listener The CarrierConfigChangeListener to be registered with. 1463 */ addCarrierConfigChangedListener( @onNull @allbackExecutor Executor executor, @NonNull CarrierConfigManager.CarrierConfigChangeListener listener)1464 public void addCarrierConfigChangedListener( 1465 @NonNull @CallbackExecutor Executor executor, 1466 @NonNull CarrierConfigManager.CarrierConfigChangeListener listener) { 1467 Objects.requireNonNull(executor, "Executor should be non-null."); 1468 Objects.requireNonNull(listener, "Listener should be non-null."); 1469 if (mCarrierConfigChangeListenerMap.get(listener) != null) { 1470 Log.e(TAG, "registerCarrierConfigChangeListener: listener already present"); 1471 return; 1472 } 1473 1474 ICarrierConfigChangeListener callback = new ICarrierConfigChangeListener.Stub() { 1475 @Override 1476 public void onCarrierConfigChanged(int slotIndex, int subId, int carrierId, 1477 int specificCarrierId) { 1478 Log.d(TAG, "onCarrierConfigChanged call in ICarrierConfigChangeListener callback"); 1479 final long identify = Binder.clearCallingIdentity(); 1480 try { 1481 executor.execute(() -> listener.onCarrierConfigChanged(slotIndex, subId, 1482 carrierId, specificCarrierId)); 1483 } finally { 1484 Binder.restoreCallingIdentity(identify); 1485 } 1486 } 1487 }; 1488 1489 try { 1490 sRegistry.addCarrierConfigChangeListener(callback, 1491 mContext.getOpPackageName(), mContext.getAttributionTag()); 1492 mCarrierConfigChangeListenerMap.put(listener, callback); 1493 } catch (RemoteException re) { 1494 // system server crashes 1495 throw re.rethrowFromSystemServer(); 1496 } 1497 } 1498 1499 /** 1500 * Unregister to stop the notification when carrier configurations changed. 1501 * 1502 * @param listener The CarrierConfigChangeListener to be unregistered with. 1503 */ removeCarrierConfigChangedListener( @onNull CarrierConfigManager.CarrierConfigChangeListener listener)1504 public void removeCarrierConfigChangedListener( 1505 @NonNull CarrierConfigManager.CarrierConfigChangeListener listener) { 1506 Objects.requireNonNull(listener, "Listener should be non-null."); 1507 if (mCarrierConfigChangeListenerMap.get(listener) == null) { 1508 Log.e(TAG, "removeCarrierConfigChangedListener: listener was not present"); 1509 return; 1510 } 1511 1512 try { 1513 sRegistry.removeCarrierConfigChangeListener( 1514 mCarrierConfigChangeListenerMap.get(listener), mContext.getOpPackageName()); 1515 mCarrierConfigChangeListenerMap.remove(listener); 1516 } catch (RemoteException re) { 1517 // System sever crashes 1518 throw re.rethrowFromSystemServer(); 1519 } 1520 } 1521 1522 /** 1523 * Notify the registrants the carrier configurations have changed. 1524 * 1525 * @param slotIndex The SIM slot index on which to monitor and get notification. 1526 * @param subId The subscription on the SIM slot. May be 1527 * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}. 1528 * @param carrierId The optional carrier Id, may be 1529 * {@link TelephonyManager#UNKNOWN_CARRIER_ID}. 1530 * @param specificCarrierId The optional specific carrier Id, may be {@link 1531 * TelephonyManager#UNKNOWN_CARRIER_ID}. 1532 */ notifyCarrierConfigChanged(int slotIndex, int subId, int carrierId, int specificCarrierId)1533 public void notifyCarrierConfigChanged(int slotIndex, int subId, int carrierId, 1534 int specificCarrierId) { 1535 // Only validate slotIndex, all others are optional and allowed to be invalid 1536 if (!SubscriptionManager.isValidPhoneId(slotIndex)) { 1537 Log.e(TAG, "notifyCarrierConfigChanged, ignored: invalid slotIndex " + slotIndex); 1538 return; 1539 } 1540 try { 1541 sRegistry.notifyCarrierConfigChanged(slotIndex, subId, carrierId, specificCarrierId); 1542 } catch (RemoteException re) { 1543 throw re.rethrowFromSystemServer(); 1544 } 1545 } 1546 1547 /** 1548 * Notify Callback Mode has been started. 1549 * @param phoneId Sender phone ID. 1550 * @param subId Sender subscription ID. 1551 * @param type for callback mode entry. 1552 * See {@link TelephonyManager.EmergencyCallbackModeType}. 1553 */ notifyCallBackModeStarted(int phoneId, int subId, @TelephonyManager.EmergencyCallbackModeType int type)1554 public void notifyCallBackModeStarted(int phoneId, int subId, 1555 @TelephonyManager.EmergencyCallbackModeType int type) { 1556 try { 1557 Log.d(TAG, "notifyCallBackModeStarted:type=" + type); 1558 sRegistry.notifyCallbackModeStarted(phoneId, subId, type); 1559 } catch (RemoteException ex) { 1560 // system process is dead 1561 throw ex.rethrowFromSystemServer(); 1562 } 1563 } 1564 1565 /** 1566 * Notify Callback Mode has been stopped. 1567 * @param phoneId Sender phone ID. 1568 * @param subId Sender subscription ID. 1569 * @param type for callback mode entry. 1570 * See {@link TelephonyManager.EmergencyCallbackModeType}. 1571 * @param reason for changing callback mode. 1572 * See {@link TelephonyManager.EmergencyCallbackModeStopReason}. 1573 */ notifyCallbackModeStopped(int phoneId, int subId, @TelephonyManager.EmergencyCallbackModeType int type, @TelephonyManager.EmergencyCallbackModeStopReason int reason)1574 public void notifyCallbackModeStopped(int phoneId, int subId, 1575 @TelephonyManager.EmergencyCallbackModeType int type, 1576 @TelephonyManager.EmergencyCallbackModeStopReason int reason) { 1577 try { 1578 Log.d(TAG, "notifyCallbackModeStopped:type=" + type + ", reason=" + reason); 1579 sRegistry.notifyCallbackModeStopped(phoneId, subId, type, reason); 1580 } catch (RemoteException ex) { 1581 // system process is dead 1582 throw ex.rethrowFromSystemServer(); 1583 } 1584 } 1585 } 1586