From 1f6cfa539999edc216677e0e6fa35db4672ffd88 Mon Sep 17 00:00:00 2001 From: Chen Xu Date: Sun, 13 Oct 2019 17:30:32 -0700 Subject: non-mainline telephony related AIDL refactor/decoupling 1. decouple IOnSubscriptionChangedListener AIDL from telephonyMainline 2. other refactor. moving APIs which will not be included in telephony mainline to frameworks/base/core/java/android/telephony. Moving internal classes like AIDL which will not be included in telephony mainline to framework/base/core/java/com/android/internal/telephony Bug: 140908357 Test: Build & unit test Change-Id: I9413ef758cceadd251d03f3b5ea1054cc48ef044 --- api/system-current.txt | 16 +- core/java/android/app/SystemServiceRegistry.java | 4 +- core/java/android/content/Context.java | 3 +- .../os/telephony/TelephonyRegistryManager.java | 549 --------- .../android/service/carrier/CarrierService.java | 2 +- .../java/android/telephony/PhoneStateListener.java | 1280 ++++++++++++++++++++ .../telephony/TelephonyRegistryManager.java | 697 +++++++++++ .../telephony/IOnSubscriptionsChangedListener.aidl | 22 + .../internal/telephony/IPhoneStateListener.aidl | 69 ++ .../internal/telephony/ITelephonyRegistry.aidl | 103 ++ .../java/android/telephony/PhoneStateListener.java | 1280 -------------------- .../android/telephony/SubscriptionManager.java | 131 +- .../telephony/IOnSubscriptionsChangedListener.aidl | 22 - .../internal/telephony/IPhoneStateListener.aidl | 66 - .../internal/telephony/ITelephonyRegistry.aidl | 103 -- 15 files changed, 2226 insertions(+), 2121 deletions(-) delete mode 100644 core/java/android/os/telephony/TelephonyRegistryManager.java create mode 100644 core/java/android/telephony/PhoneStateListener.java create mode 100644 core/java/android/telephony/TelephonyRegistryManager.java create mode 100644 core/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl create mode 100644 core/java/com/android/internal/telephony/IPhoneStateListener.aidl create mode 100644 core/java/com/android/internal/telephony/ITelephonyRegistry.aidl delete mode 100644 telephony/java/android/telephony/PhoneStateListener.java delete mode 100644 telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl delete mode 100644 telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl delete mode 100644 telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl diff --git a/api/system-current.txt b/api/system-current.txt index 8ed79a3f2338..6048ba8835ca 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5684,14 +5684,6 @@ package android.os.storage { } -package android.os.telephony { - - public class TelephonyRegistryManager { - method public void notifyCarrierNetworkChange(boolean); - } - -} - package android.permission { public final class PermissionControllerManager { @@ -8365,6 +8357,14 @@ package android.telephony { field public static final int SRVCC_STATE_HANDOVER_STARTED = 0; // 0x0 } + public class TelephonyRegistryManager { + method public void addOnOpportunisticSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener, @NonNull java.util.concurrent.Executor); + method public void addOnSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnSubscriptionsChangedListener, @NonNull java.util.concurrent.Executor); + method public void notifyCarrierNetworkChange(boolean); + method public void removeOnOpportunisticSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener); + method public void removeOnSubscriptionsChangedListener(@NonNull android.telephony.SubscriptionManager.OnSubscriptionsChangedListener); + } + public final class UiccAccessRule implements android.os.Parcelable { ctor public UiccAccessRule(byte[], @Nullable String, long); method public int describeContents(); diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index e81dc1c59040..8350fa13b097 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -152,7 +152,7 @@ import android.os.health.SystemHealthManager; import android.os.image.DynamicSystemManager; import android.os.image.IDynamicSystemService; import android.os.storage.StorageManager; -import android.os.telephony.TelephonyRegistryManager; +import android.telephony.TelephonyRegistryManager; import android.permission.PermissionControllerManager; import android.permission.PermissionManager; import android.print.IPrintManager; @@ -611,7 +611,7 @@ public final class SystemServiceRegistry { new CachedServiceFetcher() { @Override public TelephonyRegistryManager createService(ContextImpl ctx) { - return new TelephonyRegistryManager(); + return new TelephonyRegistryManager(ctx); }}); registerService(Context.TELEPHONY_SUBSCRIPTION_SERVICE, SubscriptionManager.class, diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 08817e05e0a5..6a4d1fa7ebdb 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -63,6 +63,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.storage.StorageManager; import android.provider.MediaStore; +import android.telephony.TelephonyRegistryManager; import android.util.AttributeSet; import android.view.Display; import android.view.DisplayAdjustments; @@ -4709,7 +4710,7 @@ public abstract class Context { /** * Use with {@link #getSystemService(String)} to retrieve an - * {@link android.os.telephony.TelephonyRegistryManager}. + * {@link TelephonyRegistryManager}. * @hide */ @SystemApi diff --git a/core/java/android/os/telephony/TelephonyRegistryManager.java b/core/java/android/os/telephony/TelephonyRegistryManager.java deleted file mode 100644 index 133233124b70..000000000000 --- a/core/java/android/os/telephony/TelephonyRegistryManager.java +++ /dev/null @@ -1,549 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.os.telephony; - -import android.annotation.SystemApi; -import android.net.LinkProperties; -import android.net.NetworkCapabilities; -import android.os.Bundle; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.telephony.Annotation.ApnType; -import android.telephony.Annotation.CallState; -import android.telephony.Annotation.DataActivityType; -import android.telephony.Annotation.DataFailureCause; -import android.telephony.Annotation.DataState; -import android.telephony.Annotation.NetworkType; -import android.telephony.Annotation.PreciseCallStates; -import android.telephony.Annotation.RadioPowerState; -import android.telephony.Annotation.SimActivationState; -import android.telephony.Annotation.SrvccState; -import android.telephony.CallQuality; -import android.telephony.CellInfo; -import android.telephony.DisconnectCause; -import android.telephony.PhoneCapability; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import android.telephony.TelephonyManager; -import android.telephony.data.ApnSetting; -import android.telephony.ims.ImsReasonInfo; -import com.android.internal.telephony.ITelephonyRegistry; -import java.util.List; - -/** - * A centralized place to notify telephony related status changes, e.g, {@link ServiceState} update - * or {@link PhoneCapability} changed. This might trigger callback from applications side through - * {@link android.telephony.PhoneStateListener} - * - * TODO: limit API access to only carrier apps with certain permissions or apps running on - * privileged UID. - * - * @hide - */ -@SystemApi -public class TelephonyRegistryManager { - - private static final String TAG = "TelephonyRegistryManager"; - private static ITelephonyRegistry sRegistry; - - /** @hide **/ - public TelephonyRegistryManager() { - if (sRegistry == null) { - sRegistry = ITelephonyRegistry.Stub.asInterface( - ServiceManager.getService("telephony.registry")); - } - } - - /** - * Informs the system of an intentional upcoming carrier network change by a carrier app. - * This call only used to allow the system to provide alternative UI while telephony is - * performing an action that may result in intentional, temporary network lack of connectivity. - *

- * Based on the active parameter passed in, this method will either show or hide the alternative - * UI. There is no timeout associated with showing this UX, so a carrier app must be sure to - * call with active set to false sometime after calling with it set to {@code true}. - *

- * Requires Permission: calling app has carrier privileges. - * - * @param active Whether the carrier network change is or shortly will be - * active. Set this value to true to begin showing alternative UI and false to stop. - * @see TelephonyManager#hasCarrierPrivileges - */ - public void notifyCarrierNetworkChange(boolean active) { - try { - sRegistry.notifyCarrierNetworkChange(active); - } catch (RemoteException ex) { - // system server crash - } - } - - /** - * Notify call state changed on certain subscription. - * - * @param subId for which call state changed. - * @param slotIndex for which call state changed. Can be derived from subId except when subId is - * invalid. - * @param state latest call state. e.g, offhook, ringing - * @param incomingNumer incoming phone number. - * - * @hide - */ - public void notifyCallStateChanged(int subId, int slotIndex, @CallState int state, - String incomingNumer) { - try { - sRegistry.notifyCallState(slotIndex, subId, state, incomingNumer); - } catch (RemoteException ex) { - // system server crash - } - } - - /** - * Notify {@link ServiceState} update on certain subscription. - * - * @param subId for which the service state changed. - * @param slotIndex for which the service state changed. Can be derived from subId except - * subId is invalid. - * @param state service state e.g, in service, out of service or roaming status. - * - * @hide - */ - public void notifyServiceStateChanged(int subId, int slotIndex, ServiceState state) { - try { - sRegistry.notifyServiceStateForPhoneId(slotIndex, subId, state); - } catch (RemoteException ex) { - // system server crash - } - } - - /** - * Notify {@link SignalStrength} update on certain subscription. - * - * @param subId for which the signalstrength changed. - * @param slotIndex for which the signalstrength changed. Can be derived from subId except when - * subId is invalid. - * @param signalStrength e.g, signalstrength level {@see SignalStrength#getLevel()} - * - * @hide - */ - public void notifySignalStrengthChanged(int subId, int slotIndex, - SignalStrength signalStrength) { - try { - sRegistry.notifySignalStrengthForPhoneId(slotIndex, subId, signalStrength); - } catch (RemoteException ex) { - // system server crash - } - } - - /** - * Notify changes to the message-waiting indicator on certain subscription. e.g, The status bar - * uses message waiting indicator to determine when to display the voicemail icon. - * - * @param subId for which message waiting indicator changed. - * @param slotIndex for which message waiting indicator changed. Can be derived from subId - * except when subId is invalid. - * @param msgWaitingInd {@code true} indicates there is message-waiting indicator, {@code false} - * otherwise. - * - * @hide - */ - public void notifyMessageWaitingChanged(int subId, int slotIndex, boolean msgWaitingInd) { - try { - sRegistry.notifyMessageWaitingChangedForPhoneId(slotIndex, subId, msgWaitingInd); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify changes to the call-forwarding status on certain subscription. - * - * @param subId for which call forwarding status changed. - * @param callForwardInd {@code true} indicates there is call forwarding, {@code false} - * otherwise. - * - * @hide - */ - public void notifyCallForwardingChanged(int subId, boolean callForwardInd) { - try { - sRegistry.notifyCallForwardingChangedForSubscriber(subId, callForwardInd); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify changes to activity state changes on certain subscription. - * - * @param subId for which data activity state changed. - * @param dataActivityType indicates the latest data activity type e.g, {@link - * TelephonyManager#DATA_ACTIVITY_IN} - * - * @hide - */ - public void notifyDataActivityChanged(int subId, @DataActivityType int dataActivityType) { - try { - sRegistry.notifyDataActivityForSubscriber(subId, dataActivityType); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify changes to default (Internet) data connection state on certain subscription. - * - * @param subId for which data connection state changed. - * @param slotIndex for which data connections state changed. Can be derived from subId except - * when subId is invalid. - * @param state latest data connection state, e.g, - * @param isDataConnectivityPossible indicates if data is allowed - * @param apn the APN {@link ApnSetting#getApnName()} of this data connection. - * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN. - * @param linkProperties {@link LinkProperties} associated with this data connection. - * @param networkCapabilities {@link NetworkCapabilities} associated with this data connection. - * @param networkType associated with this data connection. - * @param roaming {@code true} indicates in roaming, {@false} otherwise. - * @see TelephonyManager#DATA_DISCONNECTED - * @see TelephonyManager#isDataConnectivityPossible() - * - * @hide - */ - public void notifyDataConnectionForSubscriber(int slotIndex, int subId, @DataState int state, - boolean isDataConnectivityPossible, - @ApnType String apn, String apnType, LinkProperties linkProperties, - NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { - try { - sRegistry.notifyDataConnectionForSubscriber(slotIndex, subId, state, - isDataConnectivityPossible, - apn, apnType, linkProperties, networkCapabilities, networkType, roaming); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify {@link CallQuality} change on certain subscription. - * - * @param subId for which call quality state changed. - * @param slotIndex for which call quality state changed. Can be derived from subId except when - * subId is invalid. - * @param callQuality Information about call quality e.g, call quality level - * @param networkType associated with this data connection. e.g, LTE - * - * @hide - */ - public void notifyCallQualityChanged(int subId, int slotIndex, CallQuality callQuality, - @NetworkType int networkType) { - try { - sRegistry.notifyCallQualityChanged(callQuality, slotIndex, subId, networkType); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify emergency number list changed on certain subscription. - * - * @param subId for which emergency number list changed. - * @param slotIndex for which emergency number list changed. Can be derived from subId except - * when subId is invalid. - * - * @hide - */ - public void notifyEmergencyNumberList(int subId, int slotIndex) { - try { - sRegistry.notifyEmergencyNumberList(slotIndex, subId); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify radio power state changed on certain subscription. - * - * @param subId for which radio power state changed. - * @param slotIndex for which radio power state changed. Can be derived from subId except when - * subId is invalid. - * @param radioPowerState the current modem radio state. - * - * @hide - */ - public void notifyRadioPowerStateChanged(int subId, int slotIndex, - @RadioPowerState int radioPowerState) { - try { - sRegistry.notifyRadioPowerStateChanged(slotIndex, subId, radioPowerState); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify {@link PhoneCapability} changed. - * - * @param phoneCapability the capability of the modem group. - * - * @hide - */ - public void notifyPhoneCapabilityChanged(PhoneCapability phoneCapability) { - try { - sRegistry.notifyPhoneCapabilityChanged(phoneCapability); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify data activation state changed on certain subscription. - * @see TelephonyManager#getDataActivationState() - * - * @param subId for which data activation state changed. - * @param slotIndex for which data activation state changed. Can be derived from subId except - * when subId is invalid. - * @param activationState sim activation state e.g, activated. - * - * @hide - */ - public void notifyDataActivationStateChanged(int subId, int slotIndex, - @SimActivationState int activationState) { - try { - sRegistry.notifySimActivationStateChangedForPhoneId(slotIndex, subId, - TelephonyManager.SIM_ACTIVATION_TYPE_DATA, activationState); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify voice activation state changed on certain subscription. - * @see TelephonyManager#getVoiceActivationState() - * - * @param subId for which voice activation state changed. - * @param slotIndex for which voice activation state changed. Can be derived from subId except - * subId is invalid. - * @param activationState sim activation state e.g, activated. - * - * @hide - */ - public void notifyVoiceActivationStateChanged(int subId, int slotIndex, - @SimActivationState int activationState) { - try { - sRegistry.notifySimActivationStateChangedForPhoneId(slotIndex, subId, - TelephonyManager.SIM_ACTIVATION_TYPE_VOICE, activationState); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify User mobile data state changed on certain subscription. e.g, mobile data is enabled - * or disabled. - * - * @param subId for which mobile data state has changed. - * @param slotIndex for which mobile data state has changed. Can be derived from subId except - * when subId is invalid. - * @param state {@code true} indicates mobile data is enabled/on. {@code false} otherwise. - * - * @hide - */ - public void notifyUserMobileDataStateChanged(int slotIndex, int subId, boolean state) { - try { - sRegistry.notifyUserMobileDataStateChangedForPhoneId(slotIndex, subId, state); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * TODO: this is marked as deprecated, can we move this one safely? - * - * @param subId - * @param slotIndex - * @param rawData - * - * @hide - */ - public void notifyOemHookRawEventForSubscriber(int subId, int slotIndex, byte[] rawData) { - try { - sRegistry.notifyOemHookRawEventForSubscriber(slotIndex, subId, rawData); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify IMS call disconnect causes which contains {@link android.telephony.ims.ImsReasonInfo}. - * - * @param subId for which ims call disconnect. - * @param imsReasonInfo the reason for ims call disconnect. - * - * @hide - */ - public void notifyImsDisconnectCause(int subId, ImsReasonInfo imsReasonInfo) { - try { - sRegistry.notifyImsDisconnectCause(subId, imsReasonInfo); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify precise data connection failed cause on certain subscription. - * - * @param subId for which data connection failed. - * @param slotIndex for which data conenction failed. Can be derived from subId except when - * subId is invalid. - * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN. - * @param apn the APN {@link ApnSetting#getApnName()} of this data connection. - * @param failCause data fail cause. - * - * @hide - */ - public void notifyPreciseDataConnectionFailed(int subId, int slotIndex, String apnType, - String apn, @DataFailureCause int failCause) { - try { - sRegistry.notifyPreciseDataConnectionFailed(slotIndex, subId, apnType, apn, failCause); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify single Radio Voice Call Continuity (SRVCC) state change for the currently active call - * on certain subscription. - * - * @param subId for which srvcc state changed. - * @param state srvcc state - * - * @hide - */ - public void notifySrvccStateChanged(int subId, @SrvccState int state) { - try { - sRegistry.notifySrvccStateChanged(subId, state); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify over the air sim provisioning(OTASP) mode changed on certain subscription. - * - * @param subId for which otasp mode changed. - * @param otaspMode latest mode for OTASP e.g, OTASP needed. - * - * @hide - */ - public void notifyOtaspChanged(int subId, int otaspMode) { - try { - sRegistry.notifyOtaspChanged(subId, otaspMode); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify precise call state changed on certain subscription, including foreground, background - * and ringcall states. - * - * @param subId for which precise call state changed. - * @param slotIndex for which precise call state changed. Can be derived from subId except when - * subId is invalid. - * @param ringCallPreciseState ringCall state. - * @param foregroundCallPreciseState foreground call state. - * @param backgroundCallPreciseState background call state. - * - * @hide - */ - public void notifyPreciseCallState(int subId, int slotIndex, - @PreciseCallStates int ringCallPreciseState, - @PreciseCallStates int foregroundCallPreciseState, - @PreciseCallStates int backgroundCallPreciseState) { - try { - sRegistry.notifyPreciseCallState(slotIndex, subId, ringCallPreciseState, - foregroundCallPreciseState, backgroundCallPreciseState); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify call disconnect causes which contains {@link DisconnectCause} and {@link - * android.telephony.PreciseDisconnectCause}. - * - * @param subId for which call disconnected. - * @param slotIndex for which call disconnected. Can be derived from subId except when subId is - * invalid. - * @param cause {@link DisconnectCause} for the disconnected call. - * @param preciseCause {@link android.telephony.PreciseDisconnectCause} for the disconnected - * call. - * - * @hide - */ - public void notifyDisconnectCause(int slotIndex, int subId, int cause, int preciseCause) { - try { - sRegistry.notifyDisconnectCause(slotIndex, subId, cause, preciseCause); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify data connection failed on certain subscription. - * - * @param subId for which data connection failed. - * @param slotIndex for which data conenction faled. Can be derived from subId except when subId - * is invalid. - * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN. Note each data - * connection can support multiple anyTypes. - * - * @hide - */ - public void notifyDataConnectionFailed(int subId, int slotIndex, String apnType) { - try { - sRegistry.notifyDataConnectionFailedForSubscriber(slotIndex, subId, apnType); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * TODO change from bundle to CellLocation? - * @hide - */ - public void notifyCellLocation(int subId, Bundle cellLocation) { - try { - sRegistry.notifyCellLocationForSubscriber(subId, cellLocation); - } catch (RemoteException ex) { - // system process is dead - } - } - - /** - * Notify {@link CellInfo} changed on certain subscription. e.g, when an observed cell info has - * changed or new cells have been added or removed on the given subscription. - * - * @param subId for which cellinfo changed. - * @param cellInfo A list of cellInfo associated with the given subscription. - * - * @hide - */ - public void notifyCellInfoChanged(int subId, List cellInfo) { - try { - sRegistry.notifyCellInfoForSubscriber(subId, cellInfo); - } catch (RemoteException ex) { - - } - } - -} diff --git a/core/java/android/service/carrier/CarrierService.java b/core/java/android/service/carrier/CarrierService.java index 9184d6d51f44..eefc1b70bac9 100644 --- a/core/java/android/service/carrier/CarrierService.java +++ b/core/java/android/service/carrier/CarrierService.java @@ -22,7 +22,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.PersistableBundle; import android.os.ResultReceiver; -import android.os.telephony.TelephonyRegistryManager; +import android.telephony.TelephonyRegistryManager; import android.util.Log; /** diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java new file mode 100644 index 000000000000..a65c8fdf50c9 --- /dev/null +++ b/core/java/android/telephony/PhoneStateListener.java @@ -0,0 +1,1280 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +import android.Manifest; +import android.annotation.NonNull; +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; +import android.annotation.TestApi; +import android.annotation.UnsupportedAppUsage; +import android.os.Binder; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerExecutor; +import android.os.Looper; +import android.telephony.Annotation.CallState; +import android.telephony.Annotation.RadioPowerState; +import android.telephony.Annotation.SimActivationState; +import android.telephony.Annotation.SrvccState; +import android.telephony.emergency.EmergencyNumber; +import android.telephony.ims.ImsReasonInfo; + +import com.android.internal.telephony.IPhoneStateListener; +import com.android.internal.annotations.VisibleForTesting; + +import dalvik.system.VMRuntime; + +import java.lang.ref.WeakReference; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; + +/** + * A listener class for monitoring changes in specific telephony states + * on the device, including service state, signal strength, message + * waiting indicator (voicemail), and others. + *

+ * Override the methods for the state that you wish to receive updates for, and + * pass your PhoneStateListener object, along with bitwise-or of the LISTEN_ + * flags to {@link TelephonyManager#listen TelephonyManager.listen()}. Methods are + * called when the state changes, as well as once on initial registration. + *

+ * Note that access to some telephony information is + * permission-protected. Your application won't receive updates for protected + * information unless it has the appropriate permissions declared in + * its manifest file. Where permissions apply, they are noted in the + * appropriate LISTEN_ flags. + */ +public class PhoneStateListener { + private static final String LOG_TAG = "PhoneStateListener"; + private static final boolean DBG = false; // STOPSHIP if true + + /** + * Stop listening for updates. + * + * The PhoneStateListener is not tied to any subscription and unregistered for any update. + */ + public static final int LISTEN_NONE = 0; + + /** + * Listen for changes to the network service state (cellular). + * + * @see #onServiceStateChanged + * @see ServiceState + */ + public static final int LISTEN_SERVICE_STATE = 0x00000001; + + /** + * Listen for changes to the network signal strength (cellular). + * {@more} + * + * @see #onSignalStrengthChanged + * + * @deprecated by {@link #LISTEN_SIGNAL_STRENGTHS} + */ + @Deprecated + public static final int LISTEN_SIGNAL_STRENGTH = 0x00000002; + + /** + * Listen for changes to the message-waiting indicator. + * {@more} + * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE + * READ_PHONE_STATE} or that the calling app has carrier privileges (see + * {@link TelephonyManager#hasCarrierPrivileges}). + *

+ * Example: The status bar uses this to determine when to display the + * voicemail icon. + * + * @see #onMessageWaitingIndicatorChanged + */ + public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 0x00000004; + + /** + * Listen for changes to the call-forwarding indicator. + * {@more} + * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE + * READ_PHONE_STATE} or that the calling app has carrier privileges (see + * {@link TelephonyManager#hasCarrierPrivileges}). + * + * @see #onCallForwardingIndicatorChanged + */ + public static final int LISTEN_CALL_FORWARDING_INDICATOR = 0x00000008; + + /** + * Listen for changes to the device's cell location. Note that + * this will result in frequent callbacks to the listener. + * {@more} + * Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION + * ACCESS_COARSE_LOCATION} + *

+ * If you need regular location updates but want more control over + * the update interval or location precision, you can set up a listener + * through the {@link android.location.LocationManager location manager} + * instead. + * + * @see #onCellLocationChanged + */ + public static final int LISTEN_CELL_LOCATION = 0x00000010; + + /** + * Listen for changes to the device call state. + * {@more} + * + * @see #onCallStateChanged + */ + public static final int LISTEN_CALL_STATE = 0x00000020; + + /** + * Listen for changes to the data connection state (cellular). + * + * @see #onDataConnectionStateChanged + */ + public static final int LISTEN_DATA_CONNECTION_STATE = 0x00000040; + + /** + * Listen for changes to the direction of data traffic on the data + * connection (cellular). + * {@more} + * Example: The status bar uses this to display the appropriate + * data-traffic icon. + * + * @see #onDataActivity + */ + public static final int LISTEN_DATA_ACTIVITY = 0x00000080; + + /** + * Listen for changes to the network signal strengths (cellular). + *

+ * Example: The status bar uses this to control the signal-strength + * icon. + * + * @see #onSignalStrengthsChanged + */ + public static final int LISTEN_SIGNAL_STRENGTHS = 0x00000100; + + /** + * Listen for changes to OTASP mode. + * + * @see #onOtaspChanged + * @hide + */ + public static final int LISTEN_OTASP_CHANGED = 0x00000200; + + /** + * Listen for changes to observed cell info. + * + * @see #onCellInfoChanged + */ + public static final int LISTEN_CELL_INFO = 0x00000400; + + /** + * Listen for {@link android.telephony.Annotation.PreciseCallStates} of ringing, + * background and foreground calls. + * + * @hide + */ + @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) + @SystemApi + public static final int LISTEN_PRECISE_CALL_STATE = 0x00000800; + + /** + * Listen for {@link PreciseDataConnectionState} on the data connection (cellular). + * + * @see #onPreciseDataConnectionStateChanged + * + * @hide + */ + @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) + @SystemApi + public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 0x00001000; + + /** + * Listen for real time info for all data connections (cellular)). + * {@more} + * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE + * READ_PRECISE_PHONE_STATE} + * @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo) + * + * @deprecated Use {@link TelephonyManager#getModemActivityInfo()} + * @hide + */ + @Deprecated + public static final int LISTEN_DATA_CONNECTION_REAL_TIME_INFO = 0x00002000; + + /** + * Listen for changes to the SRVCC state of the active call. + * @see #onServiceStateChanged(ServiceState) + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public static final int LISTEN_SRVCC_STATE_CHANGED = 0x00004000; + + /** + * Listen for OEM hook raw event + * + * @see #onOemHookRawEvent + * @hide + * @deprecated OEM needs a vendor-extension hal and their apps should use that instead + */ + @Deprecated + public static final int LISTEN_OEM_HOOK_RAW_EVENT = 0x00008000; + + /** + * Listen for carrier network changes indicated by a carrier app. + * + * @see #onCarrierNetworkRequest + * @see TelephonyManager#notifyCarrierNetworkChange(boolean) + * @hide + */ + public static final int LISTEN_CARRIER_NETWORK_CHANGE = 0x00010000; + + /** + * Listen for changes to the sim voice activation state + * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING + * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED + * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED + * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED + * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN + * {@more} + * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates voice service has been + * fully activated + * + * @see #onVoiceActivationStateChanged + * @hide + */ + @SystemApi + public static final int LISTEN_VOICE_ACTIVATION_STATE = 0x00020000; + + /** + * Listen for changes to the sim data activation state + * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING + * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED + * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED + * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED + * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN + * {@more} + * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates data service has been + * fully activated + * + * @see #onDataActivationStateChanged + * @hide + */ + public static final int LISTEN_DATA_ACTIVATION_STATE = 0x00040000; + + /** + * Listen for changes to the user mobile data state + * + * @see #onUserMobileDataStateChanged + */ + public static final int LISTEN_USER_MOBILE_DATA_STATE = 0x00080000; + + /** + * Listen for changes to the physical channel configuration. + * + * @see #onPhysicalChannelConfigurationChanged + * @hide + */ + public static final int LISTEN_PHYSICAL_CHANNEL_CONFIGURATION = 0x00100000; + + /** + * Listen for changes to the phone capability. + * + * @see #onPhoneCapabilityChanged + * @hide + */ + public static final int LISTEN_PHONE_CAPABILITY_CHANGE = 0x00200000; + + /** + * Listen for changes to active data subId. Active data subscription is + * the current subscription used to setup Cellular Internet data. For example, + * it could be the current active opportunistic subscription in use, or the + * subscription user selected as default data subscription in DSDS mode. + * + * @see #onActiveDataSubscriptionIdChanged + */ + public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 0x00400000; + + /** + * Listen for changes to the radio power state. + * + * @see #onRadioPowerStateChanged + * @hide + */ + @SystemApi + public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 0x00800000; + + /** + * Listen for changes to emergency number list based on all active subscriptions. + * + *

Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling + * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @see #onEmergencyNumberListChanged + */ + public static final int LISTEN_EMERGENCY_NUMBER_LIST = 0x01000000; + + /** + * Listen for call disconnect causes which contains {@link DisconnectCause} and + * {@link PreciseDisconnectCause}. + * + * @hide + */ + @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) + @SystemApi + public static final int LISTEN_CALL_DISCONNECT_CAUSES = 0x02000000; + + /** + * Listen for changes to the call attributes of a currently active call. + * {@more} + * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE + * READ_PRECISE_PHONE_STATE} + * + * @see #onCallAttributesChanged + * @hide + */ + @SystemApi + public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 0x04000000; + + /** + * Listen for IMS call disconnect causes which contains + * {@link android.telephony.ims.ImsReasonInfo} + * + * @see #onImsCallDisconnectCauseChanged(ImsReasonInfo) + * @hide + */ + @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) + @SystemApi + public static final int LISTEN_IMS_CALL_DISCONNECT_CAUSES = 0x08000000; + + /** + * Listen for the emergency number placed from an outgoing call. + * + *

Requires permission {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION} + * + * @see #onOutgoingEmergencyCall + * @hide + */ + @SystemApi + @TestApi + @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) + public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 0x10000000; + + /** + * Listen for the emergency number placed from an outgoing SMS. + * + *

Requires permission {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION} + * + * @see #onOutgoingEmergencySms + * @hide + */ + @SystemApi + @TestApi + @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) + public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 0x20000000; + + /* + * Subscription used to listen to the phone state changes + * @hide + */ + /** @hide */ + @UnsupportedAppUsage + protected Integer mSubId; + + /** + * @hide + */ + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + @UnsupportedAppUsage + public final IPhoneStateListener callback; + + /** + * Create a PhoneStateListener for the Phone with the default subscription. + * This class requires Looper.myLooper() not return null. + */ + public PhoneStateListener() { + this(null, Looper.myLooper()); + } + + /** + * Create a PhoneStateListener for the Phone with the default subscription + * using a particular non-null Looper. + * @hide + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) + public PhoneStateListener(Looper looper) { + this(null, looper); + } + + /** + * Create a PhoneStateListener for the Phone using the specified subscription. + * This class requires Looper.myLooper() not return null. To supply your + * own non-null Looper use PhoneStateListener(int subId, Looper looper) below. + * @hide + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) + public PhoneStateListener(Integer subId) { + this(subId, Looper.myLooper()); + if (subId != null && VMRuntime.getRuntime().getTargetSdkVersion() + >= Build.VERSION_CODES.Q) { + throw new IllegalArgumentException("PhoneStateListener with subId: " + + subId + " is not supported, use default constructor"); + } + } + /** + * Create a PhoneStateListener for the Phone using the specified subscription + * and non-null Looper. + * @hide + */ + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) + public PhoneStateListener(Integer subId, Looper looper) { + this(subId, new HandlerExecutor(new Handler(looper))); + if (subId != null && VMRuntime.getRuntime().getTargetSdkVersion() + >= Build.VERSION_CODES.Q) { + throw new IllegalArgumentException("PhoneStateListener with subId: " + + subId + " is not supported, use default constructor"); + } + } + + /** + * Create a PhoneStateListener for the Phone using the specified Executor + * + *

Create a PhoneStateListener with a specified Executor for handling necessary callbacks. + * The Executor must not be null. + * + * @param executor a non-null Executor that will execute callbacks for the PhoneStateListener. + */ + public PhoneStateListener(@NonNull Executor executor) { + this(null, executor); + } + + private PhoneStateListener(Integer subId, Executor e) { + if (e == null) { + throw new IllegalArgumentException("PhoneStateListener Executor must be non-null"); + } + mSubId = subId; + callback = new IPhoneStateListenerStub(this, e); + } + + /** + * Callback invoked when device service state changes on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @see ServiceState#STATE_EMERGENCY_ONLY + * @see ServiceState#STATE_IN_SERVICE + * @see ServiceState#STATE_OUT_OF_SERVICE + * @see ServiceState#STATE_POWER_OFF + */ + public void onServiceStateChanged(ServiceState serviceState) { + // default implementation empty + } + + /** + * Callback invoked when network signal strength changes on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @see ServiceState#STATE_EMERGENCY_ONLY + * @see ServiceState#STATE_IN_SERVICE + * @see ServiceState#STATE_OUT_OF_SERVICE + * @see ServiceState#STATE_POWER_OFF + * @deprecated Use {@link #onSignalStrengthsChanged(SignalStrength)} + */ + @Deprecated + public void onSignalStrengthChanged(int asu) { + // default implementation empty + } + + /** + * Callback invoked when the message-waiting indicator changes on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + public void onMessageWaitingIndicatorChanged(boolean mwi) { + // default implementation empty + } + + /** + * Callback invoked when the call-forwarding indicator changes on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + public void onCallForwardingIndicatorChanged(boolean cfi) { + // default implementation empty + } + + /** + * Callback invoked when device cell location changes on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + public void onCellLocationChanged(CellLocation location) { + // default implementation empty + } + + /** + * Callback invoked when device call state changes. + *

+ * Reports the state of Telephony (mobile) calls on the device for the registered subscription. + *

+ * Note: the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + *

+ * Note: The state returned here may differ from that returned by + * {@link TelephonyManager#getCallState()}. Receivers of this callback should be aware that + * calling {@link TelephonyManager#getCallState()} from within this callback may return a + * different state than the callback reports. + * + * @param state call state + * @param phoneNumber call phone number. If application does not have + * {@link android.Manifest.permission#READ_CALL_LOG READ_CALL_LOG} permission or carrier + * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an empty string will be + * passed as an argument. + */ + public void onCallStateChanged(@CallState int state, String phoneNumber) { + // default implementation empty + } + + /** + * Callback invoked when connection state changes on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @see TelephonyManager#DATA_DISCONNECTED + * @see TelephonyManager#DATA_CONNECTING + * @see TelephonyManager#DATA_CONNECTED + * @see TelephonyManager#DATA_SUSPENDED + */ + public void onDataConnectionStateChanged(int state) { + // default implementation empty + } + + /** + * same as above, but with the network type. Both called. + */ + public void onDataConnectionStateChanged(int state, int networkType) { + } + + /** + * Callback invoked when data activity state changes on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @see TelephonyManager#DATA_ACTIVITY_NONE + * @see TelephonyManager#DATA_ACTIVITY_IN + * @see TelephonyManager#DATA_ACTIVITY_OUT + * @see TelephonyManager#DATA_ACTIVITY_INOUT + * @see TelephonyManager#DATA_ACTIVITY_DORMANT + */ + public void onDataActivity(int direction) { + // default implementation empty + } + + /** + * Callback invoked when network signal strengths changes on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + public void onSignalStrengthsChanged(SignalStrength signalStrength) { + // default implementation empty + } + + + /** + * The Over The Air Service Provisioning (OTASP) has changed on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * Requires the READ_PHONE_STATE permission. + * @param otaspMode is integer OTASP_UNKNOWN=1 + * means the value is currently unknown and the system should wait until + * OTASP_NEEDED=2 or OTASP_NOT_NEEDED=3 is received before + * making the decision to perform OTASP or not. + * + * @hide + */ + @UnsupportedAppUsage + public void onOtaspChanged(int otaspMode) { + // default implementation empty + } + + /** + * Callback invoked when a observed cell info has changed or new cells have been added + * or removed on the registered subscription. + * Note, the registration subId s from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param cellInfo is the list of currently visible cells. + */ + public void onCellInfoChanged(List cellInfo) { + } + + /** + * Callback invoked when precise device call state changes on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * @param callState {@link PreciseCallState} + * @hide + */ + @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) + @SystemApi + public void onPreciseCallStateChanged(@NonNull PreciseCallState callState) { + // default implementation empty + } + + /** + * Callback invoked when call disconnect cause changes on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param disconnectCause {@link DisconnectCause}. + * @param preciseDisconnectCause {@link PreciseDisconnectCause}. + * + * @hide + */ + @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) + @SystemApi + public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) { + // default implementation empty + } + + /** + * Callback invoked when Ims call disconnect cause changes on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param imsReasonInfo {@link ImsReasonInfo} contains details on why IMS call failed. + * + * @hide + */ + @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) + @SystemApi + public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo) { + // default implementation empty + } + + /** + * Callback invoked when data connection state changes with precise information + * on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param dataConnectionState {@link PreciseDataConnectionState} + * + * @hide + */ + @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) + @SystemApi + public void onPreciseDataConnectionStateChanged( + @NonNull PreciseDataConnectionState dataConnectionState) { + // default implementation empty + } + + /** + * Callback invoked when data connection real time info changes on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @hide + */ + @UnsupportedAppUsage + public void onDataConnectionRealTimeInfoChanged( + DataConnectionRealTimeInfo dcRtInfo) { + // default implementation empty + } + + /** + * Callback invoked when there has been a change in the Single Radio Voice Call Continuity + * (SRVCC) state for the currently active call on the registered subscription. + * + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @hide + */ + @SystemApi + public void onSrvccStateChanged(@SrvccState int srvccState) { + + } + + /** + * Callback invoked when the SIM voice activation state has changed on the registered + * subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param state is the current SIM voice activation state + * @hide + */ + @SystemApi + public void onVoiceActivationStateChanged(@SimActivationState int state) { + } + + /** + * Callback invoked when the SIM data activation state has changed on the registered + * subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param state is the current SIM data activation state + * @hide + */ + public void onDataActivationStateChanged(@SimActivationState int state) { + } + + /** + * Callback invoked when the user mobile data state has changed on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param enabled indicates whether the current user mobile data state is enabled or disabled. + */ + public void onUserMobileDataStateChanged(boolean enabled) { + // default implementation empty + } + + /** + * Callback invoked when the current physical channel configuration has changed on the + * registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param configs List of the current {@link PhysicalChannelConfig}s + * @hide + */ + public void onPhysicalChannelConfigurationChanged( + @NonNull List configs) { + // default implementation empty + } + + /** + * Callback invoked when the current emergency number list has changed on the registered + * subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param emergencyNumberList Map including the key as the active subscription ID + * (Note: if there is no active subscription, the key is + * {@link SubscriptionManager#getDefaultSubscriptionId}) + * and the value as the list of {@link EmergencyNumber}; + * null if this information is not available. + * @hide + */ + public void onEmergencyNumberListChanged( + @NonNull Map> emergencyNumberList) { + // default implementation empty + } + + /** + * Callback invoked when an outgoing call is placed to an emergency number. + * + * @param placedEmergencyNumber the emergency number {@link EmergencyNumber} the call is placed + * to. + * @hide + */ + @SystemApi + @TestApi + public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber) { + // default implementation empty + } + + /** + * Callback invoked when an outgoing SMS is placed to an emergency number. + * + * @param sentEmergencyNumber the emergency number {@link EmergencyNumber} the SMS is sent to. + * @hide + */ + @SystemApi + @TestApi + public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber) { + // default implementation empty + } + + /** + * Callback invoked when OEM hook raw event is received on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * Requires the READ_PRIVILEGED_PHONE_STATE permission. + * @param rawData is the byte array of the OEM hook raw data. + * @hide + */ + @UnsupportedAppUsage + public void onOemHookRawEvent(byte[] rawData) { + // default implementation empty + } + + /** + * Callback invoked when phone capability changes. + * Note, this callback triggers regardless of registered subscription. + * + * Requires the READ_PRIVILEGED_PHONE_STATE permission. + * @param capability the new phone capability + * @hide + */ + public void onPhoneCapabilityChanged(PhoneCapability capability) { + // default implementation empty + } + + /** + * Callback invoked when active data subId changes. + * Note, this callback triggers regardless of registered subscription. + * + * Requires the READ_PHONE_STATE permission. + * @param subId current subscription used to setup Cellular Internet data. + * For example, it could be the current active opportunistic subscription in use, + * or the subscription user selected as default data subscription in DSDS mode. + */ + public void onActiveDataSubscriptionIdChanged(int subId) { + // default implementation empty + } + + /** + * Callback invoked when the call attributes changes on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * Requires the READ_PRIVILEGED_PHONE_STATE permission. + * @param callAttributes the call attributes + * @hide + */ + @SystemApi + public void onCallAttributesChanged(@NonNull CallAttributes callAttributes) { + // default implementation empty + } + + /** + * Callback invoked when modem radio power state changes on the registered subscription. + * Note, the registration subId comes from {@link TelephonyManager} object which registers + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subId. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * Requires + * the READ_PRIVILEGED_PHONE_STATE permission. + * @param state the modem radio power state + * @hide + */ + @SystemApi + public void onRadioPowerStateChanged(@RadioPowerState int state) { + // default implementation empty + } + + /** + * Callback invoked when telephony has received notice from a carrier + * app that a network action that could result in connectivity loss + * has been requested by an app using + * {@link android.telephony.TelephonyManager#notifyCarrierNetworkChange(boolean)} + * + * Note, this callback is pinned to the registered subscription and will be invoked when + * the notifying carrier app has carrier privilege rule on the registered + * subscription. {@link android.telephony.TelephonyManager#hasCarrierPrivileges} + * + * @param active Whether the carrier network change is or shortly + * will be active. This value is true to indicate + * showing alternative UI and false to stop. + * + * @hide + */ + public void onCarrierNetworkChange(boolean active) { + // default implementation empty + } + + /** + * The callback methods need to be called on the handler thread where + * this object was created. If the binder did that for us it'd be nice. + * + * Using a static class and weak reference here to avoid memory leak caused by the + * IPhoneStateListener.Stub callback retaining references to the outside PhoneStateListeners: + * even caller has been destroyed and "un-registered" the PhoneStateListener, it is still not + * eligible for GC given the references coming from: + * Native Stack --> PhoneStateListener --> Context (Activity). + * memory of caller's context will be collected after GC from service side get triggered + */ + private static class IPhoneStateListenerStub extends IPhoneStateListener.Stub { + private WeakReference mPhoneStateListenerWeakRef; + private Executor mExecutor; + + IPhoneStateListenerStub(PhoneStateListener phoneStateListener, Executor executor) { + mPhoneStateListenerWeakRef = new WeakReference(phoneStateListener); + mExecutor = executor; + } + + public void onServiceStateChanged(ServiceState serviceState) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onServiceStateChanged(serviceState))); + } + + public void onSignalStrengthChanged(int asu) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onSignalStrengthChanged(asu))); + } + + public void onMessageWaitingIndicatorChanged(boolean mwi) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onMessageWaitingIndicatorChanged(mwi))); + } + + public void onCallForwardingIndicatorChanged(boolean cfi) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onCallForwardingIndicatorChanged(cfi))); + } + + public void onCellLocationChanged(Bundle bundle) { + CellLocation location = CellLocation.newFromBundle(bundle); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onCellLocationChanged(location))); + } + + public void onCallStateChanged(int state, String incomingNumber) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onCallStateChanged(state, incomingNumber))); + } + + public void onDataConnectionStateChanged(int state, int networkType) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity(() -> mExecutor.execute( + () -> { + psl.onDataConnectionStateChanged(state, networkType); + psl.onDataConnectionStateChanged(state); + })); + } + + public void onDataActivity(int direction) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onDataActivity(direction))); + } + + public void onSignalStrengthsChanged(SignalStrength signalStrength) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onSignalStrengthsChanged(signalStrength))); + } + + public void onOtaspChanged(int otaspMode) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onOtaspChanged(otaspMode))); + } + + public void onCellInfoChanged(List cellInfo) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onCellInfoChanged(cellInfo))); + } + + public void onPreciseCallStateChanged(PreciseCallState callState) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onPreciseCallStateChanged(callState))); + } + + public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onCallDisconnectCauseChanged( + disconnectCause, preciseDisconnectCause))); + } + + public void onPreciseDataConnectionStateChanged( + PreciseDataConnectionState dataConnectionState) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onPreciseDataConnectionStateChanged(dataConnectionState))); + } + + public void onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo dcRtInfo) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onDataConnectionRealTimeInfoChanged(dcRtInfo))); + } + + public void onSrvccStateChanged(int state) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onSrvccStateChanged(state))); + } + + public void onVoiceActivationStateChanged(int activationState) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onVoiceActivationStateChanged(activationState))); + } + + public void onDataActivationStateChanged(int activationState) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onDataActivationStateChanged(activationState))); + } + + public void onUserMobileDataStateChanged(boolean enabled) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onUserMobileDataStateChanged(enabled))); + } + + public void onOemHookRawEvent(byte[] rawData) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onOemHookRawEvent(rawData))); + } + + public void onCarrierNetworkChange(boolean active) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onCarrierNetworkChange(active))); + } + + public void onPhysicalChannelConfigurationChanged(List configs) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onPhysicalChannelConfigurationChanged(configs))); + } + + public void onEmergencyNumberListChanged(Map emergencyNumberList) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onEmergencyNumberListChanged(emergencyNumberList))); + } + + public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onOutgoingEmergencyCall(placedEmergencyNumber))); + } + + public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onOutgoingEmergencySms(sentEmergencyNumber))); + } + + public void onPhoneCapabilityChanged(PhoneCapability capability) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onPhoneCapabilityChanged(capability))); + } + + public void onRadioPowerStateChanged(@RadioPowerState int state) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onRadioPowerStateChanged(state))); + } + + public void onCallAttributesChanged(CallAttributes callAttributes) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onCallAttributesChanged(callAttributes))); + } + + public void onActiveDataSubIdChanged(int subId) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onActiveDataSubscriptionIdChanged(subId))); + } + + public void onImsCallDisconnectCauseChanged(ImsReasonInfo disconnectCause) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onImsCallDisconnectCauseChanged(disconnectCause))); + + } + } + + + private void log(String s) { + Rlog.d(LOG_TAG, s); + } +} diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java new file mode 100644 index 000000000000..64d612405c34 --- /dev/null +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -0,0 +1,697 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.telephony; + +import android.annotation.CallbackExecutor; +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.content.Context; +import android.net.LinkProperties; +import android.net.NetworkCapabilities; +import android.os.Binder; +import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerExecutor; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.telephony.Annotation.ApnType; +import android.telephony.Annotation.CallState; +import android.telephony.Annotation.DataActivityType; +import android.telephony.Annotation.DataFailureCause; +import android.telephony.Annotation.DataState; +import android.telephony.Annotation.NetworkType; +import android.telephony.Annotation.PreciseCallStates; +import android.telephony.Annotation.RadioPowerState; +import android.telephony.Annotation.SimActivationState; +import android.telephony.Annotation.SrvccState; +import android.telephony.CallQuality; +import android.telephony.CellInfo; +import android.telephony.DisconnectCause; +import android.telephony.PhoneCapability; +import android.telephony.ServiceState; +import android.telephony.SignalStrength; +import android.telephony.TelephonyManager; +import android.telephony.data.ApnSetting; +import android.telephony.ims.ImsReasonInfo; +import android.util.Log; + +import com.android.internal.telephony.ITelephonyRegistry; +import com.android.internal.telephony.IOnSubscriptionsChangedListener; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; + +/** + * A centralized place to notify telephony related status changes, e.g, {@link ServiceState} update + * or {@link PhoneCapability} changed. This might trigger callback from applications side through + * {@link android.telephony.PhoneStateListener} + * + * TODO: limit API access to only carrier apps with certain permissions or apps running on + * privileged UID. + * + * @hide + */ +@SystemApi +public class TelephonyRegistryManager { + + private static final String TAG = "TelephonyRegistryManager"; + private static ITelephonyRegistry sRegistry; + private final Context mContext; + + /** + * A mapping between {@link SubscriptionManager.OnSubscriptionsChangedListener} and + * its callback IOnSubscriptionsChangedListener. + */ + private final Map mSubscriptionChangedListenerMap = new HashMap<>(); + /** + * A mapping between {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} and + * its callback IOnSubscriptionsChangedListener. + */ + private final Map mOpportunisticSubscriptionChangedListenerMap + = new HashMap<>(); + + + /** @hide **/ + public TelephonyRegistryManager(@NonNull Context context) { + mContext = context; + if (sRegistry == null) { + sRegistry = ITelephonyRegistry.Stub.asInterface( + ServiceManager.getService("telephony.registry")); + } + } + + /** + * Register for changes to the list of active {@link SubscriptionInfo} records or to the + * individual records themselves. When a change occurs the onSubscriptionsChanged method of + * the listener will be invoked immediately if there has been a notification. The + * onSubscriptionChanged method will also be triggered once initially when calling this + * function. + * + * @param listener an instance of {@link SubscriptionManager.OnSubscriptionsChangedListener} + * with onSubscriptionsChanged overridden. + * @param executor the executor that will execute callbacks. + */ + public void addOnSubscriptionsChangedListener( + @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener, + @NonNull Executor executor) { + IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { + @Override + public void onSubscriptionsChanged () { + Log.d(TAG, "onSubscriptionsChangedListener callback received."); + executor.execute(() -> listener.onSubscriptionsChanged()); + } + }; + mSubscriptionChangedListenerMap.put(listener, callback); + try { + sRegistry.addOnSubscriptionsChangedListener(mContext.getOpPackageName(), callback); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Unregister the {@link SubscriptionManager.OnSubscriptionsChangedListener}. This is not + * strictly necessary as the listener will automatically be unregistered if an attempt to + * invoke the listener fails. + * + * @param listener that is to be unregistered. + */ + public void removeOnSubscriptionsChangedListener( + @NonNull SubscriptionManager.OnSubscriptionsChangedListener listener) { + if (mSubscriptionChangedListenerMap.get(listener) == null) { + return; + } + try { + sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(), + mSubscriptionChangedListenerMap.get(listener)); + mSubscriptionChangedListenerMap.remove(listener); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Register for changes to the list of opportunistic subscription records or to the + * individual records themselves. When a change occurs the onOpportunisticSubscriptionsChanged + * method of the listener will be invoked immediately if there has been a notification. + * + * @param listener an instance of + * {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} with + * onOpportunisticSubscriptionsChanged overridden. + * @param executor an Executor that will execute callbacks. + */ + public void addOnOpportunisticSubscriptionsChangedListener( + @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener, + @NonNull Executor executor) { + /** + * The callback methods need to be called on the executor thread where + * this object was created. If the binder did that for us it'd be nice. + */ + IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { + @Override + public void onSubscriptionsChanged() { + final long identity = Binder.clearCallingIdentity(); + try { + Log.d(TAG, "onOpportunisticSubscriptionsChanged callback received."); + executor.execute(() -> listener.onOpportunisticSubscriptionsChanged()); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + }; + mOpportunisticSubscriptionChangedListenerMap.put(listener, callback); + try { + sRegistry.addOnOpportunisticSubscriptionsChangedListener(mContext.getOpPackageName(), + callback); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Unregister the {@link SubscriptionManager.OnOpportunisticSubscriptionsChangedListener} + * that is currently listening opportunistic subscriptions change. This is not strictly + * necessary as the listener will automatically be unregistered if an attempt to invoke the + * listener fails. + * + * @param listener that is to be unregistered. + */ + public void removeOnOpportunisticSubscriptionsChangedListener( + @NonNull SubscriptionManager.OnOpportunisticSubscriptionsChangedListener listener) { + try { + sRegistry.removeOnSubscriptionsChangedListener(mContext.getOpPackageName(), + mOpportunisticSubscriptionChangedListenerMap.get(listener)); + mOpportunisticSubscriptionChangedListenerMap.remove(listener); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Informs the system of an intentional upcoming carrier network change by a carrier app. + * This call only used to allow the system to provide alternative UI while telephony is + * performing an action that may result in intentional, temporary network lack of connectivity. + *

+ * Based on the active parameter passed in, this method will either show or hide the alternative + * UI. There is no timeout associated with showing this UX, so a carrier app must be sure to + * call with active set to false sometime after calling with it set to {@code true}. + *

+ * Requires Permission: calling app has carrier privileges. + * + * @param active Whether the carrier network change is or shortly will be + * active. Set this value to true to begin showing alternative UI and false to stop. + * @see TelephonyManager#hasCarrierPrivileges + */ + public void notifyCarrierNetworkChange(boolean active) { + try { + sRegistry.notifyCarrierNetworkChange(active); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Notify call state changed on certain subscription. + * + * @param subId for which call state changed. + * @param slotIndex for which call state changed. Can be derived from subId except when subId is + * invalid. + * @param state latest call state. e.g, offhook, ringing + * @param incomingNumer incoming phone number. + * + * @hide + */ + public void notifyCallStateChanged(int subId, int slotIndex, @CallState int state, + String incomingNumer) { + try { + sRegistry.notifyCallState(slotIndex, subId, state, incomingNumer); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Notify {@link ServiceState} update on certain subscription. + * + * @param subId for which the service state changed. + * @param slotIndex for which the service state changed. Can be derived from subId except + * subId is invalid. + * @param state service state e.g, in service, out of service or roaming status. + * + * @hide + */ + public void notifyServiceStateChanged(int subId, int slotIndex, ServiceState state) { + try { + sRegistry.notifyServiceStateForPhoneId(slotIndex, subId, state); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Notify {@link SignalStrength} update on certain subscription. + * + * @param subId for which the signalstrength changed. + * @param slotIndex for which the signalstrength changed. Can be derived from subId except when + * subId is invalid. + * @param signalStrength e.g, signalstrength level {@see SignalStrength#getLevel()} + * + * @hide + */ + public void notifySignalStrengthChanged(int subId, int slotIndex, + SignalStrength signalStrength) { + try { + sRegistry.notifySignalStrengthForPhoneId(slotIndex, subId, signalStrength); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Notify changes to the message-waiting indicator on certain subscription. e.g, The status bar + * uses message waiting indicator to determine when to display the voicemail icon. + * + * @param subId for which message waiting indicator changed. + * @param slotIndex for which message waiting indicator changed. Can be derived from subId + * except when subId is invalid. + * @param msgWaitingInd {@code true} indicates there is message-waiting indicator, {@code false} + * otherwise. + * + * @hide + */ + public void notifyMessageWaitingChanged(int subId, int slotIndex, boolean msgWaitingInd) { + try { + sRegistry.notifyMessageWaitingChangedForPhoneId(slotIndex, subId, msgWaitingInd); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify changes to the call-forwarding status on certain subscription. + * + * @param subId for which call forwarding status changed. + * @param callForwardInd {@code true} indicates there is call forwarding, {@code false} + * otherwise. + * + * @hide + */ + public void notifyCallForwardingChanged(int subId, boolean callForwardInd) { + try { + sRegistry.notifyCallForwardingChangedForSubscriber(subId, callForwardInd); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify changes to activity state changes on certain subscription. + * + * @param subId for which data activity state changed. + * @param dataActivityType indicates the latest data activity type e.g, {@link + * TelephonyManager#DATA_ACTIVITY_IN} + * + * @hide + */ + public void notifyDataActivityChanged(int subId, @DataActivityType int dataActivityType) { + try { + sRegistry.notifyDataActivityForSubscriber(subId, dataActivityType); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify changes to default (Internet) data connection state on certain subscription. + * + * @param subId for which data connection state changed. + * @param slotIndex for which data connections state changed. Can be derived from subId except + * when subId is invalid. + * @param state latest data connection state, e.g, + * @param isDataConnectivityPossible indicates if data is allowed + * @param apn the APN {@link ApnSetting#getApnName()} of this data connection. + * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN. + * @param linkProperties {@link LinkProperties} associated with this data connection. + * @param networkCapabilities {@link NetworkCapabilities} associated with this data connection. + * @param networkType associated with this data connection. + * @param roaming {@code true} indicates in roaming, {@false} otherwise. + * @see TelephonyManager#DATA_DISCONNECTED + * @see TelephonyManager#isDataConnectivityPossible() + * + * @hide + */ + public void notifyDataConnectionForSubscriber(int slotIndex, int subId, @DataState int state, + boolean isDataConnectivityPossible, + @ApnType String apn, String apnType, LinkProperties linkProperties, + NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { + try { + sRegistry.notifyDataConnectionForSubscriber(slotIndex, subId, state, + isDataConnectivityPossible, + apn, apnType, linkProperties, networkCapabilities, networkType, roaming); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify {@link CallQuality} change on certain subscription. + * + * @param subId for which call quality state changed. + * @param slotIndex for which call quality state changed. Can be derived from subId except when + * subId is invalid. + * @param callQuality Information about call quality e.g, call quality level + * @param networkType associated with this data connection. e.g, LTE + * + * @hide + */ + public void notifyCallQualityChanged(int subId, int slotIndex, CallQuality callQuality, + @NetworkType int networkType) { + try { + sRegistry.notifyCallQualityChanged(callQuality, slotIndex, subId, networkType); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify emergency number list changed on certain subscription. + * + * @param subId for which emergency number list changed. + * @param slotIndex for which emergency number list changed. Can be derived from subId except + * when subId is invalid. + * + * @hide + */ + public void notifyEmergencyNumberList(int subId, int slotIndex) { + try { + sRegistry.notifyEmergencyNumberList(slotIndex, subId); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify radio power state changed on certain subscription. + * + * @param subId for which radio power state changed. + * @param slotIndex for which radio power state changed. Can be derived from subId except when + * subId is invalid. + * @param radioPowerState the current modem radio state. + * + * @hide + */ + public void notifyRadioPowerStateChanged(int subId, int slotIndex, + @RadioPowerState int radioPowerState) { + try { + sRegistry.notifyRadioPowerStateChanged(slotIndex, subId, radioPowerState); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify {@link PhoneCapability} changed. + * + * @param phoneCapability the capability of the modem group. + * + * @hide + */ + public void notifyPhoneCapabilityChanged(PhoneCapability phoneCapability) { + try { + sRegistry.notifyPhoneCapabilityChanged(phoneCapability); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify data activation state changed on certain subscription. + * @see TelephonyManager#getDataActivationState() + * + * @param subId for which data activation state changed. + * @param slotIndex for which data activation state changed. Can be derived from subId except + * when subId is invalid. + * @param activationState sim activation state e.g, activated. + * + * @hide + */ + public void notifyDataActivationStateChanged(int subId, int slotIndex, + @SimActivationState int activationState) { + try { + sRegistry.notifySimActivationStateChangedForPhoneId(slotIndex, subId, + TelephonyManager.SIM_ACTIVATION_TYPE_DATA, activationState); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify voice activation state changed on certain subscription. + * @see TelephonyManager#getVoiceActivationState() + * + * @param subId for which voice activation state changed. + * @param slotIndex for which voice activation state changed. Can be derived from subId except + * subId is invalid. + * @param activationState sim activation state e.g, activated. + * + * @hide + */ + public void notifyVoiceActivationStateChanged(int subId, int slotIndex, + @SimActivationState int activationState) { + try { + sRegistry.notifySimActivationStateChangedForPhoneId(slotIndex, subId, + TelephonyManager.SIM_ACTIVATION_TYPE_VOICE, activationState); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify User mobile data state changed on certain subscription. e.g, mobile data is enabled + * or disabled. + * + * @param subId for which mobile data state has changed. + * @param slotIndex for which mobile data state has changed. Can be derived from subId except + * when subId is invalid. + * @param state {@code true} indicates mobile data is enabled/on. {@code false} otherwise. + * + * @hide + */ + public void notifyUserMobileDataStateChanged(int slotIndex, int subId, boolean state) { + try { + sRegistry.notifyUserMobileDataStateChangedForPhoneId(slotIndex, subId, state); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * TODO: this is marked as deprecated, can we move this one safely? + * + * @param subId + * @param slotIndex + * @param rawData + * + * @hide + */ + public void notifyOemHookRawEventForSubscriber(int subId, int slotIndex, byte[] rawData) { + try { + sRegistry.notifyOemHookRawEventForSubscriber(slotIndex, subId, rawData); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify IMS call disconnect causes which contains {@link android.telephony.ims.ImsReasonInfo}. + * + * @param subId for which ims call disconnect. + * @param imsReasonInfo the reason for ims call disconnect. + * + * @hide + */ + public void notifyImsDisconnectCause(int subId, ImsReasonInfo imsReasonInfo) { + try { + sRegistry.notifyImsDisconnectCause(subId, imsReasonInfo); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify precise data connection failed cause on certain subscription. + * + * @param subId for which data connection failed. + * @param slotIndex for which data conenction failed. Can be derived from subId except when + * subId is invalid. + * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN. + * @param apn the APN {@link ApnSetting#getApnName()} of this data connection. + * @param failCause data fail cause. + * + * @hide + */ + public void notifyPreciseDataConnectionFailed(int subId, int slotIndex, String apnType, + String apn, @DataFailureCause int failCause) { + try { + sRegistry.notifyPreciseDataConnectionFailed(slotIndex, subId, apnType, apn, failCause); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify single Radio Voice Call Continuity (SRVCC) state change for the currently active call + * on certain subscription. + * + * @param subId for which srvcc state changed. + * @param state srvcc state + * + * @hide + */ + public void notifySrvccStateChanged(int subId, @SrvccState int state) { + try { + sRegistry.notifySrvccStateChanged(subId, state); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify over the air sim provisioning(OTASP) mode changed on certain subscription. + * + * @param subId for which otasp mode changed. + * @param otaspMode latest mode for OTASP e.g, OTASP needed. + * + * @hide + */ + public void notifyOtaspChanged(int subId, int otaspMode) { + try { + sRegistry.notifyOtaspChanged(subId, otaspMode); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify precise call state changed on certain subscription, including foreground, background + * and ringcall states. + * + * @param subId for which precise call state changed. + * @param slotIndex for which precise call state changed. Can be derived from subId except when + * subId is invalid. + * @param ringCallPreciseState ringCall state. + * @param foregroundCallPreciseState foreground call state. + * @param backgroundCallPreciseState background call state. + * + * @hide + */ + public void notifyPreciseCallState(int subId, int slotIndex, + @PreciseCallStates int ringCallPreciseState, + @PreciseCallStates int foregroundCallPreciseState, + @PreciseCallStates int backgroundCallPreciseState) { + try { + sRegistry.notifyPreciseCallState(slotIndex, subId, ringCallPreciseState, + foregroundCallPreciseState, backgroundCallPreciseState); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify call disconnect causes which contains {@link DisconnectCause} and {@link + * android.telephony.PreciseDisconnectCause}. + * + * @param subId for which call disconnected. + * @param slotIndex for which call disconnected. Can be derived from subId except when subId is + * invalid. + * @param cause {@link DisconnectCause} for the disconnected call. + * @param preciseCause {@link android.telephony.PreciseDisconnectCause} for the disconnected + * call. + * + * @hide + */ + public void notifyDisconnectCause(int slotIndex, int subId, int cause, int preciseCause) { + try { + sRegistry.notifyDisconnectCause(slotIndex, subId, cause, preciseCause); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify data connection failed on certain subscription. + * + * @param subId for which data connection failed. + * @param slotIndex for which data conenction faled. Can be derived from subId except when subId + * is invalid. + * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN. Note each data + * connection can support multiple anyTypes. + * + * @hide + */ + public void notifyDataConnectionFailed(int subId, int slotIndex, String apnType) { + try { + sRegistry.notifyDataConnectionFailedForSubscriber(slotIndex, subId, apnType); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * TODO change from bundle to CellLocation? + * @hide + */ + public void notifyCellLocation(int subId, Bundle cellLocation) { + try { + sRegistry.notifyCellLocationForSubscriber(subId, cellLocation); + } catch (RemoteException ex) { + // system process is dead + } + } + + /** + * Notify {@link CellInfo} changed on certain subscription. e.g, when an observed cell info has + * changed or new cells have been added or removed on the given subscription. + * + * @param subId for which cellinfo changed. + * @param cellInfo A list of cellInfo associated with the given subscription. + * + * @hide + */ + public void notifyCellInfoChanged(int subId, List cellInfo) { + try { + sRegistry.notifyCellInfoForSubscriber(subId, cellInfo); + } catch (RemoteException ex) { + + } + } + + /** + * @param activeDataSubId + * @hide + */ + public void notifyActiveDataSubIdChanged(int activeDataSubId) { + try { + sRegistry.notifyActiveDataSubIdChanged(activeDataSubId); + } catch (RemoteException ex) { + + } + } +} diff --git a/core/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl b/core/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl new file mode 100644 index 000000000000..493b1ff6aba7 --- /dev/null +++ b/core/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telephony; + +oneway interface IOnSubscriptionsChangedListener { + void onSubscriptionsChanged(); +} + diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl new file mode 100644 index 000000000000..084a3cc64a35 --- /dev/null +++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telephony; + +import android.os.Bundle; +import android.telephony.CallAttributes; +import android.telephony.CellInfo; +import android.telephony.DataConnectionRealTimeInfo; +import android.telephony.PhoneCapability; +import android.telephony.PhysicalChannelConfig; +import android.telephony.PreciseCallState; +import android.telephony.PreciseDataConnectionState; +import android.telephony.ServiceState; +import android.telephony.SignalStrength; +import android.telephony.emergency.EmergencyNumber; +import android.telephony.ims.ImsReasonInfo; + +/** + * {@hide} + */ +oneway interface IPhoneStateListener { + void onServiceStateChanged(in ServiceState serviceState); + void onSignalStrengthChanged(int asu); + void onMessageWaitingIndicatorChanged(boolean mwi); + void onCallForwardingIndicatorChanged(boolean cfi); + + // we use bundle here instead of CellLocation so it can get the right subclass + void onCellLocationChanged(in Bundle location); + void onCallStateChanged(int state, String incomingNumber); + void onDataConnectionStateChanged(int state, int networkType); + void onDataActivity(int direction); + void onSignalStrengthsChanged(in SignalStrength signalStrength); + void onPhysicalChannelConfigurationChanged(in List configs); + void onOtaspChanged(in int otaspMode); + void onCellInfoChanged(in List cellInfo); + void onPreciseCallStateChanged(in PreciseCallState callState); + void onPreciseDataConnectionStateChanged(in PreciseDataConnectionState dataConnectionState); + void onDataConnectionRealTimeInfoChanged(in DataConnectionRealTimeInfo dcRtInfo); + void onSrvccStateChanged(in int state); + void onVoiceActivationStateChanged(int activationState); + void onDataActivationStateChanged(int activationState); + void onOemHookRawEvent(in byte[] rawData); + void onCarrierNetworkChange(in boolean active); + void onUserMobileDataStateChanged(in boolean enabled); + void onPhoneCapabilityChanged(in PhoneCapability capability); + void onActiveDataSubIdChanged(in int subId); + void onRadioPowerStateChanged(in int state); + void onCallAttributesChanged(in CallAttributes callAttributes); + void onEmergencyNumberListChanged(in Map emergencyNumberList); + void onOutgoingEmergencyCall(in EmergencyNumber placedEmergencyNumber); + void onOutgoingEmergencySms(in EmergencyNumber sentEmergencyNumber); + void onCallDisconnectCauseChanged(in int disconnectCause, in int preciseDisconnectCause); + void onImsCallDisconnectCauseChanged(in ImsReasonInfo imsReasonInfo); +} + diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl new file mode 100644 index 000000000000..d7a7af1d530f --- /dev/null +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.telephony; + +import android.content.Intent; +import android.net.LinkProperties; +import android.net.NetworkCapabilities; +import android.os.Bundle; +import android.telephony.CallQuality; +import android.telephony.CellInfo; +import android.telephony.ims.ImsReasonInfo; +import android.telephony.PhoneCapability; +import android.telephony.PhysicalChannelConfig; +import android.telephony.ServiceState; +import android.telephony.SignalStrength; +import android.telephony.emergency.EmergencyNumber; +import com.android.internal.telephony.IPhoneStateListener; +import com.android.internal.telephony.IOnSubscriptionsChangedListener; + +interface ITelephonyRegistry { + void addOnSubscriptionsChangedListener(String pkg, + IOnSubscriptionsChangedListener callback); + void addOnOpportunisticSubscriptionsChangedListener(String pkg, + IOnSubscriptionsChangedListener callback); + void removeOnSubscriptionsChangedListener(String pkg, + IOnSubscriptionsChangedListener callback); + @UnsupportedAppUsage + void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow); + void listenForSubscriber(in int subId, String pkg, IPhoneStateListener callback, int events, + boolean notifyNow); + @UnsupportedAppUsage + void notifyCallStateForAllSubs(int state, String incomingNumber); + void notifyCallState(in int phoneId, in int subId, int state, String incomingNumber); + void notifyServiceStateForPhoneId(in int phoneId, in int subId, in ServiceState state); + void notifySignalStrengthForPhoneId(in int phoneId, in int subId, + in SignalStrength signalStrength); + void notifyMessageWaitingChangedForPhoneId(in int phoneId, in int subId, in boolean mwi); + @UnsupportedAppUsage(maxTargetSdk = 28) + void notifyCallForwardingChanged(boolean cfi); + void notifyCallForwardingChangedForSubscriber(in int subId, boolean cfi); + @UnsupportedAppUsage(maxTargetSdk = 28) + void notifyDataActivity(int state); + void notifyDataActivityForSubscriber(in int subId, int state); + void notifyDataConnection(int state, boolean isDataConnectivityPossible, + String apn, String apnType, in LinkProperties linkProperties, + in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); + void notifyDataConnectionForSubscriber(int phoneId, int subId, int state, + boolean isDataConnectivityPossible, + String apn, String apnType, in LinkProperties linkProperties, + in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); + @UnsupportedAppUsage + void notifyDataConnectionFailed(String apnType); + void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, String apnType); + @UnsupportedAppUsage(maxTargetSdk = 28) + void notifyCellLocation(in Bundle cellLocation); + void notifyCellLocationForSubscriber(in int subId, in Bundle cellLocation); + @UnsupportedAppUsage(maxTargetSdk = 28) + void notifyOtaspChanged(in int subId, in int otaspMode); + @UnsupportedAppUsage + void notifyCellInfo(in List cellInfo); + void notifyPhysicalChannelConfigurationForSubscriber(in int phoneId, in int subId, + in List configs); + void notifyPreciseCallState(int phoneId, int subId, int ringingCallState, + int foregroundCallState, int backgroundCallState); + void notifyDisconnectCause(int phoneId, int subId, int disconnectCause, + int preciseDisconnectCause); + void notifyPreciseDataConnectionFailed(int phoneId, int subId, String apnType, String apn, + int failCause); + void notifyCellInfoForSubscriber(in int subId, in List cellInfo); + void notifySrvccStateChanged(in int subId, in int lteState); + void notifySimActivationStateChangedForPhoneId(in int phoneId, in int subId, + int activationState, int activationType); + void notifyOemHookRawEventForSubscriber(in int phoneId, in int subId, in byte[] rawData); + void notifySubscriptionInfoChanged(); + void notifyOpportunisticSubscriptionInfoChanged(); + void notifyCarrierNetworkChange(in boolean active); + void notifyUserMobileDataStateChangedForPhoneId(in int phoneId, in int subId, in boolean state); + void notifyPhoneCapabilityChanged(in PhoneCapability capability); + void notifyActiveDataSubIdChanged(int activeDataSubId); + void notifyRadioPowerStateChanged(in int phoneId, in int subId, in int state); + void notifyEmergencyNumberList(in int phoneId, in int subId); + void notifyOutgoingEmergencyCall(in int phoneId, in int subId, + in EmergencyNumber emergencyNumber); + void notifyOutgoingEmergencySms(in int phoneId, in int subId, + in EmergencyNumber emergencyNumber); + void notifyCallQualityChanged(in CallQuality callQuality, int phoneId, int subId, + int callNetworkType); + void notifyImsDisconnectCause(int subId, in ImsReasonInfo imsReasonInfo); +} diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java deleted file mode 100644 index 1ba0a41024ed..000000000000 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ /dev/null @@ -1,1280 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.telephony; - -import android.Manifest; -import android.annotation.NonNull; -import android.annotation.RequiresPermission; -import android.annotation.SystemApi; -import android.annotation.TestApi; -import android.annotation.UnsupportedAppUsage; -import android.os.Binder; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerExecutor; -import android.os.Looper; -import android.telephony.Annotation.CallState; -import android.telephony.Annotation.RadioPowerState; -import android.telephony.Annotation.SimActivationState; -import android.telephony.Annotation.SrvccState; -import android.telephony.emergency.EmergencyNumber; -import android.telephony.ims.ImsReasonInfo; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.telephony.IPhoneStateListener; - -import dalvik.system.VMRuntime; - -import java.lang.ref.WeakReference; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Executor; - -/** - * A listener class for monitoring changes in specific telephony states - * on the device, including service state, signal strength, message - * waiting indicator (voicemail), and others. - *

- * Override the methods for the state that you wish to receive updates for, and - * pass your PhoneStateListener object, along with bitwise-or of the LISTEN_ - * flags to {@link TelephonyManager#listen TelephonyManager.listen()}. Methods are - * called when the state changes, as well as once on initial registration. - *

- * Note that access to some telephony information is - * permission-protected. Your application won't receive updates for protected - * information unless it has the appropriate permissions declared in - * its manifest file. Where permissions apply, they are noted in the - * appropriate LISTEN_ flags. - */ -public class PhoneStateListener { - private static final String LOG_TAG = "PhoneStateListener"; - private static final boolean DBG = false; // STOPSHIP if true - - /** - * Stop listening for updates. - * - * The PhoneStateListener is not tied to any subscription and unregistered for any update. - */ - public static final int LISTEN_NONE = 0; - - /** - * Listen for changes to the network service state (cellular). - * - * @see #onServiceStateChanged - * @see ServiceState - */ - public static final int LISTEN_SERVICE_STATE = 0x00000001; - - /** - * Listen for changes to the network signal strength (cellular). - * {@more} - * - * @see #onSignalStrengthChanged - * - * @deprecated by {@link #LISTEN_SIGNAL_STRENGTHS} - */ - @Deprecated - public static final int LISTEN_SIGNAL_STRENGTH = 0x00000002; - - /** - * Listen for changes to the message-waiting indicator. - * {@more} - * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE - * READ_PHONE_STATE} or that the calling app has carrier privileges (see - * {@link TelephonyManager#hasCarrierPrivileges}). - *

- * Example: The status bar uses this to determine when to display the - * voicemail icon. - * - * @see #onMessageWaitingIndicatorChanged - */ - public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 0x00000004; - - /** - * Listen for changes to the call-forwarding indicator. - * {@more} - * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE - * READ_PHONE_STATE} or that the calling app has carrier privileges (see - * {@link TelephonyManager#hasCarrierPrivileges}). - * - * @see #onCallForwardingIndicatorChanged - */ - public static final int LISTEN_CALL_FORWARDING_INDICATOR = 0x00000008; - - /** - * Listen for changes to the device's cell location. Note that - * this will result in frequent callbacks to the listener. - * {@more} - * Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION - * ACCESS_COARSE_LOCATION} - *

- * If you need regular location updates but want more control over - * the update interval or location precision, you can set up a listener - * through the {@link android.location.LocationManager location manager} - * instead. - * - * @see #onCellLocationChanged - */ - public static final int LISTEN_CELL_LOCATION = 0x00000010; - - /** - * Listen for changes to the device call state. - * {@more} - * - * @see #onCallStateChanged - */ - public static final int LISTEN_CALL_STATE = 0x00000020; - - /** - * Listen for changes to the data connection state (cellular). - * - * @see #onDataConnectionStateChanged - */ - public static final int LISTEN_DATA_CONNECTION_STATE = 0x00000040; - - /** - * Listen for changes to the direction of data traffic on the data - * connection (cellular). - * {@more} - * Example: The status bar uses this to display the appropriate - * data-traffic icon. - * - * @see #onDataActivity - */ - public static final int LISTEN_DATA_ACTIVITY = 0x00000080; - - /** - * Listen for changes to the network signal strengths (cellular). - *

- * Example: The status bar uses this to control the signal-strength - * icon. - * - * @see #onSignalStrengthsChanged - */ - public static final int LISTEN_SIGNAL_STRENGTHS = 0x00000100; - - /** - * Listen for changes to OTASP mode. - * - * @see #onOtaspChanged - * @hide - */ - public static final int LISTEN_OTASP_CHANGED = 0x00000200; - - /** - * Listen for changes to observed cell info. - * - * @see #onCellInfoChanged - */ - public static final int LISTEN_CELL_INFO = 0x00000400; - - /** - * Listen for {@link android.telephony.Annotation.PreciseCallStates} of ringing, - * background and foreground calls. - * - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public static final int LISTEN_PRECISE_CALL_STATE = 0x00000800; - - /** - * Listen for {@link PreciseDataConnectionState} on the data connection (cellular). - * - * @see #onPreciseDataConnectionStateChanged - * - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 0x00001000; - - /** - * Listen for real time info for all data connections (cellular)). - * {@more} - * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE - * READ_PRECISE_PHONE_STATE} - * @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo) - * - * @deprecated Use {@link TelephonyManager#getModemActivityInfo()} - * @hide - */ - @Deprecated - public static final int LISTEN_DATA_CONNECTION_REAL_TIME_INFO = 0x00002000; - - /** - * Listen for changes to the SRVCC state of the active call. - * @see #onServiceStateChanged(ServiceState) - * @hide - */ - @SystemApi - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public static final int LISTEN_SRVCC_STATE_CHANGED = 0x00004000; - - /** - * Listen for OEM hook raw event - * - * @see #onOemHookRawEvent - * @hide - * @deprecated OEM needs a vendor-extension hal and their apps should use that instead - */ - @Deprecated - public static final int LISTEN_OEM_HOOK_RAW_EVENT = 0x00008000; - - /** - * Listen for carrier network changes indicated by a carrier app. - * - * @see #onCarrierNetworkRequest - * @see TelephonyManager#notifyCarrierNetworkChange(boolean) - * @hide - */ - public static final int LISTEN_CARRIER_NETWORK_CHANGE = 0x00010000; - - /** - * Listen for changes to the sim voice activation state - * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING - * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED - * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED - * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED - * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN - * {@more} - * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates voice service has been - * fully activated - * - * @see #onVoiceActivationStateChanged - * @hide - */ - @SystemApi - public static final int LISTEN_VOICE_ACTIVATION_STATE = 0x00020000; - - /** - * Listen for changes to the sim data activation state - * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING - * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED - * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED - * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED - * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN - * {@more} - * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates data service has been - * fully activated - * - * @see #onDataActivationStateChanged - * @hide - */ - public static final int LISTEN_DATA_ACTIVATION_STATE = 0x00040000; - - /** - * Listen for changes to the user mobile data state - * - * @see #onUserMobileDataStateChanged - */ - public static final int LISTEN_USER_MOBILE_DATA_STATE = 0x00080000; - - /** - * Listen for changes to the physical channel configuration. - * - * @see #onPhysicalChannelConfigurationChanged - * @hide - */ - public static final int LISTEN_PHYSICAL_CHANNEL_CONFIGURATION = 0x00100000; - - /** - * Listen for changes to the phone capability. - * - * @see #onPhoneCapabilityChanged - * @hide - */ - public static final int LISTEN_PHONE_CAPABILITY_CHANGE = 0x00200000; - - /** - * Listen for changes to active data subId. Active data subscription is - * the current subscription used to setup Cellular Internet data. For example, - * it could be the current active opportunistic subscription in use, or the - * subscription user selected as default data subscription in DSDS mode. - * - * @see #onActiveDataSubscriptionIdChanged - */ - public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 0x00400000; - - /** - * Listen for changes to the radio power state. - * - * @see #onRadioPowerStateChanged - * @hide - */ - @SystemApi - public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 0x00800000; - - /** - * Listen for changes to emergency number list based on all active subscriptions. - * - *

Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling - * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). - * - * @see #onEmergencyNumberListChanged - */ - public static final int LISTEN_EMERGENCY_NUMBER_LIST = 0x01000000; - - /** - * Listen for call disconnect causes which contains {@link DisconnectCause} and - * {@link PreciseDisconnectCause}. - * - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public static final int LISTEN_CALL_DISCONNECT_CAUSES = 0x02000000; - - /** - * Listen for changes to the call attributes of a currently active call. - * {@more} - * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE - * READ_PRECISE_PHONE_STATE} - * - * @see #onCallAttributesChanged - * @hide - */ - @SystemApi - public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 0x04000000; - - /** - * Listen for IMS call disconnect causes which contains - * {@link android.telephony.ims.ImsReasonInfo} - * - * @see #onImsCallDisconnectCauseChanged(ImsReasonInfo) - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public static final int LISTEN_IMS_CALL_DISCONNECT_CAUSES = 0x08000000; - - /** - * Listen for the emergency number placed from an outgoing call. - * - *

Requires permission {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION} - * - * @see #onOutgoingEmergencyCall - * @hide - */ - @SystemApi - @TestApi - @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) - public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 0x10000000; - - /** - * Listen for the emergency number placed from an outgoing SMS. - * - *

Requires permission {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION} - * - * @see #onOutgoingEmergencySms - * @hide - */ - @SystemApi - @TestApi - @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) - public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 0x20000000; - - /* - * Subscription used to listen to the phone state changes - * @hide - */ - /** @hide */ - @UnsupportedAppUsage - protected Integer mSubId; - - /** - * @hide - */ - @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - @UnsupportedAppUsage - public final IPhoneStateListener callback; - - /** - * Create a PhoneStateListener for the Phone with the default subscription. - * This class requires Looper.myLooper() not return null. - */ - public PhoneStateListener() { - this(null, Looper.myLooper()); - } - - /** - * Create a PhoneStateListener for the Phone with the default subscription - * using a particular non-null Looper. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public PhoneStateListener(Looper looper) { - this(null, looper); - } - - /** - * Create a PhoneStateListener for the Phone using the specified subscription. - * This class requires Looper.myLooper() not return null. To supply your - * own non-null Looper use PhoneStateListener(int subId, Looper looper) below. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public PhoneStateListener(Integer subId) { - this(subId, Looper.myLooper()); - if (subId != null && VMRuntime.getRuntime().getTargetSdkVersion() - >= Build.VERSION_CODES.Q) { - throw new IllegalArgumentException("PhoneStateListener with subId: " - + subId + " is not supported, use default constructor"); - } - } - /** - * Create a PhoneStateListener for the Phone using the specified subscription - * and non-null Looper. - * @hide - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) - public PhoneStateListener(Integer subId, Looper looper) { - this(subId, new HandlerExecutor(new Handler(looper))); - if (subId != null && VMRuntime.getRuntime().getTargetSdkVersion() - >= Build.VERSION_CODES.Q) { - throw new IllegalArgumentException("PhoneStateListener with subId: " - + subId + " is not supported, use default constructor"); - } - } - - /** - * Create a PhoneStateListener for the Phone using the specified Executor - * - *

Create a PhoneStateListener with a specified Executor for handling necessary callbacks. - * The Executor must not be null. - * - * @param executor a non-null Executor that will execute callbacks for the PhoneStateListener. - */ - public PhoneStateListener(@NonNull Executor executor) { - this(null, executor); - } - - private PhoneStateListener(Integer subId, Executor e) { - if (e == null) { - throw new IllegalArgumentException("PhoneStateListener Executor must be non-null"); - } - mSubId = subId; - callback = new IPhoneStateListenerStub(this, e); - } - - /** - * Callback invoked when device service state changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @see ServiceState#STATE_EMERGENCY_ONLY - * @see ServiceState#STATE_IN_SERVICE - * @see ServiceState#STATE_OUT_OF_SERVICE - * @see ServiceState#STATE_POWER_OFF - */ - public void onServiceStateChanged(ServiceState serviceState) { - // default implementation empty - } - - /** - * Callback invoked when network signal strength changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @see ServiceState#STATE_EMERGENCY_ONLY - * @see ServiceState#STATE_IN_SERVICE - * @see ServiceState#STATE_OUT_OF_SERVICE - * @see ServiceState#STATE_POWER_OFF - * @deprecated Use {@link #onSignalStrengthsChanged(SignalStrength)} - */ - @Deprecated - public void onSignalStrengthChanged(int asu) { - // default implementation empty - } - - /** - * Callback invoked when the message-waiting indicator changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - */ - public void onMessageWaitingIndicatorChanged(boolean mwi) { - // default implementation empty - } - - /** - * Callback invoked when the call-forwarding indicator changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - */ - public void onCallForwardingIndicatorChanged(boolean cfi) { - // default implementation empty - } - - /** - * Callback invoked when device cell location changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - */ - public void onCellLocationChanged(CellLocation location) { - // default implementation empty - } - - /** - * Callback invoked when device call state changes. - *

- * Reports the state of Telephony (mobile) calls on the device for the registered subscription. - *

- * Note: the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - *

- * Note: The state returned here may differ from that returned by - * {@link TelephonyManager#getCallState()}. Receivers of this callback should be aware that - * calling {@link TelephonyManager#getCallState()} from within this callback may return a - * different state than the callback reports. - * - * @param state call state - * @param phoneNumber call phone number. If application does not have - * {@link android.Manifest.permission#READ_CALL_LOG READ_CALL_LOG} permission or carrier - * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an empty string will be - * passed as an argument. - */ - public void onCallStateChanged(@CallState int state, String phoneNumber) { - // default implementation empty - } - - /** - * Callback invoked when connection state changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @see TelephonyManager#DATA_DISCONNECTED - * @see TelephonyManager#DATA_CONNECTING - * @see TelephonyManager#DATA_CONNECTED - * @see TelephonyManager#DATA_SUSPENDED - */ - public void onDataConnectionStateChanged(int state) { - // default implementation empty - } - - /** - * same as above, but with the network type. Both called. - */ - public void onDataConnectionStateChanged(int state, int networkType) { - } - - /** - * Callback invoked when data activity state changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @see TelephonyManager#DATA_ACTIVITY_NONE - * @see TelephonyManager#DATA_ACTIVITY_IN - * @see TelephonyManager#DATA_ACTIVITY_OUT - * @see TelephonyManager#DATA_ACTIVITY_INOUT - * @see TelephonyManager#DATA_ACTIVITY_DORMANT - */ - public void onDataActivity(int direction) { - // default implementation empty - } - - /** - * Callback invoked when network signal strengths changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - */ - public void onSignalStrengthsChanged(SignalStrength signalStrength) { - // default implementation empty - } - - - /** - * The Over The Air Service Provisioning (OTASP) has changed on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * Requires the READ_PHONE_STATE permission. - * @param otaspMode is integer OTASP_UNKNOWN=1 - * means the value is currently unknown and the system should wait until - * OTASP_NEEDED=2 or OTASP_NOT_NEEDED=3 is received before - * making the decision to perform OTASP or not. - * - * @hide - */ - @UnsupportedAppUsage - public void onOtaspChanged(int otaspMode) { - // default implementation empty - } - - /** - * Callback invoked when a observed cell info has changed or new cells have been added - * or removed on the registered subscription. - * Note, the registration subId s from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param cellInfo is the list of currently visible cells. - */ - public void onCellInfoChanged(List cellInfo) { - } - - /** - * Callback invoked when precise device call state changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * @param callState {@link PreciseCallState} - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public void onPreciseCallStateChanged(@NonNull PreciseCallState callState) { - // default implementation empty - } - - /** - * Callback invoked when call disconnect cause changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param disconnectCause {@link DisconnectCause}. - * @param preciseDisconnectCause {@link PreciseDisconnectCause}. - * - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) { - // default implementation empty - } - - /** - * Callback invoked when Ims call disconnect cause changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param imsReasonInfo {@link ImsReasonInfo} contains details on why IMS call failed. - * - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo) { - // default implementation empty - } - - /** - * Callback invoked when data connection state changes with precise information - * on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param dataConnectionState {@link PreciseDataConnectionState} - * - * @hide - */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - @SystemApi - public void onPreciseDataConnectionStateChanged( - @NonNull PreciseDataConnectionState dataConnectionState) { - // default implementation empty - } - - /** - * Callback invoked when data connection real time info changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @hide - */ - @UnsupportedAppUsage - public void onDataConnectionRealTimeInfoChanged( - DataConnectionRealTimeInfo dcRtInfo) { - // default implementation empty - } - - /** - * Callback invoked when there has been a change in the Single Radio Voice Call Continuity - * (SRVCC) state for the currently active call on the registered subscription. - * - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @hide - */ - @SystemApi - public void onSrvccStateChanged(@SrvccState int srvccState) { - - } - - /** - * Callback invoked when the SIM voice activation state has changed on the registered - * subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param state is the current SIM voice activation state - * @hide - */ - @SystemApi - public void onVoiceActivationStateChanged(@SimActivationState int state) { - } - - /** - * Callback invoked when the SIM data activation state has changed on the registered - * subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param state is the current SIM data activation state - * @hide - */ - public void onDataActivationStateChanged(@SimActivationState int state) { - } - - /** - * Callback invoked when the user mobile data state has changed on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param enabled indicates whether the current user mobile data state is enabled or disabled. - */ - public void onUserMobileDataStateChanged(boolean enabled) { - // default implementation empty - } - - /** - * Callback invoked when the current physical channel configuration has changed on the - * registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param configs List of the current {@link PhysicalChannelConfig}s - * @hide - */ - public void onPhysicalChannelConfigurationChanged( - @NonNull List configs) { - // default implementation empty - } - - /** - * Callback invoked when the current emergency number list has changed on the registered - * subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param emergencyNumberList Map including the key as the active subscription ID - * (Note: if there is no active subscription, the key is - * {@link SubscriptionManager#getDefaultSubscriptionId}) - * and the value as the list of {@link EmergencyNumber}; - * null if this information is not available. - * @hide - */ - public void onEmergencyNumberListChanged( - @NonNull Map> emergencyNumberList) { - // default implementation empty - } - - /** - * Callback invoked when an outgoing call is placed to an emergency number. - * - * @param placedEmergencyNumber the emergency number {@link EmergencyNumber} the call is placed - * to. - * @hide - */ - @SystemApi - @TestApi - public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber) { - // default implementation empty - } - - /** - * Callback invoked when an outgoing SMS is placed to an emergency number. - * - * @param sentEmergencyNumber the emergency number {@link EmergencyNumber} the SMS is sent to. - * @hide - */ - @SystemApi - @TestApi - public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber) { - // default implementation empty - } - - /** - * Callback invoked when OEM hook raw event is received on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * Requires the READ_PRIVILEGED_PHONE_STATE permission. - * @param rawData is the byte array of the OEM hook raw data. - * @hide - */ - @UnsupportedAppUsage - public void onOemHookRawEvent(byte[] rawData) { - // default implementation empty - } - - /** - * Callback invoked when phone capability changes. - * Note, this callback triggers regardless of registered subscription. - * - * Requires the READ_PRIVILEGED_PHONE_STATE permission. - * @param capability the new phone capability - * @hide - */ - public void onPhoneCapabilityChanged(PhoneCapability capability) { - // default implementation empty - } - - /** - * Callback invoked when active data subId changes. - * Note, this callback triggers regardless of registered subscription. - * - * Requires the READ_PHONE_STATE permission. - * @param subId current subscription used to setup Cellular Internet data. - * For example, it could be the current active opportunistic subscription in use, - * or the subscription user selected as default data subscription in DSDS mode. - */ - public void onActiveDataSubscriptionIdChanged(int subId) { - // default implementation empty - } - - /** - * Callback invoked when the call attributes changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * Requires the READ_PRIVILEGED_PHONE_STATE permission. - * @param callAttributes the call attributes - * @hide - */ - @SystemApi - public void onCallAttributesChanged(@NonNull CallAttributes callAttributes) { - // default implementation empty - } - - /** - * Callback invoked when modem radio power state changes on the registered subscription. - * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subId. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * Requires - * the READ_PRIVILEGED_PHONE_STATE permission. - * @param state the modem radio power state - * @hide - */ - @SystemApi - public void onRadioPowerStateChanged(@RadioPowerState int state) { - // default implementation empty - } - - /** - * Callback invoked when telephony has received notice from a carrier - * app that a network action that could result in connectivity loss - * has been requested by an app using - * {@link android.telephony.TelephonyManager#notifyCarrierNetworkChange(boolean)} - * - * Note, this callback is pinned to the registered subscription and will be invoked when - * the notifying carrier app has carrier privilege rule on the registered - * subscription. {@link android.telephony.TelephonyManager#hasCarrierPrivileges} - * - * @param active Whether the carrier network change is or shortly - * will be active. This value is true to indicate - * showing alternative UI and false to stop. - * - * @hide - */ - public void onCarrierNetworkChange(boolean active) { - // default implementation empty - } - - /** - * The callback methods need to be called on the handler thread where - * this object was created. If the binder did that for us it'd be nice. - * - * Using a static class and weak reference here to avoid memory leak caused by the - * IPhoneStateListener.Stub callback retaining references to the outside PhoneStateListeners: - * even caller has been destroyed and "un-registered" the PhoneStateListener, it is still not - * eligible for GC given the references coming from: - * Native Stack --> PhoneStateListener --> Context (Activity). - * memory of caller's context will be collected after GC from service side get triggered - */ - private static class IPhoneStateListenerStub extends IPhoneStateListener.Stub { - private WeakReference mPhoneStateListenerWeakRef; - private Executor mExecutor; - - IPhoneStateListenerStub(PhoneStateListener phoneStateListener, Executor executor) { - mPhoneStateListenerWeakRef = new WeakReference(phoneStateListener); - mExecutor = executor; - } - - public void onServiceStateChanged(ServiceState serviceState) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onServiceStateChanged(serviceState))); - } - - public void onSignalStrengthChanged(int asu) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onSignalStrengthChanged(asu))); - } - - public void onMessageWaitingIndicatorChanged(boolean mwi) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onMessageWaitingIndicatorChanged(mwi))); - } - - public void onCallForwardingIndicatorChanged(boolean cfi) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onCallForwardingIndicatorChanged(cfi))); - } - - public void onCellLocationChanged(Bundle bundle) { - CellLocation location = CellLocation.newFromBundle(bundle); - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onCellLocationChanged(location))); - } - - public void onCallStateChanged(int state, String incomingNumber) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onCallStateChanged(state, incomingNumber))); - } - - public void onDataConnectionStateChanged(int state, int networkType) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity(() -> mExecutor.execute( - () -> { - psl.onDataConnectionStateChanged(state, networkType); - psl.onDataConnectionStateChanged(state); - })); - } - - public void onDataActivity(int direction) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onDataActivity(direction))); - } - - public void onSignalStrengthsChanged(SignalStrength signalStrength) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onSignalStrengthsChanged(signalStrength))); - } - - public void onOtaspChanged(int otaspMode) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onOtaspChanged(otaspMode))); - } - - public void onCellInfoChanged(List cellInfo) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onCellInfoChanged(cellInfo))); - } - - public void onPreciseCallStateChanged(PreciseCallState callState) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onPreciseCallStateChanged(callState))); - } - - public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onCallDisconnectCauseChanged( - disconnectCause, preciseDisconnectCause))); - } - - public void onPreciseDataConnectionStateChanged( - PreciseDataConnectionState dataConnectionState) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onPreciseDataConnectionStateChanged(dataConnectionState))); - } - - public void onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo dcRtInfo) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onDataConnectionRealTimeInfoChanged(dcRtInfo))); - } - - public void onSrvccStateChanged(int state) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onSrvccStateChanged(state))); - } - - public void onVoiceActivationStateChanged(int activationState) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onVoiceActivationStateChanged(activationState))); - } - - public void onDataActivationStateChanged(int activationState) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onDataActivationStateChanged(activationState))); - } - - public void onUserMobileDataStateChanged(boolean enabled) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onUserMobileDataStateChanged(enabled))); - } - - public void onOemHookRawEvent(byte[] rawData) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onOemHookRawEvent(rawData))); - } - - public void onCarrierNetworkChange(boolean active) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onCarrierNetworkChange(active))); - } - - public void onPhysicalChannelConfigurationChanged(List configs) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onPhysicalChannelConfigurationChanged(configs))); - } - - public void onEmergencyNumberListChanged(Map emergencyNumberList) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onEmergencyNumberListChanged(emergencyNumberList))); - } - - public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onOutgoingEmergencyCall(placedEmergencyNumber))); - } - - public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onOutgoingEmergencySms(sentEmergencyNumber))); - } - - public void onPhoneCapabilityChanged(PhoneCapability capability) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onPhoneCapabilityChanged(capability))); - } - - public void onRadioPowerStateChanged(@RadioPowerState int state) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onRadioPowerStateChanged(state))); - } - - public void onCallAttributesChanged(CallAttributes callAttributes) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onCallAttributesChanged(callAttributes))); - } - - public void onActiveDataSubIdChanged(int subId) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> psl.onActiveDataSubscriptionIdChanged(subId))); - } - - public void onImsCallDisconnectCauseChanged(ImsReasonInfo disconnectCause) { - PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); - if (psl == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> psl.onImsCallDisconnectCauseChanged(disconnectCause))); - - } - } - - - private void log(String s) { - Rlog.d(LOG_TAG, s); - } -} diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 1b876575a742..86ee72104152 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -47,6 +47,7 @@ import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.Looper; import android.os.Message; import android.os.ParcelUuid; @@ -59,10 +60,8 @@ import android.telephony.ims.ImsMmTelManager; import android.util.DisplayMetrics; import android.util.Log; -import com.android.internal.telephony.IOnSubscriptionsChangedListener; import com.android.internal.telephony.ISetOpportunisticDataCallback; import com.android.internal.telephony.ISub; -import com.android.internal.telephony.ITelephonyRegistry; import com.android.internal.telephony.PhoneConstants; import com.android.internal.util.Preconditions; @@ -924,20 +923,24 @@ public class SubscriptionManager { OnSubscriptionsChangedListenerHandler(Looper looper) { super(looper); } - - @Override - public void handleMessage(Message msg) { - if (DBG) { - log("handleMessage: invoke the overriden onSubscriptionsChanged()"); - } - OnSubscriptionsChangedListener.this.onSubscriptionsChanged(); - } } - private final Handler mHandler; + /** + * Posted executor callback on the handler associated with a given looper. + * The looper can be the calling thread's looper or the looper passed from the + * constructor {@link #OnSubscriptionsChangedListener(Looper)}. + */ + private final HandlerExecutor mExecutor; + + /** + * @hide + */ + public HandlerExecutor getHandlerExecutor() { + return mExecutor; + } public OnSubscriptionsChangedListener() { - mHandler = new OnSubscriptionsChangedListenerHandler(); + mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler()); } /** @@ -946,7 +949,7 @@ public class SubscriptionManager { * @hide */ public OnSubscriptionsChangedListener(Looper looper) { - mHandler = new OnSubscriptionsChangedListenerHandler(looper); + mExecutor = new HandlerExecutor(new OnSubscriptionsChangedListenerHandler(looper)); } /** @@ -958,18 +961,6 @@ public class SubscriptionManager { if (DBG) log("onSubscriptionsChanged: NOT OVERRIDDEN"); } - /** - * The callback methods need to be called on the handler thread where - * this object was created. If the binder did that for us it'd be nice. - */ - IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { - @Override - public void onSubscriptionsChanged() { - if (DBG) log("callback: received, sendEmptyMessage(0) to handler"); - mHandler.sendEmptyMessage(0); - } - }; - private void log(String s) { Rlog.d(LOG_TAG, s); } @@ -1011,21 +1002,19 @@ public class SubscriptionManager { * onSubscriptionsChanged overridden. */ public void addOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { + if (listener == null) return; String pkgName = mContext != null ? mContext.getOpPackageName() : ""; if (DBG) { logd("register OnSubscriptionsChangedListener pkgName=" + pkgName + " listener=" + listener); } - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available. Where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.addOnSubscriptionsChangedListener(pkgName, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + // We use the TelephonyRegistry as it runs in the system and thus is always + // available. Where as SubscriptionController could crash and not be available + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.addOnSubscriptionsChangedListener(listener, + listener.mExecutor); } } @@ -1037,21 +1026,18 @@ public class SubscriptionManager { * @param listener that is to be unregistered. */ public void removeOnSubscriptionsChangedListener(OnSubscriptionsChangedListener listener) { + if (listener == null) return; String pkgForDebug = mContext != null ? mContext.getOpPackageName() : ""; if (DBG) { logd("unregister OnSubscriptionsChangedListener pkgForDebug=" + pkgForDebug + " listener=" + listener); } - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + // We use the TelephonyRegistry as it runs in the system and thus is always + // available where as SubscriptionController could crash and not be available + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.removeOnSubscriptionsChangedListener(listener); } } @@ -1070,7 +1056,6 @@ public class SubscriptionManager { * for #onOpportunisticSubscriptionsChanged to be invoked. */ public static class OnOpportunisticSubscriptionsChangedListener { - private Executor mExecutor; /** * Callback invoked when there is any change to any SubscriptionInfo. Typically * this method would invoke {@link #getActiveSubscriptionInfoList} @@ -1079,27 +1064,6 @@ public class SubscriptionManager { if (DBG) log("onOpportunisticSubscriptionsChanged: NOT OVERRIDDEN"); } - private void setExecutor(Executor executor) { - mExecutor = executor; - } - - /** - * The callback methods need to be called on the handler thread where - * this object was created. If the binder did that for us it'd be nice. - */ - IOnSubscriptionsChangedListener callback = new IOnSubscriptionsChangedListener.Stub() { - @Override - public void onSubscriptionsChanged() { - final long identity = Binder.clearCallingIdentity(); - try { - if (DBG) log("onOpportunisticSubscriptionsChanged callback received."); - mExecutor.execute(() -> onOpportunisticSubscriptionsChanged()); - } finally { - Binder.restoreCallingIdentity(identity); - } - } - }; - private void log(String s) { Rlog.d(LOG_TAG, s); } @@ -1126,18 +1090,13 @@ public class SubscriptionManager { + " listener=" + listener); } - listener.setExecutor(executor); - - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available. Where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.addOnOpportunisticSubscriptionsChangedListener(pkgName, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + // We use the TelephonyRegistry as it runs in the system and thus is always + // available where as SubscriptionController could crash and not be available + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.addOnOpportunisticSubscriptionsChangedListener( + listener, executor); } } @@ -1157,16 +1116,10 @@ public class SubscriptionManager { logd("unregister OnOpportunisticSubscriptionsChangedListener pkgForDebug=" + pkgForDebug + " listener=" + listener); } - try { - // We use the TelephonyRegistry as it runs in the system and thus is always - // available where as SubscriptionController could crash and not be available - ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( - "telephony.registry")); - if (tr != null) { - tr.removeOnSubscriptionsChangedListener(pkgForDebug, listener.callback); - } - } catch (RemoteException ex) { - Log.e(LOG_TAG, "Remote exception ITelephonyRegistry " + ex); + TelephonyRegistryManager telephonyRegistryManager = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (telephonyRegistryManager != null) { + telephonyRegistryManager.removeOnOpportunisticSubscriptionsChangedListener(listener); } } diff --git a/telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl b/telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl deleted file mode 100644 index 493b1ff6aba7..000000000000 --- a/telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -oneway interface IOnSubscriptionsChangedListener { - void onSubscriptionsChanged(); -} - diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl deleted file mode 100644 index 90019eef62fd..000000000000 --- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import android.os.Bundle; -import android.telephony.CallAttributes; -import android.telephony.CellInfo; -import android.telephony.DataConnectionRealTimeInfo; -import android.telephony.PhoneCapability; -import android.telephony.PhysicalChannelConfig; -import android.telephony.PreciseCallState; -import android.telephony.PreciseDataConnectionState; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import android.telephony.emergency.EmergencyNumber; -import android.telephony.ims.ImsReasonInfo; - -oneway interface IPhoneStateListener { - void onServiceStateChanged(in ServiceState serviceState); - void onSignalStrengthChanged(int asu); - void onMessageWaitingIndicatorChanged(boolean mwi); - void onCallForwardingIndicatorChanged(boolean cfi); - - // we use bundle here instead of CellLocation so it can get the right subclass - void onCellLocationChanged(in Bundle location); - void onCallStateChanged(int state, String incomingNumber); - void onDataConnectionStateChanged(int state, int networkType); - void onDataActivity(int direction); - void onSignalStrengthsChanged(in SignalStrength signalStrength); - void onPhysicalChannelConfigurationChanged(in List configs); - void onOtaspChanged(in int otaspMode); - void onCellInfoChanged(in List cellInfo); - void onPreciseCallStateChanged(in PreciseCallState callState); - void onPreciseDataConnectionStateChanged(in PreciseDataConnectionState dataConnectionState); - void onDataConnectionRealTimeInfoChanged(in DataConnectionRealTimeInfo dcRtInfo); - void onSrvccStateChanged(in int state); - void onVoiceActivationStateChanged(int activationState); - void onDataActivationStateChanged(int activationState); - void onOemHookRawEvent(in byte[] rawData); - void onCarrierNetworkChange(in boolean active); - void onUserMobileDataStateChanged(in boolean enabled); - void onPhoneCapabilityChanged(in PhoneCapability capability); - void onActiveDataSubIdChanged(in int subId); - void onRadioPowerStateChanged(in int state); - void onCallAttributesChanged(in CallAttributes callAttributes); - void onEmergencyNumberListChanged(in Map emergencyNumberList); - void onOutgoingEmergencyCall(in EmergencyNumber placedEmergencyNumber); - void onOutgoingEmergencySms(in EmergencyNumber sentEmergencyNumber); - void onCallDisconnectCauseChanged(in int disconnectCause, in int preciseDisconnectCause); - void onImsCallDisconnectCauseChanged(in ImsReasonInfo imsReasonInfo); -} - diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl deleted file mode 100644 index d7a7af1d530f..000000000000 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.internal.telephony; - -import android.content.Intent; -import android.net.LinkProperties; -import android.net.NetworkCapabilities; -import android.os.Bundle; -import android.telephony.CallQuality; -import android.telephony.CellInfo; -import android.telephony.ims.ImsReasonInfo; -import android.telephony.PhoneCapability; -import android.telephony.PhysicalChannelConfig; -import android.telephony.ServiceState; -import android.telephony.SignalStrength; -import android.telephony.emergency.EmergencyNumber; -import com.android.internal.telephony.IPhoneStateListener; -import com.android.internal.telephony.IOnSubscriptionsChangedListener; - -interface ITelephonyRegistry { - void addOnSubscriptionsChangedListener(String pkg, - IOnSubscriptionsChangedListener callback); - void addOnOpportunisticSubscriptionsChangedListener(String pkg, - IOnSubscriptionsChangedListener callback); - void removeOnSubscriptionsChangedListener(String pkg, - IOnSubscriptionsChangedListener callback); - @UnsupportedAppUsage - void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow); - void listenForSubscriber(in int subId, String pkg, IPhoneStateListener callback, int events, - boolean notifyNow); - @UnsupportedAppUsage - void notifyCallStateForAllSubs(int state, String incomingNumber); - void notifyCallState(in int phoneId, in int subId, int state, String incomingNumber); - void notifyServiceStateForPhoneId(in int phoneId, in int subId, in ServiceState state); - void notifySignalStrengthForPhoneId(in int phoneId, in int subId, - in SignalStrength signalStrength); - void notifyMessageWaitingChangedForPhoneId(in int phoneId, in int subId, in boolean mwi); - @UnsupportedAppUsage(maxTargetSdk = 28) - void notifyCallForwardingChanged(boolean cfi); - void notifyCallForwardingChangedForSubscriber(in int subId, boolean cfi); - @UnsupportedAppUsage(maxTargetSdk = 28) - void notifyDataActivity(int state); - void notifyDataActivityForSubscriber(in int subId, int state); - void notifyDataConnection(int state, boolean isDataConnectivityPossible, - String apn, String apnType, in LinkProperties linkProperties, - in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); - void notifyDataConnectionForSubscriber(int phoneId, int subId, int state, - boolean isDataConnectivityPossible, - String apn, String apnType, in LinkProperties linkProperties, - in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); - @UnsupportedAppUsage - void notifyDataConnectionFailed(String apnType); - void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, String apnType); - @UnsupportedAppUsage(maxTargetSdk = 28) - void notifyCellLocation(in Bundle cellLocation); - void notifyCellLocationForSubscriber(in int subId, in Bundle cellLocation); - @UnsupportedAppUsage(maxTargetSdk = 28) - void notifyOtaspChanged(in int subId, in int otaspMode); - @UnsupportedAppUsage - void notifyCellInfo(in List cellInfo); - void notifyPhysicalChannelConfigurationForSubscriber(in int phoneId, in int subId, - in List configs); - void notifyPreciseCallState(int phoneId, int subId, int ringingCallState, - int foregroundCallState, int backgroundCallState); - void notifyDisconnectCause(int phoneId, int subId, int disconnectCause, - int preciseDisconnectCause); - void notifyPreciseDataConnectionFailed(int phoneId, int subId, String apnType, String apn, - int failCause); - void notifyCellInfoForSubscriber(in int subId, in List cellInfo); - void notifySrvccStateChanged(in int subId, in int lteState); - void notifySimActivationStateChangedForPhoneId(in int phoneId, in int subId, - int activationState, int activationType); - void notifyOemHookRawEventForSubscriber(in int phoneId, in int subId, in byte[] rawData); - void notifySubscriptionInfoChanged(); - void notifyOpportunisticSubscriptionInfoChanged(); - void notifyCarrierNetworkChange(in boolean active); - void notifyUserMobileDataStateChangedForPhoneId(in int phoneId, in int subId, in boolean state); - void notifyPhoneCapabilityChanged(in PhoneCapability capability); - void notifyActiveDataSubIdChanged(int activeDataSubId); - void notifyRadioPowerStateChanged(in int phoneId, in int subId, in int state); - void notifyEmergencyNumberList(in int phoneId, in int subId); - void notifyOutgoingEmergencyCall(in int phoneId, in int subId, - in EmergencyNumber emergencyNumber); - void notifyOutgoingEmergencySms(in int phoneId, in int subId, - in EmergencyNumber emergencyNumber); - void notifyCallQualityChanged(in CallQuality callQuality, int phoneId, int subId, - int callNetworkType); - void notifyImsDisconnectCause(int subId, in ImsReasonInfo imsReasonInfo); -} -- cgit v1.2.3-59-g8ed1b