From 041679fa9a3987d12a68e188269f254b95e363a4 Mon Sep 17 00:00:00 2001 From: Zoey Chen Date: Tue, 24 Nov 2020 14:45:01 +0800 Subject: [PATCH] [Telephony] PhoneStateListener redesign for new event 1. Add int EVENT_* and expose these as @SystemApi 2. Add listener interface 3. Deprecated LISTEN_* 4. un/registerPhoneStateListener 5. get event from event listener 6. Add event to list Test: manual and atest TelephonyManagerTest#testRegisterPhoneStateListener atest TelephonyManagerPermissionTest atest CtsTelephonyTestCases:PhoneStateListenerTest atest TelephonyRegistryManagerTest atest CtsTelecomTestCases:android.telecom.cts.IncomingCallTest atest CtsTelecomTestCases:android.telecom.cts.OutgoingCallTest Bug: 167684594 Change-Id: Id89a541745fb8700e1ebd2cc162ee55cd1055661 Merged-In: Id89a541745fb8700e1ebd2cc162ee55cd1055661 --- core/api/current.txt | 160 +- core/api/system-current.txt | 86 +- .../android/telephony/PhoneStateListener.java | 1421 ++++++++++++++++- .../telephony/TelephonyRegistryManager.java | 380 ++++- .../telephony/IPhoneStateListener.aidl | 3 + .../telephony/ITelephonyRegistry.aidl | 15 +- .../com/android/server/TelephonyRegistry.java | 926 ++++++----- .../android/telephony/PhoneCapability.java | 2 - .../telephony/PhysicalChannelConfig.java | 55 +- .../android/telephony/TelephonyManager.java | 113 +- 10 files changed, 2641 insertions(+), 520 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 252c33c4efda9..4c2a1db000db5 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -40486,6 +40486,12 @@ package android.telephony { field public static final int SCAN_TYPE_PERIODIC = 1; // 0x1 } + public final class PhoneCapability implements android.os.Parcelable { + method public int describeContents(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + } + public class PhoneNumberFormattingTextWatcher implements android.text.TextWatcher { ctor public PhoneNumberFormattingTextWatcher(); ctor public PhoneNumberFormattingTextWatcher(String); @@ -40554,10 +40560,10 @@ package android.telephony { public class PhoneStateListener { ctor public PhoneStateListener(); - ctor public PhoneStateListener(@NonNull java.util.concurrent.Executor); + ctor @Deprecated public PhoneStateListener(@NonNull java.util.concurrent.Executor); method public void onActiveDataSubscriptionIdChanged(int); method public void onBarringInfoChanged(@NonNull android.telephony.BarringInfo); - method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onCallDisconnectCauseChanged(int, int); + method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallDisconnectCauseChanged(int, int); method public void onCallForwardingIndicatorChanged(boolean); method public void onCallStateChanged(int, String); method public void onCellInfoChanged(java.util.List); @@ -40565,36 +40571,140 @@ package android.telephony { method public void onDataActivity(int); method public void onDataConnectionStateChanged(int); method public void onDataConnectionStateChanged(int, int); - method @RequiresPermission("android.permission.READ_PHONE_STATE") public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo); + method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo); method public void onEmergencyNumberListChanged(@NonNull java.util.Map>); - method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo); + method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo); method public void onMessageWaitingIndicatorChanged(boolean); - method @RequiresPermission("android.permission.MODIFY_PHONE_STATE") public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState); method public void onRegistrationFailed(@NonNull android.telephony.CellIdentity, @NonNull String, int, int, int); method public void onServiceStateChanged(android.telephony.ServiceState); method @Deprecated public void onSignalStrengthChanged(int); method public void onSignalStrengthsChanged(android.telephony.SignalStrength); method public void onUserMobileDataStateChanged(boolean); - field public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 4194304; // 0x400000 - field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_BARRING_INFO = -2147483648; // 0x80000000 - field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_DISCONNECT_CAUSES = 33554432; // 0x2000000 - field public static final int LISTEN_CALL_FORWARDING_INDICATOR = 8; // 0x8 - field public static final int LISTEN_CALL_STATE = 32; // 0x20 - field public static final int LISTEN_CELL_INFO = 1024; // 0x400 - field public static final int LISTEN_CELL_LOCATION = 16; // 0x10 - field public static final int LISTEN_DATA_ACTIVITY = 128; // 0x80 - field public static final int LISTEN_DATA_CONNECTION_STATE = 64; // 0x40 - field public static final int LISTEN_DISPLAY_INFO_CHANGED = 1048576; // 0x100000 - field public static final int LISTEN_EMERGENCY_NUMBER_LIST = 16777216; // 0x1000000 - field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_IMS_CALL_DISCONNECT_CAUSES = 134217728; // 0x8000000 - field public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 4; // 0x4 + field @Deprecated public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 4194304; // 0x400000 + field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_BARRING_INFO = -2147483648; // 0x80000000 + field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_CALL_DISCONNECT_CAUSES = 33554432; // 0x2000000 + field @Deprecated public static final int LISTEN_CALL_FORWARDING_INDICATOR = 8; // 0x8 + field @Deprecated public static final int LISTEN_CALL_STATE = 32; // 0x20 + field @Deprecated public static final int LISTEN_CELL_INFO = 1024; // 0x400 + field @Deprecated public static final int LISTEN_CELL_LOCATION = 16; // 0x10 + field @Deprecated public static final int LISTEN_DATA_ACTIVITY = 128; // 0x80 + field @Deprecated public static final int LISTEN_DATA_CONNECTION_STATE = 64; // 0x40 + field @Deprecated public static final int LISTEN_DISPLAY_INFO_CHANGED = 1048576; // 0x100000 + field @Deprecated public static final int LISTEN_EMERGENCY_NUMBER_LIST = 16777216; // 0x1000000 + field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_IMS_CALL_DISCONNECT_CAUSES = 134217728; // 0x8000000 + field @Deprecated public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 4; // 0x4 field public static final int LISTEN_NONE = 0; // 0x0 - field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 4096; // 0x1000 - field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_REGISTRATION_FAILURE = 1073741824; // 0x40000000 - field public static final int LISTEN_SERVICE_STATE = 1; // 0x1 + field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 4096; // 0x1000 + field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_REGISTRATION_FAILURE = 1073741824; // 0x40000000 + field @Deprecated public static final int LISTEN_SERVICE_STATE = 1; // 0x1 field @Deprecated public static final int LISTEN_SIGNAL_STRENGTH = 2; // 0x2 - field public static final int LISTEN_SIGNAL_STRENGTHS = 256; // 0x100 - field public static final int LISTEN_USER_MOBILE_DATA_STATE = 524288; // 0x80000 + field @Deprecated public static final int LISTEN_SIGNAL_STRENGTHS = 256; // 0x100 + field @Deprecated public static final int LISTEN_USER_MOBILE_DATA_STATE = 524288; // 0x80000 + } + + public static interface PhoneStateListener.ActiveDataSubscriptionIdChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onActiveDataSubscriptionIdChanged(int); + } + + public static interface PhoneStateListener.AlwaysReportedSignalStrengthChangedListener { + method @RequiresPermission("android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH") public void onSignalStrengthsChanged(@NonNull android.telephony.SignalStrength); + } + + public static interface PhoneStateListener.BarringInfoChangedListener { + method @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void onBarringInfoChanged(@NonNull android.telephony.BarringInfo); + } + + public static interface PhoneStateListener.CallDisconnectCauseChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallDisconnectCauseChanged(int, int); + } + + public static interface PhoneStateListener.CallForwardingIndicatorChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onCallForwardingIndicatorChanged(boolean); + } + + public static interface PhoneStateListener.CallStateChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) public void onCallStateChanged(int, @Nullable String); + } + + public static interface PhoneStateListener.CarrierNetworkChangeListener { + method public void onCarrierNetworkChange(boolean); + } + + public static interface PhoneStateListener.CellInfoChangedListener { + method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void onCellInfoChanged(@NonNull java.util.List); + } + + public static interface PhoneStateListener.CellLocationChangedListener { + method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void onCellLocationChanged(@NonNull android.telephony.CellLocation); + } + + public static interface PhoneStateListener.DataActivationStateChangedListener { + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onDataActivationStateChanged(int); + } + + public static interface PhoneStateListener.DataActivityListener { + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onDataActivity(int); + } + + public static interface PhoneStateListener.DataConnectionStateChangedListener { + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onDataConnectionStateChanged(int, int); + } + + public static interface PhoneStateListener.DisplayInfoChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onDisplayInfoChanged(@NonNull android.telephony.TelephonyDisplayInfo); + } + + public static interface PhoneStateListener.EmergencyNumberListChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onEmergencyNumberListChanged(@NonNull java.util.Map>); + } + + public static interface PhoneStateListener.ImsCallDisconnectCauseChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onImsCallDisconnectCauseChanged(@NonNull android.telephony.ims.ImsReasonInfo); + } + + public static interface PhoneStateListener.MessageWaitingIndicatorChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onMessageWaitingIndicatorChanged(boolean); + } + + public static interface PhoneStateListener.PhoneCapabilityChangedListener { + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onPhoneCapabilityChanged(@NonNull android.telephony.PhoneCapability); + } + + public static interface PhoneStateListener.PreciseDataConnectionStateChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState); + } + + public static interface PhoneStateListener.RegistrationFailedListener { + method @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void onRegistrationFailed(@NonNull android.telephony.CellIdentity, @NonNull String, int, int, int); + } + + public static interface PhoneStateListener.ServiceStateChangedListener { + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onServiceStateChanged(@NonNull android.telephony.ServiceState); + } + + public static interface PhoneStateListener.SignalStrengthsChangedListener { + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onSignalStrengthsChanged(@NonNull android.telephony.SignalStrength); + } + + public static interface PhoneStateListener.UserMobileDataStateChangedListener { + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onUserMobileDataStateChanged(boolean); + } + + public final class PhysicalChannelConfig implements android.os.Parcelable { + method public int describeContents(); + method public int getCellBandwidthDownlink(); + method public int getChannelNumber(); + method public int getConnectionStatus(); + method public int getNetworkType(); + method @IntRange(from=0, to=1007) public int getPhysicalCellId(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field public static final int CHANNEL_NUMBER_UNKNOWN = -1; // 0xffffffff + field public static final int CONNECTION_PRIMARY_SERVING = 1; // 0x1 + field public static final int CONNECTION_SECONDARY_SERVING = 2; // 0x2 + field public static final int CONNECTION_UNKNOWN = -1; // 0xffffffff + field @NonNull public static final android.os.Parcelable.Creator CREATOR; + field public static final int PHYSICAL_CELL_ID_UNKNOWN = -1; // 0xffffffff } public final class PreciseDataConnectionState implements android.os.Parcelable { @@ -41105,7 +41215,8 @@ package android.telephony { method public boolean isVoiceCapable(); method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle); method public boolean isWorldPhone(); - method public void listen(android.telephony.PhoneStateListener, int); + method @Deprecated public void listen(android.telephony.PhoneStateListener, int); + method public void registerPhoneStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.PhoneStateListener); method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestCellInfoUpdate(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, java.util.concurrent.Executor, android.telephony.TelephonyScanManager.NetworkScanCallback); method public void sendDialerSpecialCode(String); @@ -41128,6 +41239,7 @@ package android.telephony { method @Deprecated public void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri); method @Deprecated public void setVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle, boolean); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void switchMultiSimConfig(int); + method public void unregisterPhoneStateListener(@NonNull android.telephony.PhoneStateListener); method public void updateAvailableNetworks(@NonNull java.util.List, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer); field public static final String ACTION_CARRIER_MESSAGING_CLIENT_SERVICE = "android.telephony.action.CARRIER_MESSAGING_CLIENT_SERVICE"; field public static final String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL"; diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 328d17758ca5c..966d71487c0e1 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -9804,17 +9804,87 @@ package android.telephony { method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int); method @Deprecated public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber); method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber, int); - method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState); + method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState); method public void onRadioPowerStateChanged(int); method public void onSrvccStateChanged(int); method public void onVoiceActivationStateChanged(int); - field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000 - field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000 - field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000 - field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800 - field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000 - field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_SRVCC_STATE_CHANGED = 16384; // 0x4000 - field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000 + field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED = 23; // 0x17 + field @RequiresPermission("android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH") public static final int EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED = 10; // 0xa + field @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static final int EVENT_BARRING_INFO_CHANGED = 32; // 0x20 + field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_CALL_ATTRIBUTES_CHANGED = 27; // 0x1b + field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_CALL_DISCONNECT_CAUSE_CHANGED = 26; // 0x1a + field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_CALL_FORWARDING_INDICATOR_CHANGED = 4; // 0x4 + field @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) public static final int EVENT_CALL_STATE_CHANGED = 6; // 0x6 + field public static final int EVENT_CARRIER_NETWORK_CHANGED = 17; // 0x11 + field @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static final int EVENT_CELL_INFO_CHANGED = 11; // 0xb + field @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public static final int EVENT_CELL_LOCATION_CHANGED = 5; // 0x5 + field public static final int EVENT_DATA_ACTIVATION_STATE_CHANGED = 19; // 0x13 + field public static final int EVENT_DATA_ACTIVITY_CHANGED = 8; // 0x8 + field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED = 14; // 0xe + field public static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 7; // 0x7 + field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_DATA_ENABLED_CHANGED = 34; // 0x22 + field public static final int EVENT_DISPLAY_INFO_CHANGED = 21; // 0x15 + field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_EMERGENCY_NUMBER_LIST_CHANGED = 25; // 0x19 + field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED = 28; // 0x1c + field @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public static final int EVENT_MESSAGE_WAITING_INDICATOR_CHANGED = 3; // 0x3 + field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_OEM_HOOK_RAW = 15; // 0xf + field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int EVENT_OUTGOING_EMERGENCY_CALL = 29; // 0x1d + field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int EVENT_OUTGOING_EMERGENCY_SMS = 30; // 0x1e + field public static final int EVENT_PHONE_CAPABILITY_CHANGED = 22; // 0x16 + field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 33; // 0x21 + field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_PRECISE_CALL_STATE_CHANGED = 12; // 0xc + field @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED = 13; // 0xd + field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_RADIO_POWER_STATE_CHANGED = 24; // 0x18 + field @RequiresPermission(allOf={android.Manifest.permission.READ_PRECISE_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public static final int EVENT_REGISTRATION_FAILURE = 31; // 0x1f + field public static final int EVENT_SERVICE_STATE_CHANGED = 1; // 0x1 + field public static final int EVENT_SIGNAL_STRENGTHS_CHANGED = 9; // 0x9 + field public static final int EVENT_SIGNAL_STRENGTH_CHANGED = 2; // 0x2 + field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_SRVCC_STATE_CHANGED = 16; // 0x10 + field public static final int EVENT_USER_MOBILE_DATA_STATE_CHANGED = 20; // 0x14 + field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int EVENT_VOICE_ACTIVATION_STATE_CHANGED = 18; // 0x12 + field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 67108864; // 0x4000000 + field @Deprecated @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000 + field @Deprecated @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000 + field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800 + field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000 + field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_SRVCC_STATE_CHANGED = 16384; // 0x4000 + field @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000 + } + + public static interface PhoneStateListener.CallAttributesChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onCallAttributesChanged(@NonNull android.telephony.CallAttributes); + } + + public static interface PhoneStateListener.DataEnabledChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onDataEnabledChanged(boolean, int); + } + + public static interface PhoneStateListener.OutgoingEmergencyCallListener { + method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber, int); + } + + public static interface PhoneStateListener.OutgoingEmergencySmsListener { + method @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber, int); + } + + public static interface PhoneStateListener.PhysicalChannelConfigChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPhysicalChannelConfigChanged(@NonNull java.util.List); + } + + public static interface PhoneStateListener.PreciseCallStateChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState); + } + + public static interface PhoneStateListener.RadioPowerStateChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onRadioPowerStateChanged(int); + } + + public static interface PhoneStateListener.SrvccStateChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onSrvccStateChanged(int); + } + + public static interface PhoneStateListener.VoiceActivationStateChangedListener { + method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void onVoiceActivationStateChanged(int); } public final class PinResult implements android.os.Parcelable { diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index d6ae434af9d55..03d3755111aab 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -17,7 +17,10 @@ package android.telephony; import android.Manifest; +import android.annotation.CallbackExecutor; +import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; @@ -29,9 +32,16 @@ import android.os.Handler; import android.os.HandlerExecutor; import android.os.Looper; import android.telephony.Annotation.CallState; +import android.telephony.Annotation.DataActivityType; +import android.telephony.Annotation.DisconnectCauses; +import android.telephony.Annotation.NetworkType; +import android.telephony.Annotation.PreciseDisconnectCauses; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SimActivationState; import android.telephony.Annotation.SrvccState; +import android.telephony.NetworkRegistrationInfo.Domain; +import android.telephony.TelephonyManager.DataEnabledReason; +import android.telephony.TelephonyManager.DataState; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; @@ -40,6 +50,8 @@ import com.android.internal.telephony.IPhoneStateListener; import dalvik.system.VMRuntime; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.util.List; import java.util.Map; @@ -114,7 +126,9 @@ public class PhoneStateListener { * * @see #onServiceStateChanged * @see ServiceState + * @deprecated Use {@link ServiceStateChangedListener} instead. */ + @Deprecated public static final int LISTEN_SERVICE_STATE = 0x00000001; /** @@ -122,8 +136,7 @@ public class PhoneStateListener { * {@more} * * @see #onSignalStrengthChanged - * - * @deprecated by {@link #LISTEN_SIGNAL_STRENGTHS} + * @deprecated Use {@link SignalStrengthsChangedListener} instead. */ @Deprecated public static final int LISTEN_SIGNAL_STRENGTH = 0x00000002; @@ -139,7 +152,9 @@ public class PhoneStateListener { * voicemail icon. * * @see #onMessageWaitingIndicatorChanged + * @deprecated Use {@link MessageWaitingIndicatorChangedListener} instead. */ + @Deprecated public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 0x00000004; /** @@ -150,7 +165,9 @@ public class PhoneStateListener { * {@link TelephonyManager#hasCarrierPrivileges}). * * @see #onCallForwardingIndicatorChanged + * @deprecated Use {@link CallForwardingIndicatorChangedListener} instead. */ + @Deprecated public static final int LISTEN_CALL_FORWARDING_INDICATOR = 0x00000008; /** @@ -166,7 +183,9 @@ public class PhoneStateListener { * instead. * * @see #onCellLocationChanged + * @deprecated Use {@link CellLocationChangedListener} instead. */ + @Deprecated public static final int LISTEN_CELL_LOCATION = 0x00000010; /** @@ -174,14 +193,18 @@ public class PhoneStateListener { * {@more} * * @see #onCallStateChanged + * @deprecated Use {@link CallStateChangedListener} instead. */ + @Deprecated public static final int LISTEN_CALL_STATE = 0x00000020; /** * Listen for changes to the data connection state (cellular). * * @see #onDataConnectionStateChanged + * @deprecated Use {@link DataConnectionStateChangedListener} instead. */ + @Deprecated public static final int LISTEN_DATA_CONNECTION_STATE = 0x00000040; /** @@ -192,7 +215,9 @@ public class PhoneStateListener { * data-traffic icon. * * @see #onDataActivity + * @deprecated Use {@link DataActivityListener} instead. */ + @Deprecated public static final int LISTEN_DATA_ACTIVITY = 0x00000080; /** @@ -202,7 +227,9 @@ public class PhoneStateListener { * icon. * * @see #onSignalStrengthsChanged + * @deprecated Use {@link SignalStrengthsChangedListener} instead. */ + @Deprecated public static final int LISTEN_SIGNAL_STRENGTHS = 0x00000100; /** @@ -212,7 +239,9 @@ public class PhoneStateListener { * @see #onSignalStrengthsChanged * * @hide + * @deprecated Use {@link AlwaysReportedSignalStrengthChangedListener} instead. */ + @Deprecated @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) public static final int LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH = 0x00000200; @@ -223,7 +252,9 @@ public class PhoneStateListener { * permission. * * @see #onCellInfoChanged + * @deprecated Use {@link CellInfoChangedListener} instead. */ + @Deprecated public static final int LISTEN_CELL_INFO = 0x00000400; /** @@ -235,8 +266,10 @@ public class PhoneStateListener { * (see {@link TelephonyManager#hasCarrierPrivileges}). * * @hide + * @deprecated Use {@link PreciseCallStateChangedListener} instead. */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) + @Deprecated + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) @SystemApi public static final int LISTEN_PRECISE_CALL_STATE = 0x00000800; @@ -248,8 +281,10 @@ public class PhoneStateListener { * (see {@link TelephonyManager#hasCarrierPrivileges}). * * @see #onPreciseDataConnectionStateChanged + * @deprecated Use {@link PreciseDataConnectionStateChangedListener} instead. */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) + @Deprecated + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 0x00001000; /** @@ -259,7 +294,7 @@ public class PhoneStateListener { * READ_PRECISE_PHONE_STATE} * @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo) * - * @deprecated Use {@link TelephonyManager#getModemActivityInfo()} + * @deprecated Use {@link TelephonyManager#requestModemActivityInfo} instead. * @hide */ @Deprecated @@ -272,7 +307,9 @@ public class PhoneStateListener { * * @see #onServiceStateChanged(ServiceState) * @hide + * @deprecated Use {@link SrvccStateChangedListener} instead. */ + @Deprecated @SystemApi @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_SRVCC_STATE_CHANGED = 0x00004000; @@ -290,10 +327,11 @@ public class PhoneStateListener { /** * Listen for carrier network changes indicated by a carrier app. * - * @see #onCarrierNetworkRequest - * @see TelephonyManager#notifyCarrierNetworkChange(boolean) + * @see android.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean) * @hide + * @deprecated Use {@link CarrierNetworkChangeListener} instead. */ + @Deprecated public static final int LISTEN_CARRIER_NETWORK_CHANGE = 0x00010000; /** @@ -312,7 +350,9 @@ public class PhoneStateListener { * * @see #onVoiceActivationStateChanged * @hide + * @deprecated Use {@link VoiceActivationStateChangedListener} instead. */ + @Deprecated @SystemApi @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_VOICE_ACTIVATION_STATE = 0x00020000; @@ -324,20 +364,24 @@ public class PhoneStateListener { * @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 + * @deprecated Use {@link DataActivationStateChangedListener} instead. */ + @Deprecated public static final int LISTEN_DATA_ACTIVATION_STATE = 0x00040000; /** * Listen for changes to the user mobile data state * * @see #onUserMobileDataStateChanged + * @deprecated Use {@link UserMobileDataStateChangedListener} instead. */ + @Deprecated public static final int LISTEN_USER_MOBILE_DATA_STATE = 0x00080000; /** @@ -348,7 +392,9 @@ public class PhoneStateListener { * {@link TelephonyManager#hasCarrierPrivileges}). * * @see #onDisplayInfoChanged + * @deprecated Use {@link DisplayInfoChangedListener} instead. */ + @Deprecated public static final int LISTEN_DISPLAY_INFO_CHANGED = 0x00100000; /** @@ -356,7 +402,9 @@ public class PhoneStateListener { * * @see #onPhoneCapabilityChanged * @hide + * @deprecated Use {@link PhoneCapabilityChangedListener} instead. */ + @Deprecated public static final int LISTEN_PHONE_CAPABILITY_CHANGE = 0x00200000; /** @@ -366,17 +414,19 @@ public class PhoneStateListener { * subscription user selected as default data subscription in DSDS mode. * * @see #onActiveDataSubscriptionIdChanged + * @deprecated Use {@link ActiveDataSubscriptionIdChangedListener} instead. */ + @Deprecated public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 0x00400000; /** * Listen for changes to the radio power state. * - *

Requires permission {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} - * * @see #onRadioPowerStateChanged * @hide + * @deprecated Use {@link RadioPowerStateChangedListener} instead. */ + @Deprecated @SystemApi @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 0x00800000; @@ -386,7 +436,10 @@ public class PhoneStateListener { * *

Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @deprecated Use {@link EmergencyNumberListChangedListener} instead. */ + @Deprecated public static final int LISTEN_EMERGENCY_NUMBER_LIST = 0x01000000; /** @@ -397,8 +450,10 @@ public class PhoneStateListener { * or the calling app has carrier privileges * (see {@link TelephonyManager#hasCarrierPrivileges}). * + * @deprecated Use {@link CallDisconnectCauseChangedListener} instead. */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) + @Deprecated + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_CALL_DISCONNECT_CAUSES = 0x02000000; /** @@ -410,9 +465,11 @@ public class PhoneStateListener { * * @see #onCallAttributesChanged * @hide + * @deprecated Use {@link CallAttributesChangedListener} instead. */ + @Deprecated @SystemApi - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_CALL_ATTRIBUTES_CHANGED = 0x04000000; /** @@ -424,18 +481,20 @@ public class PhoneStateListener { * (see {@link TelephonyManager#hasCarrierPrivileges}). * * @see #onImsCallDisconnectCauseChanged(ImsReasonInfo) + * @deprecated Use {@link ImsCallDisconnectCauseChangedListener} instead. */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) + @Deprecated + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) 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 + * @deprecated Use {@link OutgoingEmergencyCallListener} instead. */ + @Deprecated @SystemApi @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 0x10000000; @@ -443,11 +502,11 @@ public class PhoneStateListener { /** * Listen for the emergency number placed from an outgoing SMS. * - *

Requires permission {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION} - * * @see #onOutgoingEmergencySms * @hide + * @deprecated Use {@link OutgoingEmergencySmsListener} instead. */ + @Deprecated @SystemApi @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 0x20000000; @@ -466,7 +525,9 @@ public class PhoneStateListener { * of whether the calling app has carrier privileges. * * @see #onRegistrationFailed + * @deprecated Use {@link RegistrationFailedListener} instead. */ + @Deprecated @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_REGISTRATION_FAILURE = 0x40000000; @@ -480,10 +541,525 @@ public class PhoneStateListener { * of whether the calling app has carrier privileges. * * @see #onBarringInfoChanged + * @deprecated Use {@link BarringInfoChangedListener} instead. */ + @Deprecated @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_BARRING_INFO = 0x80000000; + /** + * Event for changes to the network service state (cellular). + * + * @see ServiceStateChangedListener#onServiceStateChanged + * @see ServiceState + * + * @hide + */ + @SystemApi + public static final int EVENT_SERVICE_STATE_CHANGED = 1; + + /** + * Event for changes to the network signal strength (cellular). + * + * @see SignalStrengthsChangedListener#onSignalStrengthsChanged + * + * @hide + */ + @SystemApi + public static final int EVENT_SIGNAL_STRENGTH_CHANGED = 2; + + /** + * Event for changes to the message-waiting indicator. + * + * Requires Permission: {@link android.Manifest.permission#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 MessageWaitingIndicatorChangedListener#onMessageWaitingIndicatorChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public static final int EVENT_MESSAGE_WAITING_INDICATOR_CHANGED = 3; + + /** + * Event for changes to the call-forwarding indicator. + * + * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE} or that + * the calling app has carrier privileges (see + * {@link TelephonyManager#hasCarrierPrivileges}). + * + * @see CallForwardingIndicatorChangedListener#onCallForwardingIndicatorChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public static final int EVENT_CALL_FORWARDING_INDICATOR_CHANGED = 4; + + /** + * Event for changes to the device's cell location. Note that + * this will result in frequent callbacks to the listener. + * + * 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 CellLocationChangedListener#onCellLocationChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) + public static final int EVENT_CELL_LOCATION_CHANGED = 5; + + /** + * Event for changes to the device call state. + * + * @see CallStateChangedListener#onCallStateChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) + public static final int EVENT_CALL_STATE_CHANGED = 6; + + /** + * Event for changes to the data connection state (cellular). + * + * @see DataConnectionStateChangedListener#onDataConnectionStateChanged + * + * @hide + */ + @SystemApi + public static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 7; + + /** + * Event for changes to the direction of data traffic on the data + * connection (cellular). + * + * Example: The status bar uses this to display the appropriate + * data-traffic icon. + * + * @see DataActivityListener#onDataActivity + * + * @hide + */ + @SystemApi + public static final int EVENT_DATA_ACTIVITY_CHANGED = 8; + + /** + * Event for changes to the network signal strengths (cellular). + *

+ * Example: The status bar uses this to control the signal-strength + * icon. + * + * @see SignalStrengthsChangedListener#onSignalStrengthsChanged + * + * @hide + */ + @SystemApi + public static final int EVENT_SIGNAL_STRENGTHS_CHANGED = 9; + + /** + * Event for changes of the network signal strengths (cellular) always reported from modem, + * even in some situations such as the screen of the device is off. + * + * @see AlwaysReportedSignalStrengthChangedListener#onSignalStrengthsChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) + public static final int EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED = 10; + + /** + * Event for changes to observed cell info. + * + * @see CellInfoChangedListener#onCellInfoChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) + public static final int EVENT_CELL_INFO_CHANGED = 11; + + /** + * Event for {@link android.telephony.Annotation.PreciseCallStates} of ringing, + * background and foreground calls. + * + *

Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @see PreciseCallStateChangedListener#onPreciseCallStateChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_PRECISE_CALL_STATE_CHANGED = 12; + + /** + * Event for {@link PreciseDataConnectionState} on the data connection (cellular). + * + *

Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @see PreciseDataConnectionStateChangedListener#onPreciseDataConnectionStateChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED = 13; + + /** + * Event for real time info for all data connections (cellular)). + * + * @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo) + * + * @deprecated Use {@link TelephonyManager#requestModemActivityInfo} + * @hide + */ + @Deprecated + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED = 14; + + /** + * Event for OEM hook raw event + * + * @see #onOemHookRawEvent + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public static final int EVENT_OEM_HOOK_RAW = 15; + + /** + * Event for changes to the SRVCC state of the active call. + * + * @see SrvccStateChangedListener#onSrvccStateChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public static final int EVENT_SRVCC_STATE_CHANGED = 16; + + /** + * Event for carrier network changes indicated by a carrier app. + * + * @see android.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean) + * @see CarrierNetworkChangeListener#onCarrierNetworkChange + * + * @hide + */ + @SystemApi + public static final int EVENT_CARRIER_NETWORK_CHANGED = 17; + + /** + * Event 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 + * + * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates voice service has been + * fully activated + * + * @see VoiceActivationStateChangedListener#onVoiceActivationStateChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public static final int EVENT_VOICE_ACTIVATION_STATE_CHANGED = 18; + + /** + * Event 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 + * + * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates data service has been + * fully activated + * + * @see DataActivationStateChangedListener#onDataActivationStateChanged + * @hide + */ + @SystemApi + public static final int EVENT_DATA_ACTIVATION_STATE_CHANGED = 19; + + /** + * Event for changes to the user mobile data state + * + * @see UserMobileDataStateChangedListener#onUserMobileDataStateChanged + * + * @hide + */ + @SystemApi + public static final int EVENT_USER_MOBILE_DATA_STATE_CHANGED = 20; + + /** + * Event for display info changed event. + * + * @see DisplayInfoChangedListener#onDisplayInfoChanged + * + * @hide + */ + @SystemApi + public static final int EVENT_DISPLAY_INFO_CHANGED = 21; + + /** + * Event for changes to the phone capability. + * + * @see PhoneCapabilityChangedListener#onPhoneCapabilityChanged + * + * @hide + */ + @SystemApi + public static final int EVENT_PHONE_CAPABILITY_CHANGED = 22; + + /** + * Event for changes to active data subscription ID. 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. + * + *

Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling + * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @see ActiveDataSubscriptionIdChangedListener#onActiveDataSubscriptionIdChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public static final int EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED = 23; + + /** + * Event for changes to the radio power state. + * + * @see RadioPowerStateChangedListener#onRadioPowerStateChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public static final int EVENT_RADIO_POWER_STATE_CHANGED = 24; + + /** + * Event 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 EmergencyNumberListChangedListener#onEmergencyNumberListChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public static final int EVENT_EMERGENCY_NUMBER_LIST_CHANGED = 25; + + /** + * Event for call disconnect causes which contains {@link DisconnectCause} and + * {@link PreciseDisconnectCause}. + * + *

Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @see CallDisconnectCauseChangedListener#onCallDisconnectCauseChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_CALL_DISCONNECT_CAUSE_CHANGED = 26; + + /** + * Event for changes to the call attributes of a currently active call. + * + *

Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @see CallAttributesChangedListener#onCallAttributesChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_CALL_ATTRIBUTES_CHANGED = 27; + + /** + * Event for IMS call disconnect causes which contains + * {@link android.telephony.ims.ImsReasonInfo} + * + *

Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @see ImsCallDisconnectCauseChangedListener#onImsCallDisconnectCauseChanged(ImsReasonInfo) + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED = 28; + + /** + * Event for the emergency number placed from an outgoing call. + * + * @see OutgoingEmergencyCallListener#onOutgoingEmergencyCall + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) + public static final int EVENT_OUTGOING_EMERGENCY_CALL = 29; + + /** + * Event for the emergency number placed from an outgoing SMS. + * + * @see OutgoingEmergencySmsListener#onOutgoingEmergencySms + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) + public static final int EVENT_OUTGOING_EMERGENCY_SMS = 30; + + /** + * Event for registration failures. + * + * Event for indications that a registration procedure has failed in either the CS or PS + * domain. This indication does not necessarily indicate a change of service state, which should + * be tracked via {@link #EVENT_SERVICE_STATE_CHANGED}. + * + *

Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or + * the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). + * + *

Also requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission, regardless + * of whether the calling app has carrier privileges. + * + * @see RegistrationFailedListener#onRegistrationFailed + * + * @hide + */ + @SystemApi + @RequiresPermission(allOf = { + Manifest.permission.READ_PRECISE_PHONE_STATE, + Manifest.permission.ACCESS_FINE_LOCATION + }) + public static final int EVENT_REGISTRATION_FAILURE = 31; + + /** + * Event for Barring Information for the current registered / camped cell. + * + *

Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or + * the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). + * + *

Also requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission, regardless + * of whether the calling app has carrier privileges. + * + * @see BarringInfoChangedListener#onBarringInfoChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(allOf = { + Manifest.permission.READ_PRECISE_PHONE_STATE, + Manifest.permission.ACCESS_FINE_LOCATION + }) + public static final int EVENT_BARRING_INFO_CHANGED = 32; + + /** + * Event for changes to the physical channel configuration. + * + *

Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @see PhysicalChannelConfigChangedListener#onPhysicalChannelConfigChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 33; + + /** + * Event for changes to the data enabled. + * + * Event for indications that the enabled status of current data has changed. + * + *

Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @see DataEnabledChangedListener#onDataEnabledChanged + * + * @hide + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_DATA_ENABLED_CHANGED = 34; + + /** @hide */ + @IntDef(prefix = { "EVENT_" }, value = { + EVENT_SERVICE_STATE_CHANGED, + EVENT_SIGNAL_STRENGTH_CHANGED, + EVENT_MESSAGE_WAITING_INDICATOR_CHANGED, + EVENT_CALL_FORWARDING_INDICATOR_CHANGED, + EVENT_CELL_LOCATION_CHANGED, + EVENT_CALL_STATE_CHANGED, + EVENT_DATA_CONNECTION_STATE_CHANGED, + EVENT_DATA_ACTIVITY_CHANGED, + EVENT_SIGNAL_STRENGTHS_CHANGED, + EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED, + EVENT_CELL_INFO_CHANGED, + EVENT_PRECISE_CALL_STATE_CHANGED, + EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED, + EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED, + EVENT_OEM_HOOK_RAW, + EVENT_SRVCC_STATE_CHANGED, + EVENT_CARRIER_NETWORK_CHANGED, + EVENT_VOICE_ACTIVATION_STATE_CHANGED, + EVENT_DATA_ACTIVATION_STATE_CHANGED, + EVENT_USER_MOBILE_DATA_STATE_CHANGED, + EVENT_DISPLAY_INFO_CHANGED, + EVENT_PHONE_CAPABILITY_CHANGED, + EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED, + EVENT_RADIO_POWER_STATE_CHANGED, + EVENT_EMERGENCY_NUMBER_LIST_CHANGED, + EVENT_CALL_DISCONNECT_CAUSE_CHANGED, + EVENT_CALL_ATTRIBUTES_CHANGED, + EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED, + EVENT_OUTGOING_EMERGENCY_CALL, + EVENT_OUTGOING_EMERGENCY_SMS, + EVENT_REGISTRATION_FAILURE, + EVENT_BARRING_INFO_CHANGED, + EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED, + EVENT_DATA_ENABLED_CHANGED + }) + @Retention(RetentionPolicy.SOURCE) + public @interface TelephonyEvent {} + /* * Subscription used to listen to the phone state changes * @hide @@ -495,13 +1071,19 @@ public class PhoneStateListener { /** * @hide */ + //TODO: The maxTargetSdk should be S if the build time tool updates it. @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - @UnsupportedAppUsage - public final IPhoneStateListener callback; + @UnsupportedAppUsage( + maxTargetSdk = Build.VERSION_CODES.R, + publicAlternatives = "Use {@code TelephonyManager#registerPhoneStateListener(" + + "Executor, PhoneStateListener)} instead") + public IPhoneStateListener callback; /** * Create a PhoneStateListener for the Phone with the default subscription. - * This class requires Looper.myLooper() not return null. + * If this is created for use with deprecated API + * {@link TelephonyManager#listen(PhoneStateListener, int)}, then this class requires + * Looper.myLooper() not return null. */ public PhoneStateListener() { this(null, Looper.myLooper()); @@ -539,7 +1121,10 @@ public class PhoneStateListener { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public PhoneStateListener(Integer subId, Looper looper) { - this(subId, new HandlerExecutor(new Handler(looper))); + if (looper != null) { + setExecutor(new HandlerExecutor(new Handler(looper))); + } + mSubId = subId; if (subId != null && VMRuntime.getRuntime().getTargetSdkVersion() >= Build.VERSION_CODES.Q) { throw new IllegalArgumentException("PhoneStateListener with subId: " @@ -554,17 +1139,744 @@ public class PhoneStateListener { * The Executor must not be null. * * @param executor a non-null Executor that will execute callbacks for the PhoneStateListener. + * @deprecated Use + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)} instead. */ + @Deprecated public PhoneStateListener(@NonNull Executor executor) { - this(null, executor); + setExecutor(executor); + mSubId = null; } - private PhoneStateListener(Integer subId, Executor e) { - if (e == null) { + private @NonNull Executor mExecutor; + + /** + * @hide + */ + public void setExecutor(@NonNull @CallbackExecutor Executor executor) { + if (executor == null) { throw new IllegalArgumentException("PhoneStateListener Executor must be non-null"); } - mSubId = subId; - callback = new IPhoneStateListenerStub(this, e); + mExecutor = executor; + callback = new IPhoneStateListenerStub(this, mExecutor); + } + + /** + * @hide + */ + public boolean isExecutorSet() { + return mExecutor != null; + } + + /** + * Interface for service state listener. + */ + public interface ServiceStateChangedListener { + /** + * Callback invoked when device service state changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * The instance of {@link ServiceState} passed as an argument here will have various + * levels of location information stripped from it depending on the location permissions + * that your app holds. + * Only apps holding the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission will + * receive all the information in {@link ServiceState}. + * + * @see ServiceState#STATE_EMERGENCY_ONLY + * @see ServiceState#STATE_IN_SERVICE + * @see ServiceState#STATE_OUT_OF_SERVICE + * @see ServiceState#STATE_POWER_OFF + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void onServiceStateChanged(@NonNull ServiceState serviceState); + } + + /** + * Interface for message waiting indicator listener. + */ + public interface MessageWaitingIndicatorChangedListener { + /** + * Callback invoked when the message-waiting indicator changes on the registered + * subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public void onMessageWaitingIndicatorChanged(boolean mwi); + } + + /** + * Interface for call-forwarding indicator listener. + */ + public interface CallForwardingIndicatorChangedListener { + /** + * Callback invoked when the call-forwarding indicator changes on the registered + * subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public void onCallForwardingIndicatorChanged(boolean cfi); + } + + /** + * Interface for device cell location listener. + */ + public interface CellLocationChangedListener { + /** + * Callback invoked when device cell location changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) + public void onCellLocationChanged(@NonNull CellLocation location); + } + + /** + * Interface for call state listener. + */ + public interface CallStateChangedListener { + /** + * Callback invoked when device call state changes. + *

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

+ * Note: the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to all subIds. + *

+ * 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} permission or carrier + * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an empty string will be + * passed as an argument. + */ + @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) + public void onCallStateChanged(@CallState int state, @Nullable String phoneNumber); + } + + /** + * Interface for data connection state listener. + */ + public interface DataConnectionStateChangedListener { + /** + * Callback invoked when connection state changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @see TelephonyManager#DATA_DISCONNECTED + * @see TelephonyManager#DATA_CONNECTING + * @see TelephonyManager#DATA_CONNECTED + * @see TelephonyManager#DATA_SUSPENDED + * + * @param state is the current state of data connection. + * @param networkType is the current network type of data connection. + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void onDataConnectionStateChanged(@DataState int state, + @NetworkType int networkType); + } + + /** + * Interface for data activity state listener. + */ + public interface DataActivityListener { + /** + * Callback invoked when data activity state changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. 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 + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void onDataActivity(@DataActivityType int direction); + } + + /** + * Interface for network signal strengths listener. + */ + public interface SignalStrengthsChangedListener { + /** + * Callback invoked when network signal strengths changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void onSignalStrengthsChanged(@NonNull SignalStrength signalStrength); + } + + /** + * Interface for network signal strengths listener which always reported from modem. + */ + public interface AlwaysReportedSignalStrengthChangedListener { + /** + * Callback always invoked from modem when network signal strengths changes on the + * registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) + public void onSignalStrengthsChanged(@NonNull SignalStrength signalStrength); + } + + /** + * Interface for cell info listener. + */ + public interface CellInfoChangedListener { + /** + * Callback invoked when a observed cell info has changed or new cells have been added + * or removed on the registered subscription. + * Note, the registration subscription ID s from {@link TelephonyManager} object + * which registersPhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param cellInfo is the list of currently visible cells. + */ + @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) + public void onCellInfoChanged(@NonNull List cellInfo); + } + + /** + * Interface for precise device call state listener. + * + * @hide + */ + @SystemApi + public interface PreciseCallStateChangedListener { + /** + * Callback invoked when precise device call state changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param callState {@link PreciseCallState} + */ + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public void onPreciseCallStateChanged(@NonNull PreciseCallState callState); + } + + /** + * Interface for call disconnect cause listener. + */ + public interface CallDisconnectCauseChangedListener { + /** + * Callback invoked when call disconnect cause changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param disconnectCause {@link DisconnectCause}. + * @param preciseDisconnectCause {@link PreciseDisconnectCause}. + */ + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public void onCallDisconnectCauseChanged(@DisconnectCauses int disconnectCause, + @PreciseDisconnectCauses int preciseDisconnectCause); + } + + /** + * Interface for IMS call disconnect cause listener. + */ + public interface ImsCallDisconnectCauseChangedListener { + /** + * Callback invoked when IMS call disconnect cause changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param imsReasonInfo {@link ImsReasonInfo} contains details on why IMS call failed. + * + */ + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo); + } + + /** + * Interface for precise data connection state listener. + */ + public interface PreciseDataConnectionStateChangedListener { + /** + * Callback providing update about the default/internet data connection on the registered + * subscription. + * + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + *

Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @param dataConnectionState {@link PreciseDataConnectionState} + */ + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public void onPreciseDataConnectionStateChanged( + @NonNull PreciseDataConnectionState dataConnectionState); + } + + /** + * Interface for Single Radio Voice Call Continuity listener. + * + * @hide + */ + @SystemApi + public interface SrvccStateChangedListener { + /** + * 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 subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void onSrvccStateChanged(@SrvccState int srvccState); + } + + /** + * Interface for SIM voice activation state listener. + * + * @hide + */ + @SystemApi + public interface VoiceActivationStateChangedListener { + /** + * Callback invoked when the SIM voice activation state has changed on the registered + * subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param state is the current SIM voice activation state + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void onVoiceActivationStateChanged(@SimActivationState int state); + + } + + /** + * Interface for SIM data activation state listener. + */ + public interface DataActivationStateChangedListener { + /** + * Callback invoked when the SIM data activation state has changed on the registered + * subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param state is the current SIM data activation state + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void onDataActivationStateChanged(@SimActivationState int state); + } + + /** + * Interface for user mobile data state listener. + */ + public interface UserMobileDataStateChangedListener { + /** + * Callback invoked when the user mobile data state has changed on the registered + * subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param enabled indicates whether the current user mobile data state is enabled or + * disabled. + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void onUserMobileDataStateChanged(boolean enabled); + } + + /** + * Interface for display info listener. + */ + public interface DisplayInfoChangedListener { + /** + * Callback invoked when the display info has changed on the registered subscription. + *

The {@link TelephonyDisplayInfo} contains status information shown to the user + * based on carrier policy. + * + * @param telephonyDisplayInfo The display information. + */ + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo telephonyDisplayInfo); + } + + /** + * Interface for the current emergency number list listener. + */ + public interface EmergencyNumberListChangedListener { + /** + * Callback invoked when the current emergency number list has changed on the registered + * subscription. + * + * Note, the registered subscription is associated with {@link TelephonyManager} object + * on which + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)} + * was called. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * given subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param emergencyNumberList Map associating all active subscriptions on the device with + * the list of emergency numbers originating from that + * subscription. + * If there are no active subscriptions, the map will contain a + * single entry with + * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} as + * the key and a list of emergency numbers as the value. If no + * emergency number information is available, the value will be + * empty. + */ + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public void onEmergencyNumberListChanged( + @NonNull Map> emergencyNumberList); + } + + /** + * Interface for outgoing emergency call listener. + * + * @hide + */ + @SystemApi + public interface OutgoingEmergencyCallListener { + /** + * Callback invoked when an outgoing call is placed to an emergency number. + * + * This method will be called when an emergency call is placed on any subscription + * (including the no-SIM case), regardless of which subscription this listener was + * registered on. + * + * The default implementation of this method calls + * {@link #onOutgoingEmergencyCall(EmergencyNumber)} for backwards compatibility purposes. + * Do not call {@code super(...)} from within your implementation unless you want + * {@link #onOutgoingEmergencyCall(EmergencyNumber)} to be called as well. + * + * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was + * placed to. + * @param subscriptionId The subscription ID used to place the emergency call. If the + * emergency call was placed without a valid subscription + * (e.g. when there are no SIM cards in the device), this will be + * equal to {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}. + */ + @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) + public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber, + int subscriptionId); + } + + /** + * Interface for outgoing emergency sms listener. + * + * @hide + */ + @SystemApi + public interface OutgoingEmergencySmsListener { + /** + * Smsback invoked when an outgoing sms is sent to an emergency number. + * + * This method will be called when an emergency sms is sent on any subscription, + * regardless of which subscription this listener was registered on. + * + * The default implementation of this method calls + * {@link #onOutgoingEmergencySms(EmergencyNumber)} for backwards compatibility purposes. Do + * not call {@code super(...)} from within your implementation unless you want + * {@link #onOutgoingEmergencySms(EmergencyNumber)} to be called as well. + * + * @param sentEmergencyNumber The {@link EmergencyNumber} the emergency sms was sent to. + * @param subscriptionId The subscription ID used to send the emergency sms. + */ + @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) + public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber, + int subscriptionId); + } + + /** + * Interface for phone capability listener. + * + */ + public interface PhoneCapabilityChangedListener { + /** + * Callback invoked when phone capability changes. + * Note, this callback triggers regardless of registered subscription. + * + * @param capability the new phone capability + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void onPhoneCapabilityChanged(@NonNull PhoneCapability capability); + } + + /** + * Interface for active data subscription ID listener. + */ + public interface ActiveDataSubscriptionIdChangedListener { + /** + * Callback invoked when active data subscription ID changes. + * Note, this callback triggers regardless of registered subscription. + * + * @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. + */ + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public void onActiveDataSubscriptionIdChanged(int subId); + } + + /** + * Interface for modem radio power state listener. + * + * @hide + */ + @SystemApi + public interface RadioPowerStateChangedListener { + /** + * Callback invoked when modem radio power state changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param state the modem radio power state + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void onRadioPowerStateChanged(@RadioPowerState int state); + } + + /** + * Interface for carrier network listener. + */ + public interface CarrierNetworkChangeListener { + /** + * 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.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean)} + * + * This is optional and is 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. + * + * 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 If the carrier network change is or shortly will be active, + * {@code true} indicate that showing alternative UI, {@code false} otherwise. + */ + public void onCarrierNetworkChange(boolean active); + } + + /** + * Interface for registration failures listener. + */ + public interface RegistrationFailedListener { + /** + * Report that Registration or a Location/Routing/Tracking Area update has failed. + * + *

Indicate whenever a registration procedure, including a location, routing, or tracking + * area update fails. This includes procedures that do not necessarily result in a change of + * the modem's registration status. If the modem's registration status changes, that is + * reflected in the onNetworkStateChanged() and subsequent + * get{Voice/Data}RegistrationState(). + * + *

Because registration failures are ephemeral, this callback is not sticky. + * Registrants will not receive the most recent past value when registering. + * + * @param cellIdentity the CellIdentity, which must include the globally unique identifier + * for the cell (for example, all components of the CGI or ECGI). + * @param chosenPlmn a 5 or 6 digit alphanumeric PLMN (MCC|MNC) among those broadcast by the + * cell that was chosen for the failed registration attempt. + * @param domain DOMAIN_CS, DOMAIN_PS or both in case of a combined procedure. + * @param causeCode the primary failure cause code of the procedure. + * For GSM/UMTS (MM), values are in TS 24.008 Sec 10.5.95 + * For GSM/UMTS (GMM), values are in TS 24.008 Sec 10.5.147 + * For LTE (EMM), cause codes are TS 24.301 Sec 9.9.3.9 + * For NR (5GMM), cause codes are TS 24.501 Sec 9.11.3.2 + * Integer.MAX_VALUE if this value is unused. + * @param additionalCauseCode the cause code of any secondary/combined procedure + * if appropriate. For UMTS, if a combined attach succeeds for + * PS only, then the GMM cause code shall be included as an + * additionalCauseCode. For LTE (ESM), cause codes are in + * TS 24.301 9.9.4.4. Integer.MAX_VALUE if this value is unused. + */ + @RequiresPermission(allOf = { + Manifest.permission.READ_PRECISE_PHONE_STATE, + Manifest.permission.ACCESS_FINE_LOCATION + }) + public void onRegistrationFailed(@NonNull CellIdentity cellIdentity, + @NonNull String chosenPlmn, @Domain int domain, + int causeCode, int additionalCauseCode); + } + + /** + * Interface for call attributes listener. + * + * @hide + */ + @SystemApi + public interface CallAttributesChangedListener { + /** + * Callback invoked when the call attributes changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param callAttributes the call attributes + */ + @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) + void onCallAttributesChanged(@NonNull CallAttributes callAttributes); + } + + /** + * Interface for barring information listener. + */ + public interface BarringInfoChangedListener { + /** + * Report updated barring information for the current camped/registered cell. + * + *

Barring info is provided for all services applicable to the current camped/registered + * cell, for the registered PLMN and current access class/access category. + * + * @param barringInfo for all services on the current cell. + * @see android.telephony.BarringInfo + */ + @RequiresPermission(allOf = { + Manifest.permission.READ_PRECISE_PHONE_STATE, + Manifest.permission.ACCESS_FINE_LOCATION + }) + public void onBarringInfoChanged(@NonNull BarringInfo barringInfo); + } + + /** + * Interface for current physical channel configuration listener. + * @hide + */ + @SystemApi + public interface PhysicalChannelConfigChangedListener { + /** + * Callback invoked when the current physical channel configuration has changed + * + * @param configs List of the current {@link PhysicalChannelConfig}s + */ + @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) + public void onPhysicalChannelConfigChanged(@NonNull List configs); + } + + /** + * Interface for data enabled listener. + * + * @hide + */ + @SystemApi + public interface DataEnabledChangedListener { + /** + * Callback invoked when the data enabled changes. + * + * @param enabled {@code true} if data is enabled, otherwise disabled. + * @param reason Reason for data enabled/disabled. + * See {@link TelephonyManager.DataEnabledReason}. + */ + @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) + public void onDataEnabledChanged(boolean enabled, + @DataEnabledReason int reason); } /** @@ -658,8 +1970,7 @@ public class PhoneStateListener { * 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()}. + * subId. Otherwise, this callback applies to all subIds. *

* Note: The state returned here may differ from that returned by * {@link TelephonyManager#getCallState()}. Receivers of this callback should be aware that @@ -698,6 +2009,7 @@ public class PhoneStateListener { * same as above, but with the network type. Both called. */ public void onDataConnectionStateChanged(int state, int networkType) { + // default implementation empty } /** @@ -745,6 +2057,7 @@ public class PhoneStateListener { * @param cellInfo is the list of currently visible cells. */ public void onCellInfoChanged(List cellInfo) { + // default implementation empty } /** @@ -758,7 +2071,7 @@ public class PhoneStateListener { * @param callState {@link PreciseCallState} * @hide */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) @SystemApi public void onPreciseCallStateChanged(@NonNull PreciseCallState callState) { // default implementation empty @@ -777,9 +2090,9 @@ public class PhoneStateListener { * @param preciseDisconnectCause {@link PreciseDisconnectCause}. * */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) - public void onCallDisconnectCauseChanged(@Annotation.DisconnectCauses int disconnectCause, - int preciseDisconnectCause) { + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public void onCallDisconnectCauseChanged(@DisconnectCauses int disconnectCause, + @PreciseDisconnectCauses int preciseDisconnectCause) { // default implementation empty } @@ -795,7 +2108,7 @@ public class PhoneStateListener { * @param imsReasonInfo {@link ImsReasonInfo} contains details on why IMS call failed. * */ - @RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo) { // default implementation empty } @@ -817,7 +2130,7 @@ public class PhoneStateListener { * * @param dataConnectionState {@link PreciseDataConnectionState} */ - @RequiresPermission((android.Manifest.permission.MODIFY_PHONE_STATE)) + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void onPreciseDataConnectionStateChanged( @NonNull PreciseDataConnectionState dataConnectionState) { // default implementation empty @@ -855,6 +2168,7 @@ public class PhoneStateListener { */ @SystemApi public void onSrvccStateChanged(@SrvccState int srvccState) { + // default implementation empty } @@ -873,6 +2187,7 @@ public class PhoneStateListener { */ @SystemApi public void onVoiceActivationStateChanged(@SimActivationState int state) { + // default implementation empty } /** @@ -889,6 +2204,7 @@ public class PhoneStateListener { * @hide */ public void onDataActivationStateChanged(@SimActivationState int state) { + // default implementation empty } /** @@ -916,7 +2232,7 @@ public class PhoneStateListener { * * @param telephonyDisplayInfo The display information. */ - @RequiresPermission((android.Manifest.permission.READ_PHONE_STATE)) + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo telephonyDisplayInfo) { // default implementation empty } @@ -1030,7 +2346,8 @@ public class PhoneStateListener { /** * 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)}. + * PhoneStateListener by + * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. * If this TelephonyManager object was created with * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the * subId. Otherwise, this callback applies to @@ -1052,7 +2369,7 @@ public class PhoneStateListener { * @param capability the new phone capability * @hide */ - public void onPhoneCapabilityChanged(PhoneCapability capability) { + public void onPhoneCapabilityChanged(@NonNull PhoneCapability capability) { // default implementation empty } @@ -1096,7 +2413,8 @@ public class PhoneStateListener { * subId. Otherwise, this callback applies to * {@link SubscriptionManager#getDefaultSubscriptionId()}. * - * @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE} + * Requires permission {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} + * * @param state the modem radio power state * @hide */ @@ -1453,18 +2771,16 @@ public class PhoneStateListener { Binder.withCleanCallingIdentity( () -> mExecutor.execute( () -> psl.onImsCallDisconnectCauseChanged(disconnectCause))); - } public void onRegistrationFailed(@NonNull CellIdentity cellIdentity, - @NonNull String chosenPlmn, int domain, - int causeCode, int additionalCauseCode) { + @NonNull String chosenPlmn, int domain, int causeCode, int additionalCauseCode) { PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); if (psl == null) return; Binder.withCleanCallingIdentity( () -> mExecutor.execute(() -> psl.onRegistrationFailed( - cellIdentity, chosenPlmn, domain, causeCode, additionalCauseCode))); + cellIdentity, chosenPlmn, domain, causeCode, additionalCauseCode))); // default implementation empty } @@ -1475,8 +2791,27 @@ public class PhoneStateListener { Binder.withCleanCallingIdentity( () -> mExecutor.execute(() -> psl.onBarringInfoChanged(barringInfo))); } - } + public void onPhysicalChannelConfigChanged(List configs) { + PhysicalChannelConfigChangedListener listener = + (PhysicalChannelConfigChangedListener) mPhoneStateListenerWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onPhysicalChannelConfigChanged( + configs))); + } + + public void onDataEnabledChanged(boolean enabled, @DataEnabledReason int reason) { + DataEnabledChangedListener listener = + (DataEnabledChangedListener) mPhoneStateListenerWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onDataEnabledChanged( + enabled, reason))); + } + } 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 index 3673ae7f7a379..a9548b0a42b44 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -15,6 +15,7 @@ */ package android.telephony; +import android.annotation.CallbackExecutor; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -24,6 +25,9 @@ import android.compat.annotation.EnabledAfter; import android.content.Context; import android.os.Binder; import android.os.Build; +import android.os.Handler; +import android.os.HandlerExecutor; +import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.Annotation.CallState; @@ -37,6 +41,7 @@ import android.telephony.Annotation.SimActivationState; import android.telephony.Annotation.SrvccState; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; +import android.util.ArraySet; import android.util.Log; import com.android.internal.telephony.IOnSubscriptionsChangedListener; @@ -45,6 +50,7 @@ import com.android.internal.telephony.ITelephonyRegistry; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.Executor; /** @@ -206,7 +212,7 @@ public class TelephonyRegistryManager { } /** - * To check the SDK version for {@link #listenForSubscriber}. + * To check the SDK version for {@link #listenWithEventList}. */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.P) @@ -218,23 +224,23 @@ public class TelephonyRegistryManager { * @param pkg Package name * @param featureId Feature ID * @param listener Listener providing callback - * @param events Events + * @param events List events * @param notifyNow Whether to notify instantly */ - public void listenForSubscriber(int subId, @NonNull String pkg, @NonNull String featureId, - @NonNull PhoneStateListener listener, int events, boolean notifyNow) { + public void listenWithEventList(int subId, @NonNull String pkg, @NonNull String featureId, + @NonNull PhoneStateListener listener, @NonNull int[] events, boolean notifyNow) { try { // subId from PhoneStateListener is deprecated Q on forward, use the subId from // TelephonyManager instance. Keep using subId from PhoneStateListener for pre-Q. if (Compatibility.isChangeEnabled(LISTEN_CODE_CHANGE)) { // Since mSubId in PhoneStateListener is deprecated from Q on forward, this is // the only place to set mSubId and its for "informational" only. - listener.mSubId = (events == PhoneStateListener.LISTEN_NONE) + listener.mSubId = (events.length == 0) ? SubscriptionManager.INVALID_SUBSCRIPTION_ID : subId; } else if (listener.mSubId != null) { subId = listener.mSubId; } - sRegistry.listenForSubscriber( + sRegistry.listenWithEventList( subId, pkg, featureId, listener.callback, events, notifyNow); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -765,4 +771,366 @@ public class TelephonyRegistryManager { } } + /** + * Notify {@link PhysicalChannelConfig} has changed for a specific subscription. + * + * @param subId the subId + * @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel. + */ + public void notifyPhysicalChannelConfigForSubscriber( + int subId, List configs) { + try { + sRegistry.notifyPhysicalChannelConfigForSubscriber(subId, configs); + } catch (RemoteException ex) { + // system server crash + } + } + + /** + * Notify that the data enabled has changed. + * + * @param enabled True if data is enabled, otherwise disabled. + * @param reason Reason for data enabled/disabled. See {@code REASON_*} in + * {@link TelephonyManager}. + */ + public void notifyDataEnabled(boolean enabled, @TelephonyManager.DataEnabledReason int reason) { + try { + sRegistry.notifyDataEnabled(enabled, reason); + } catch (RemoteException ex) { + // system server crash + } + } + + public @NonNull Set getEventsFromListener(@NonNull PhoneStateListener listener) { + + Set eventList = new ArraySet<>(); + + if (listener instanceof PhoneStateListener.ServiceStateChangedListener) { + eventList.add(PhoneStateListener.EVENT_SERVICE_STATE_CHANGED); + } + + if (listener instanceof PhoneStateListener.MessageWaitingIndicatorChangedListener) { + eventList.add(PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED); + } + + if (listener instanceof PhoneStateListener.CallForwardingIndicatorChangedListener) { + eventList.add(PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED); + } + + if (listener instanceof PhoneStateListener.CellLocationChangedListener) { + eventList.add(PhoneStateListener.EVENT_CELL_LOCATION_CHANGED); + } + + if (listener instanceof PhoneStateListener.CallStateChangedListener) { + eventList.add(PhoneStateListener.EVENT_CALL_STATE_CHANGED); + } + + if (listener instanceof PhoneStateListener.DataConnectionStateChangedListener) { + eventList.add(PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED); + } + + if (listener instanceof PhoneStateListener.DataActivityListener) { + eventList.add(PhoneStateListener.EVENT_DATA_ACTIVITY_CHANGED); + } + + if (listener instanceof PhoneStateListener.SignalStrengthsChangedListener) { + eventList.add(PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED); + } + + if (listener instanceof PhoneStateListener.AlwaysReportedSignalStrengthChangedListener) { + eventList.add(PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED); + } + + if (listener instanceof PhoneStateListener.CellInfoChangedListener) { + eventList.add(PhoneStateListener.EVENT_CELL_INFO_CHANGED); + } + + if (listener instanceof PhoneStateListener.PreciseCallStateChangedListener) { + eventList.add(PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED); + } + + if (listener instanceof PhoneStateListener.CallDisconnectCauseChangedListener) { + eventList.add(PhoneStateListener.EVENT_CALL_DISCONNECT_CAUSE_CHANGED); + } + + if (listener instanceof PhoneStateListener.ImsCallDisconnectCauseChangedListener) { + eventList.add(PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED); + } + + if (listener instanceof PhoneStateListener.PreciseDataConnectionStateChangedListener) { + eventList.add(PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED); + } + + if (listener instanceof PhoneStateListener.SrvccStateChangedListener) { + eventList.add(PhoneStateListener.EVENT_SRVCC_STATE_CHANGED); + } + + if (listener instanceof PhoneStateListener.VoiceActivationStateChangedListener) { + eventList.add(PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED); + } + + if (listener instanceof PhoneStateListener.DataActivationStateChangedListener) { + eventList.add(PhoneStateListener.EVENT_DATA_ACTIVATION_STATE_CHANGED); + } + + if (listener instanceof PhoneStateListener.UserMobileDataStateChangedListener) { + eventList.add(PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED); + } + + if (listener instanceof PhoneStateListener.DisplayInfoChangedListener) { + eventList.add(PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED); + } + + if (listener instanceof PhoneStateListener.EmergencyNumberListChangedListener) { + eventList.add(PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED); + } + + if (listener instanceof PhoneStateListener.OutgoingEmergencyCallListener) { + eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_CALL); + } + + if (listener instanceof PhoneStateListener.OutgoingEmergencySmsListener) { + eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_SMS); + } + + if (listener instanceof PhoneStateListener.PhoneCapabilityChangedListener) { + eventList.add(PhoneStateListener.EVENT_PHONE_CAPABILITY_CHANGED); + } + + if (listener instanceof PhoneStateListener.ActiveDataSubscriptionIdChangedListener) { + eventList.add(PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED); + } + + if (listener instanceof PhoneStateListener.RadioPowerStateChangedListener) { + eventList.add(PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED); + } + + if (listener instanceof PhoneStateListener.CarrierNetworkChangeListener) { + eventList.add(PhoneStateListener.EVENT_CARRIER_NETWORK_CHANGED); + } + + if (listener instanceof PhoneStateListener.RegistrationFailedListener) { + eventList.add(PhoneStateListener.EVENT_REGISTRATION_FAILURE); + } + + if (listener instanceof PhoneStateListener.CallAttributesChangedListener) { + eventList.add(PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED); + } + + if (listener instanceof PhoneStateListener.BarringInfoChangedListener) { + eventList.add(PhoneStateListener.EVENT_BARRING_INFO_CHANGED); + } + + if (listener instanceof PhoneStateListener.PhysicalChannelConfigChangedListener) { + eventList.add(PhoneStateListener.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED); + } + + if (listener instanceof PhoneStateListener.DataEnabledChangedListener) { + eventList.add(PhoneStateListener.EVENT_DATA_ENABLED_CHANGED); + } + + return eventList; + } + + private @NonNull Set getEventsFromBitmask(int eventMask) { + + Set eventList = new ArraySet<>(); + + if ((eventMask & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { + eventList.add(PhoneStateListener.EVENT_SERVICE_STATE_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { + eventList.add(PhoneStateListener.EVENT_SIGNAL_STRENGTH_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { + eventList.add(PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { + eventList.add(PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { + eventList.add(PhoneStateListener.EVENT_CELL_LOCATION_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_CALL_STATE) != 0) { + eventList.add(PhoneStateListener.EVENT_CALL_STATE_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { + eventList.add(PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) { + eventList.add(PhoneStateListener.EVENT_DATA_ACTIVITY_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { + eventList.add(PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) != 0) { + eventList.add(PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_CELL_INFO) != 0) { + eventList.add(PhoneStateListener.EVENT_CELL_INFO_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) { + eventList.add(PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) { + eventList.add(PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO) != 0) { + eventList.add(PhoneStateListener.EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) { + eventList.add(PhoneStateListener.EVENT_OEM_HOOK_RAW); + } + + if ((eventMask & PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) != 0) { + eventList.add(PhoneStateListener.EVENT_SRVCC_STATE_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE) != 0) { + eventList.add(PhoneStateListener.EVENT_CARRIER_NETWORK_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) != 0) { + eventList.add(PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE) != 0) { + eventList.add(PhoneStateListener.EVENT_DATA_ACTIVATION_STATE_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE) != 0) { + eventList.add(PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED) != 0) { + eventList.add(PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE) != 0) { + eventList.add(PhoneStateListener.EVENT_PHONE_CAPABILITY_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE) != 0) { + eventList.add(PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED) != 0) { + eventList.add(PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST) != 0) { + eventList.add(PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES) != 0) { + eventList.add(PhoneStateListener.EVENT_CALL_DISCONNECT_CAUSE_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED) != 0) { + eventList.add(PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES) != 0) { + eventList.add(PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED); + } + + if ((eventMask & PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL) != 0) { + eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_CALL); + } + + if ((eventMask & PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS) != 0) { + eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_SMS); + } + + if ((eventMask & PhoneStateListener.LISTEN_REGISTRATION_FAILURE) != 0) { + eventList.add(PhoneStateListener.EVENT_REGISTRATION_FAILURE); + } + + if ((eventMask & PhoneStateListener.LISTEN_BARRING_INFO) != 0) { + eventList.add(PhoneStateListener.EVENT_BARRING_INFO_CHANGED); + } + return eventList; + + } + + /** + * Registers a listener object to receive notification of changes + * in specified telephony states. + *

+ * To register a listener, pass a {@link PhoneStateListener} which implements + * interfaces of events. For example, + * FakeServiceStateChangedListener extends {@link PhoneStateListener} implements + * {@link PhoneStateListener.ServiceStateChangedListener}. + * + * At registration, and when a specified telephony state changes, the telephony manager invokes + * the appropriate callback method on the listener object and passes the current (updated) + * values. + *

+ * + * If this TelephonyManager object has been created with + * {@link TelephonyManager#createForSubscriptionId}, applies to the given subId. + * Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}. + * To listen events for multiple subIds, pass a separate listener object to + * each TelephonyManager object created with {@link TelephonyManager#createForSubscriptionId}. + * + * Note: if you call this method while in the middle of a binder transaction, you must + * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A + * {@link SecurityException} will be thrown otherwise. + * + * This API should be used sparingly -- large numbers of listeners will cause system + * instability. If a process has registered too many listeners without unregistering them, it + * may encounter an {@link IllegalStateException} when trying to register more listeners. + * + * @param listener The {@link PhoneStateListener} object to register. + */ + public void registerPhoneStateListener(@NonNull @CallbackExecutor Executor executor, int subId, + String pkgName, String attributionTag, @NonNull PhoneStateListener listener, + boolean notifyNow) { + listener.setExecutor(executor); + registerPhoneStateListener(subId, pkgName, attributionTag, listener, + getEventsFromListener(listener), notifyNow); + } + + public void registerPhoneStateListenerWithEvents(int subId, String pkgName, + String attributionTag, @NonNull PhoneStateListener listener, int events, + boolean notifyNow) { + registerPhoneStateListener( + subId, pkgName, attributionTag, listener, getEventsFromBitmask(events), notifyNow); + } + + private void registerPhoneStateListener(int subId, + String pkgName, String attributionTag, @NonNull PhoneStateListener listener, + @NonNull Set events, boolean notifyNow) { + if (listener == null) { + throw new IllegalStateException("telephony service is null."); + } + + listenWithEventList(subId, pkgName, attributionTag, listener, + events.stream().mapToInt(i -> i).toArray(), notifyNow); + } + + /** + * Unregister an existing {@link PhoneStateListener}. + * + * @param listener The {@link PhoneStateListener} object to unregister. + */ + public void unregisterPhoneStateListener(int subId, String pkgName, String attributionTag, + @NonNull PhoneStateListener listener, + boolean notifyNow) { + listenWithEventList(subId, pkgName, attributionTag, listener, new int[0], notifyNow); + } } diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl index d2dc7c283ff7a..854fb17e692b2 100644 --- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -23,6 +23,7 @@ import android.telephony.CellInfo; import android.telephony.DataConnectionRealTimeInfo; import android.telephony.TelephonyDisplayInfo; import android.telephony.PhoneCapability; +import android.telephony.PhysicalChannelConfig; import android.telephony.PreciseCallState; import android.telephony.PreciseDataConnectionState; import android.telephony.ServiceState; @@ -68,4 +69,6 @@ oneway interface IPhoneStateListener { void onRegistrationFailed(in CellIdentity cellIdentity, String chosenPlmn, int domain, int causeCode, int additionalCauseCode); void onBarringInfoChanged(in BarringInfo barringInfo); + void onPhysicalChannelConfigChanged(in List configs); + void onDataEnabledChanged(boolean enabled, int reason); } diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 5f2dcc3d22e18..2a73dacbc94a8 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -41,16 +41,8 @@ interface ITelephonyRegistry { IOnSubscriptionsChangedListener callback); void removeOnSubscriptionsChangedListener(String pkg, IOnSubscriptionsChangedListener callback); - /** - * @deprecated Use {@link #listenWithFeature(String, String, IPhoneStateListener, int, - * boolean) instead - */ - @UnsupportedAppUsage - void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow); - void listenWithFeature(String pkg, String featureId, IPhoneStateListener callback, int events, - boolean notifyNow); - void listenForSubscriber(in int subId, String pkg, String featureId, - IPhoneStateListener callback, int events, boolean notifyNow); + void listenWithEventList(in int subId, String pkg, String featureId, + IPhoneStateListener callback, in int[] events, boolean notifyNow); @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) void notifyCallStateForAllSubs(int state, String incomingNumber); void notifyCallState(in int phoneId, in int subId, int state, String incomingNumber); @@ -99,4 +91,7 @@ interface ITelephonyRegistry { void notifyRegistrationFailed(int slotIndex, int subId, in CellIdentity cellIdentity, String chosenPlmn, int domain, int causeCode, int additionalCauseCode); void notifyBarringInfoChanged(int slotIndex, int subId, in BarringInfo barringInfo); + void notifyPhysicalChannelConfigForSubscriber(in int subId, + in List configs); + void notifyDataEnabled(boolean enabled, int reason); } diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 5f6e8df30f8d8..5560f8137e4c1 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -64,6 +64,7 @@ import android.telephony.DisconnectCause; import android.telephony.LocationAccessPolicy; import android.telephony.PhoneCapability; import android.telephony.PhoneStateListener; +import android.telephony.PhysicalChannelConfig; import android.telephony.PreciseCallState; import android.telephony.PreciseDataConnectionState; import android.telephony.PreciseDisconnectCause; @@ -78,6 +79,7 @@ import android.telephony.data.ApnSetting; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; import android.util.ArrayMap; +import android.util.ArraySet; import android.util.LocalLog; import android.util.Pair; @@ -99,10 +101,13 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; /** * Since phone process can be restarted, this class provides a centralized place @@ -142,14 +147,14 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { int callerUid; int callerPid; - int events; + Set eventList; int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; int phoneId = SubscriptionManager.INVALID_SIM_SLOT_INDEX; - boolean matchPhoneStateListenerEvent(int events) { - return (callback != null) && ((events & this.events) != 0); + boolean matchPhoneStateListenerEvent(int event) { + return (callback != null) && (this.eventList.contains(event)); } boolean matchOnSubscriptionsChangedListener() { @@ -177,7 +182,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { + onSubscriptionsChangedListenerCallback + " onOpportunisticSubscriptionsChangedListenererCallback=" + onOpportunisticSubscriptionsChangedListenerCallback + " subId=" + subId - + " phoneId=" + phoneId + " events=" + Integer.toHexString(events) + "}"; + + " phoneId=" + phoneId + " events=" + eventList + "}"; } } @@ -306,6 +311,12 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private final LocalLog mListenLog = new LocalLog(200); + private List mPhysicalChannelConfigs; + + private boolean mIsDataEnabled = false; + + private int mDataEnabledReason; + /** * Per-phone map of precise data connection state. The key of the map is the pair of transport * type and APN setting. This is the cache to prevent redundant callbacks to the listeners. @@ -315,39 +326,62 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private List, PreciseDataConnectionState>> mPreciseDataConnectionStates; - // Starting in Q, almost all cellular location requires FINE location enforcement. - // Prior to Q, cellular was available with COARSE location enforcement. Bits in this - // list will be checked for COARSE on apps targeting P or earlier and FINE on Q or later. - static final int ENFORCE_LOCATION_PERMISSION_MASK = - PhoneStateListener.LISTEN_CELL_LOCATION - | PhoneStateListener.LISTEN_CELL_INFO - | PhoneStateListener.LISTEN_REGISTRATION_FAILURE - | PhoneStateListener.LISTEN_BARRING_INFO; + private static final Set REQUIRE_PRECISE_PHONE_STATE_PERMISSION; + static { + REQUIRE_PRECISE_PHONE_STATE_PERMISSION = new HashSet(); + REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( + PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED); + REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( + PhoneStateListener.EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED); + REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( + PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED); + REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( + PhoneStateListener.EVENT_CALL_DISCONNECT_CAUSE_CHANGED); + REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( + PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED); + REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( + PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED); + REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(PhoneStateListener.EVENT_REGISTRATION_FAILURE); + REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add(PhoneStateListener.EVENT_BARRING_INFO_CHANGED); + REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( + PhoneStateListener.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED); + REQUIRE_PRECISE_PHONE_STATE_PERMISSION.add( + PhoneStateListener.EVENT_DATA_ENABLED_CHANGED); + } - static final int ENFORCE_PHONE_STATE_PERMISSION_MASK = - PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR - | PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR - | PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST - | PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED; + private boolean isLocationPermissionRequired(Set events) { + return events.contains(PhoneStateListener.EVENT_CELL_LOCATION_CHANGED) + || events.contains(PhoneStateListener.EVENT_CELL_INFO_CHANGED) + || events.contains(PhoneStateListener.EVENT_REGISTRATION_FAILURE) + || events.contains(PhoneStateListener.EVENT_BARRING_INFO_CHANGED); + } - static final int ENFORCE_PRECISE_PHONE_STATE_PERMISSION_MASK = - PhoneStateListener.LISTEN_PRECISE_CALL_STATE - | PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE - | PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES - | PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED - | PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES - | PhoneStateListener.LISTEN_REGISTRATION_FAILURE - | PhoneStateListener.LISTEN_BARRING_INFO; + private boolean isPhoneStatePermissionRequired(Set events) { + return events.contains(PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED) + || events.contains(PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED) + || events.contains(PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED) + || events.contains(PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED); + } - static final int READ_ACTIVE_EMERGENCY_SESSION_PERMISSION_MASK = - PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL - | PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS; + private boolean isPrecisePhoneStatePermissionRequired(Set events) { + for (Integer requireEvent : REQUIRE_PRECISE_PHONE_STATE_PERMISSION) { + if (events.contains(requireEvent)) { + return true; + } + } + return false; + } - static final int READ_PRIVILEGED_PHONE_STATE_PERMISSION_MASK = - PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT - | PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED - | PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED - | PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE; + private boolean isActiveEmergencySessionPermissionRequired(Set events) { + return events.contains(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_CALL) + || events.contains(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_SMS); + } + + private boolean isPrivilegedPhoneStatePermissionRequired(Set events) { + return events.contains(PhoneStateListener.EVENT_SRVCC_STATE_CHANGED) + || events.contains(PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED) + || events.contains(PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED); + } private static final int MSG_USER_SWITCHED = 1; private static final int MSG_UPDATE_DEFAULT_SUB = 2; @@ -495,6 +529,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { cutListToSize(mImsReasonInfo, mNumPhones); cutListToSize(mPreciseDataConnectionStates, mNumPhones); cutListToSize(mBarringInfo, mNumPhones); + cutListToSize(mPhysicalChannelConfigs, mNumPhones); return; } @@ -528,6 +563,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mPreciseDataConnectionStates.add(new ArrayMap<>()); mBarringInfo.add(i, new BarringInfo()); mTelephonyDisplayInfos[i] = null; + mPhysicalChannelConfigs.add(i, new PhysicalChannelConfig.Builder().build()); } } @@ -588,6 +624,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mOutgoingSmsEmergencyNumber = new EmergencyNumber[numPhones]; mBarringInfo = new ArrayList<>(); mTelephonyDisplayInfos = new TelephonyDisplayInfo[numPhones]; + mPhysicalChannelConfigs = new ArrayList<>(); for (int i = 0; i < numPhones; i++) { mCallState[i] = TelephonyManager.CALL_STATE_IDLE; mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE; @@ -617,6 +654,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mPreciseDataConnectionStates.add(new ArrayMap<>()); mBarringInfo.add(i, new BarringInfo()); mTelephonyDisplayInfos[i] = null; + mPhysicalChannelConfigs.add(i, new PhysicalChannelConfig.Builder().build()); } mAppOps = mContext.getSystemService(AppOpsManager.class); @@ -659,7 +697,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { r.callingFeatureId = callingFeatureId; r.callerUid = Binder.getCallingUid(); r.callerPid = Binder.getCallingPid(); - r.events = 0; + r.eventList = new ArraySet<>(); if (DBG) { log("listen oscl: Register r=" + r); } @@ -713,7 +751,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { r.callingFeatureId = callingFeatureId; r.callerUid = Binder.getCallingUid(); r.callerPid = Binder.getCallingPid(); - r.events = 0; + r.eventList = new ArraySet<>(); if (DBG) { log("listen ooscl: Register r=" + r); } @@ -786,323 +824,337 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - @Deprecated @Override - public void listen(String callingPackage, IPhoneStateListener callback, int events, - boolean notifyNow) { - listenWithFeature(callingPackage, null, callback, events, notifyNow); - } - - @Override - public void listenWithFeature(String callingPackage, String callingFeatureId, - IPhoneStateListener callback, int events, boolean notifyNow) { - listenForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, callingPackage, - callingFeatureId, callback, events, notifyNow); - } - - @Override - public void listenForSubscriber(int subId, String callingPackage, String callingFeatureId, - IPhoneStateListener callback, int events, boolean notifyNow) { - listen(callingPackage, callingFeatureId, callback, events, notifyNow, subId); + public void listenWithEventList(int subId, String callingPackage, String callingFeatureId, + IPhoneStateListener callback, int[] events, boolean notifyNow) { + Set eventList = Arrays.stream(events).boxed().collect(Collectors.toSet()); + listen(callingPackage, callingFeatureId, callback, eventList, notifyNow, subId); } private void listen(String callingPackage, @Nullable String callingFeatureId, - IPhoneStateListener callback, int events, boolean notifyNow, int subId) { + IPhoneStateListener callback, Set events, boolean notifyNow, int subId) { int callerUserId = UserHandle.getCallingUserId(); mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); String str = "listen: E pkg=" + pii(callingPackage) + " uid=" + Binder.getCallingUid() - + " events=0x" + Integer.toHexString(events) + " notifyNow=" + notifyNow + " subId=" - + subId + " myUserId=" + UserHandle.myUserId() + " callerUserId=" + callerUserId; + + " events=" + events + " notifyNow=" + notifyNow + + " subId=" + subId + " myUserId=" + UserHandle.myUserId() + + " callerUserId=" + callerUserId; mListenLog.log(str); if (VDBG) { log(str); } - if (events != PhoneStateListener.LISTEN_NONE) { - // Checks permission and throws SecurityException for disallowed operations. For pre-M - // apps whose runtime permission has been revoked, we return immediately to skip sending - // events to the app without crashing it. - if (!checkListenerPermission(events, subId, callingPackage, callingFeatureId, - "listen")) { + if (events.isEmpty()) { + if (DBG) { + log("listen: Unregister"); + } + events.clear(); + remove(callback.asBinder()); + return; + } + + // Checks permission and throws SecurityException for disallowed operations. For pre-M + // apps whose runtime permission has been revoked, we return immediately to skip sending + // events to the app without crashing it. + if (!checkListenerPermission(events, subId, callingPackage, callingFeatureId, + "listen")) { + return; + } + + int phoneId = getPhoneIdFromSubId(subId); + synchronized (mRecords) { + // register + IBinder b = callback.asBinder(); + boolean doesLimitApply = + Binder.getCallingUid() != Process.SYSTEM_UID + && Binder.getCallingUid() != Process.PHONE_UID + && Binder.getCallingUid() != Process.myUid(); + Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply); + + if (r == null) { return; } - int phoneId = getPhoneIdFromSubId(subId); - synchronized (mRecords) { - // register - IBinder b = callback.asBinder(); - boolean doesLimitApply = - Binder.getCallingUid() != Process.SYSTEM_UID - && Binder.getCallingUid() != Process.PHONE_UID - && Binder.getCallingUid() != Process.myUid(); - Record r = add(b, Binder.getCallingUid(), Binder.getCallingPid(), doesLimitApply); - - if (r == null) { - return; + r.context = mContext; + r.callback = callback; + r.callingPackage = callingPackage; + r.callingFeatureId = callingFeatureId; + r.callerUid = Binder.getCallingUid(); + r.callerPid = Binder.getCallingPid(); + // Legacy applications pass SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, + // force all illegal subId to SubscriptionManager.DEFAULT_SUBSCRIPTION_ID + if (!SubscriptionManager.isValidSubscriptionId(subId)) { + r.subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; + } else {//APP specify subID + r.subId = subId; + } + r.phoneId = phoneId; + r.eventList = events; + if (DBG) { + log("listen: Register r=" + r + " r.subId=" + r.subId + " phoneId=" + phoneId); + } + if (notifyNow && validatePhoneId(phoneId)) { + if (events.contains(PhoneStateListener.EVENT_SERVICE_STATE_CHANGED)) { + try { + if (VDBG) log("listen: call onSSC state=" + mServiceState[phoneId]); + ServiceState rawSs = new ServiceState(mServiceState[phoneId]); + if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { + r.callback.onServiceStateChanged(rawSs); + } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) { + r.callback.onServiceStateChanged( + rawSs.createLocationInfoSanitizedCopy(false)); + } else { + r.callback.onServiceStateChanged( + rawSs.createLocationInfoSanitizedCopy(true)); + } + } catch (RemoteException ex) { + remove(r.binder); + } } - - r.context = mContext; - r.callback = callback; - r.callingPackage = callingPackage; - r.callingFeatureId = callingFeatureId; - r.callerUid = Binder.getCallingUid(); - r.callerPid = Binder.getCallingPid(); - // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID, - // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID - if (!SubscriptionManager.isValidSubscriptionId(subId)) { - r.subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; - } else {//APP specify subID - r.subId = subId; + if (events.contains(PhoneStateListener.EVENT_SIGNAL_STRENGTH_CHANGED)) { + try { + if (mSignalStrength[phoneId] != null) { + int gsmSignalStrength = mSignalStrength[phoneId] + .getGsmSignalStrength(); + r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 + : gsmSignalStrength)); + } + } catch (RemoteException ex) { + remove(r.binder); + } } - r.phoneId = phoneId; - r.events = events; - if (DBG) { - log("listen: Register r=" + r + " r.subId=" + r.subId + " phoneId=" + phoneId); + if (events.contains( + PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)) { + try { + r.callback.onMessageWaitingIndicatorChanged( + mMessageWaiting[phoneId]); + } catch (RemoteException ex) { + remove(r.binder); + } } - if (notifyNow && validatePhoneId(phoneId)) { - if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { - try { - if (VDBG) log("listen: call onSSC state=" + mServiceState[phoneId]); - ServiceState rawSs = new ServiceState(mServiceState[phoneId]); - if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { - r.callback.onServiceStateChanged(rawSs); - } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) { - r.callback.onServiceStateChanged( - rawSs.createLocationInfoSanitizedCopy(false)); - } else { - r.callback.onServiceStateChanged( - rawSs.createLocationInfoSanitizedCopy(true)); - } - } catch (RemoteException ex) { - remove(r.binder); - } + if (events.contains( + PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)) { + try { + r.callback.onCallForwardingIndicatorChanged( + mCallForwarding[phoneId]); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { - try { - if (mSignalStrength[phoneId] != null) { - int gsmSignalStrength = mSignalStrength[phoneId] - .getGsmSignalStrength(); - r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1 - : gsmSignalStrength)); - } - } catch (RemoteException ex) { - remove(r.binder); + } + if (validateEventAndUserLocked( + r, PhoneStateListener.EVENT_CELL_LOCATION_CHANGED)) { + try { + if (DBG_LOC) log("listen: mCellIdentity = " + mCellIdentity[phoneId]); + if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE) + && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { + // null will be translated to empty CellLocation object in client. + r.callback.onCellLocationChanged(mCellIdentity[phoneId]); } + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { - try { - r.callback.onMessageWaitingIndicatorChanged( - mMessageWaiting[phoneId]); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains(PhoneStateListener.EVENT_CALL_STATE_CHANGED)) { + try { + r.callback.onCallStateChanged(mCallState[phoneId], + getCallIncomingNumber(r, phoneId)); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { - try { - r.callback.onCallForwardingIndicatorChanged( - mCallForwarding[phoneId]); - } catch (RemoteException ex) { - remove(r.binder); - } - } - if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { - try { - if (DBG_LOC) log("listen: mCellIdentity = " + mCellIdentity[phoneId]); - if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE) - && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { - // null will be translated to empty CellLocation object in client. - r.callback.onCellLocationChanged(mCellIdentity[phoneId]); - } - } catch (RemoteException ex) { - remove(r.binder); - } - } - if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) { - try { - r.callback.onCallStateChanged(mCallState[phoneId], - getCallIncomingNumber(r, phoneId)); - } catch (RemoteException ex) { - remove(r.binder); - } - } - if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { - try { - r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], + } + if (events.contains(PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED)) { + try { + r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId], mDataConnectionNetworkType[phoneId]); - } catch (RemoteException ex) { - remove(r.binder); - } + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) { - try { - r.callback.onDataActivity(mDataActivity[phoneId]); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains(PhoneStateListener.EVENT_DATA_ACTIVITY_CHANGED)) { + try { + r.callback.onDataActivity(mDataActivity[phoneId]); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { - try { - if (mSignalStrength[phoneId] != null) { - r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]); - } - } catch (RemoteException ex) { - remove(r.binder); + } + if (events.contains(PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED)) { + try { + if (mSignalStrength[phoneId] != null) { + r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]); } + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) - != 0) { - updateReportSignalStrengthDecision(r.subId); - try { - if (mSignalStrength[phoneId] != null) { - r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]); - } - } catch (RemoteException ex) { - remove(r.binder); + } + if (events.contains( + PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) { + updateReportSignalStrengthDecision(r.subId); + try { + if (mSignalStrength[phoneId] != null) { + r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]); } + } catch (RemoteException ex) { + remove(r.binder); } - if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) { - try { - if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = " - + mCellInfo.get(phoneId)); - if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE) - && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { - r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); - } - } catch (RemoteException ex) { - remove(r.binder); + } + if (validateEventAndUserLocked( + r, PhoneStateListener.EVENT_CELL_INFO_CHANGED)) { + try { + if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = " + + mCellInfo.get(phoneId)); + if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE) + && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) { + r.callback.onCellInfoChanged(mCellInfo.get(phoneId)); } + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) { - try { - r.callback.onPreciseCallStateChanged(mPreciseCallState[phoneId]); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains(PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED)) { + try { + r.callback.onPreciseCallStateChanged(mPreciseCallState[phoneId]); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES) != 0) { - try { - r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause[phoneId], - mCallPreciseDisconnectCause[phoneId]); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains(PhoneStateListener.EVENT_CALL_DISCONNECT_CAUSE_CHANGED)) { + try { + r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause[phoneId], + mCallPreciseDisconnectCause[phoneId]); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES) != 0) { - try { - r.callback.onImsCallDisconnectCauseChanged(mImsReasonInfo.get(phoneId)); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains(PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED)) { + try { + r.callback.onImsCallDisconnectCauseChanged(mImsReasonInfo.get(phoneId)); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) { - try { - for (PreciseDataConnectionState pdcs - : mPreciseDataConnectionStates.get(phoneId).values()) { - r.callback.onPreciseDataConnectionStateChanged(pdcs); - } - } catch (RemoteException ex) { - remove(r.binder); + } + if (events.contains( + PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED)) { + try { + for (PreciseDataConnectionState pdcs + : mPreciseDataConnectionStates.get(phoneId).values()) { + r.callback.onPreciseDataConnectionStateChanged(pdcs); } + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE) != 0) { - try { - r.callback.onCarrierNetworkChange(mCarrierNetworkChangeState); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains(PhoneStateListener.EVENT_CARRIER_NETWORK_CHANGED)) { + try { + r.callback.onCarrierNetworkChange(mCarrierNetworkChangeState); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) !=0) { - try { - r.callback.onVoiceActivationStateChanged( - mVoiceActivationState[phoneId]); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains(PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED)) { + try { + r.callback.onVoiceActivationStateChanged( + mVoiceActivationState[phoneId]); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE) !=0) { - try { - r.callback.onDataActivationStateChanged(mDataActivationState[phoneId]); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains(PhoneStateListener.EVENT_DATA_ACTIVATION_STATE_CHANGED)) { + try { + r.callback.onDataActivationStateChanged(mDataActivationState[phoneId]); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE) != 0) { - try { - r.callback.onUserMobileDataStateChanged(mUserMobileDataState[phoneId]); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains(PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED)) { + try { + r.callback.onUserMobileDataStateChanged(mUserMobileDataState[phoneId]); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED) != 0) { - try { - if (mTelephonyDisplayInfos[phoneId] != null) { - r.callback.onDisplayInfoChanged(mTelephonyDisplayInfos[phoneId]); - } - } catch (RemoteException ex) { - remove(r.binder); + } + if (events.contains(PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED)) { + try { + if (mTelephonyDisplayInfos[phoneId] != null) { + r.callback.onDisplayInfoChanged(mTelephonyDisplayInfos[phoneId]); } + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST) != 0) { - try { - r.callback.onEmergencyNumberListChanged(mEmergencyNumberList); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains(PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)) { + try { + r.callback.onEmergencyNumberListChanged(mEmergencyNumberList); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE) != 0) { - try { - r.callback.onPhoneCapabilityChanged(mPhoneCapability); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains(PhoneStateListener.EVENT_PHONE_CAPABILITY_CHANGED)) { + try { + r.callback.onPhoneCapabilityChanged(mPhoneCapability); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener - .LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE) != 0) { - try { - r.callback.onActiveDataSubIdChanged(mActiveDataSubId); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains( + PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED)) { + try { + r.callback.onActiveDataSubIdChanged(mActiveDataSubId); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED) != 0) { - try { - r.callback.onRadioPowerStateChanged(mRadioPowerState); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains(PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED)) { + try { + r.callback.onRadioPowerStateChanged(mRadioPowerState); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) != 0) { - try { - r.callback.onSrvccStateChanged(mSrvccState[phoneId]); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains(PhoneStateListener.EVENT_SRVCC_STATE_CHANGED)) { + try { + r.callback.onSrvccStateChanged(mSrvccState[phoneId]); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED) != 0) { - try { - r.callback.onCallAttributesChanged(mCallAttributes[phoneId]); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains(PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED)) { + try { + r.callback.onCallAttributesChanged(mCallAttributes[phoneId]); + } catch (RemoteException ex) { + remove(r.binder); } - if ((events & PhoneStateListener.LISTEN_BARRING_INFO) != 0) { - BarringInfo barringInfo = mBarringInfo.get(phoneId); - BarringInfo biNoLocation = barringInfo != null - ? barringInfo.createLocationInfoSanitizedCopy() : null; - if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo); - try { - r.callback.onBarringInfoChanged( - checkFineLocationAccess(r, Build.VERSION_CODES.BASE) - ? barringInfo : biNoLocation); - } catch (RemoteException ex) { - remove(r.binder); - } + } + if (events.contains(PhoneStateListener.EVENT_BARRING_INFO_CHANGED)) { + BarringInfo barringInfo = mBarringInfo.get(phoneId); + BarringInfo biNoLocation = barringInfo != null + ? barringInfo.createLocationInfoSanitizedCopy() : null; + if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo); + try { + r.callback.onBarringInfoChanged( + checkFineLocationAccess(r, Build.VERSION_CODES.BASE) + ? barringInfo : biNoLocation); + } catch (RemoteException ex) { + remove(r.binder); + } + } + if (events.contains( + PhoneStateListener.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED)) { + try { + r.callback.onPhysicalChannelConfigChanged( + mPhysicalChannelConfigs); + } catch (RemoteException ex) { + remove(r.binder); + } + } + if (events.contains( + PhoneStateListener.EVENT_DATA_ENABLED_CHANGED)) { + try { + r.callback.onDataEnabledChanged(mIsDataEnabled, mDataEnabledReason); + } catch (RemoteException ex) { + remove(r.binder); } } } - } else { - if(DBG) log("listen: Unregister"); - remove(callback.asBinder()); } } @@ -1114,7 +1166,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { // If any of the system clients wants to always listen to signal strength, // we need to set it on. if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)) { + PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) { telephonyManager.createForSubscriptionId(subscriptionId) .setAlwaysReportSignalStrength(true); return; @@ -1215,7 +1267,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { // strength is removed from registry records, we need to check if // the signal strength decision needs to update on its slot. if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)) { + PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) { updateReportSignalStrengthDecision(r.subId); } return; @@ -1235,8 +1287,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { synchronized (mRecords) { for (Record r : mRecords) { - if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) && - (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { + if (r.matchPhoneStateListenerEvent(PhoneStateListener.EVENT_CALL_STATE_CHANGED) + && (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { try { // Ensure the listener has read call log permission; if they do not return // an empty phone number. @@ -1270,9 +1322,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCallState[phoneId] = state; mCallIncomingNumber[phoneId] = incomingNumber; for (Record r : mRecords) { - if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_CALL_STATE) && - (r.subId == subId) && - (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { + if (r.matchPhoneStateListenerEvent(PhoneStateListener.EVENT_CALL_STATE_CHANGED) + && (r.subId == subId) + && (r.subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) { try { String incomingNumberOrEmpty = getCallIncomingNumber(r, phoneId); r.callback.onCallStateChanged(state, incomingNumberOrEmpty); @@ -1312,8 +1364,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { log("notifyServiceStateForSubscriber: r=" + r + " subId=" + subId + " phoneId=" + phoneId + " state=" + state); } - if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SERVICE_STATE) && - idMatch(r.subId, subId, phoneId)) { + if (r.matchPhoneStateListenerEvent( + PhoneStateListener.EVENT_SERVICE_STATE_CHANGED) + && idMatch(r.subId, subId, phoneId)) { try { ServiceState stateToSend; @@ -1374,7 +1427,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { try { if ((activationType == SIM_ACTIVATION_TYPE_VOICE) && r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) + PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED) && idMatch(r.subId, subId, phoneId)) { if (DBG) { log("notifyVoiceActivationStateForPhoneId: callback.onVASC r=" + r @@ -1385,7 +1438,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } if ((activationType == SIM_ACTIVATION_TYPE_DATA) && r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE) + PhoneStateListener.EVENT_DATA_ACTIVATION_STATE_CHANGED) && idMatch(r.subId, subId, phoneId)) { if (DBG) { log("notifyDataActivationStateForPhoneId: callback.onDASC r=" + r @@ -1424,9 +1477,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { log("notifySignalStrengthForPhoneId: r=" + r + " subId=" + subId + " phoneId=" + phoneId + " ss=" + signalStrength); } - if ((r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) + if ((r.matchPhoneStateListenerEvent( + PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED) || r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)) + PhoneStateListener. + EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) && idMatch(r.subId, subId, phoneId)) { try { if (DBG) { @@ -1439,8 +1494,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mRemoveList.add(r.binder); } } - if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTH) && - idMatch(r.subId, subId, phoneId)) { + if (r.matchPhoneStateListenerEvent( + PhoneStateListener.EVENT_SIGNAL_STRENGTH_CHANGED) + && idMatch(r.subId, subId, phoneId)) { try { int gsmSignalStrength = signalStrength.getGsmSignalStrength(); int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); @@ -1486,8 +1542,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE) && - idMatch(r.subId, subId, phoneId)) { + PhoneStateListener.EVENT_CARRIER_NETWORK_CHANGED) + && idMatch(r.subId, subId, phoneId)) { try { r.callback.onCarrierNetworkChange(active); } catch (RemoteException ex) { @@ -1517,9 +1573,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (validatePhoneId(phoneId)) { mCellInfo.set(phoneId, cellInfo); for (Record r : mRecords) { - if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO) && - idMatch(r.subId, subId, phoneId) && - (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE) + if (validateEventAndUserLocked( + r, PhoneStateListener.EVENT_CELL_INFO_CHANGED) + && idMatch(r.subId, subId, phoneId) + && (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE) && checkFineLocationAccess(r, Build.VERSION_CODES.Q))) { try { if (DBG_LOC) { @@ -1551,8 +1608,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mMessageWaiting[phoneId] = mwi; for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) && - idMatch(r.subId, subId, phoneId)) { + PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED) + && idMatch(r.subId, subId, phoneId)) { try { r.callback.onMessageWaitingIndicatorChanged(mwi); } catch (RemoteException ex) { @@ -1578,8 +1635,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mUserMobileDataState[phoneId] = state; for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE) && - idMatch(r.subId, subId, phoneId)) { + PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED) + && idMatch(r.subId, subId, phoneId)) { try { r.callback.onUserMobileDataStateChanged(state); } catch (RemoteException ex) { @@ -1617,7 +1674,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mTelephonyDisplayInfos[phoneId] = telephonyDisplayInfo; for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED) + PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED) && idMatchWithoutDefaultPhoneCheck(r.subId, subId)) { try { r.callback.onDisplayInfoChanged(telephonyDisplayInfo); @@ -1649,8 +1706,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCallForwarding[phoneId] = cfi; for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) && - idMatch(r.subId, subId, phoneId)) { + PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED) + && idMatch(r.subId, subId, phoneId)) { try { r.callback.onCallForwardingIndicatorChanged(cfi); } catch (RemoteException ex) { @@ -1677,8 +1734,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mDataActivity[phoneId] = state; for (Record r : mRecords) { // Notify by correct subId. - if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_DATA_ACTIVITY) && - idMatch(r.subId, subId, phoneId)) { + if (r.matchPhoneStateListenerEvent( + PhoneStateListener.EVENT_DATA_ACTIVITY_CHANGED) + && idMatch(r.subId, subId, phoneId)) { try { r.callback.onDataActivity(state); } catch (RemoteException ex) { @@ -1725,7 +1783,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mLocalLog.log(str); for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) + PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED) && idMatch(r.subId, subId, phoneId)) { try { if (DBG) { @@ -1747,12 +1805,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { preciseState.getApnSetting()); PreciseDataConnectionState oldState = mPreciseDataConnectionStates.get(phoneId) .remove(key); - log("Jack: oldState=" + oldState); - log("Jack: newState=" + preciseState); if (!Objects.equals(oldState, preciseState)) { for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) + PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED) && idMatch(r.subId, subId, phoneId)) { try { r.callback.onPreciseDataConnectionStateChanged(preciseState); @@ -1797,9 +1853,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (validatePhoneId(phoneId) && !Objects.equals(cellIdentity, mCellIdentity[phoneId])) { mCellIdentity[phoneId] = cellIdentity; for (Record r : mRecords) { - if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) && - idMatch(r.subId, subId, phoneId) && - (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE) + if (validateEventAndUserLocked( + r, PhoneStateListener.EVENT_CELL_LOCATION_CHANGED) + && idMatch(r.subId, subId, phoneId) + && (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE) && checkFineLocationAccess(r, Build.VERSION_CODES.Q))) { try { if (DBG_LOC) { @@ -1850,7 +1907,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } for (Record r : mRecords) { - if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_PRECISE_CALL_STATE) + if (r.matchPhoneStateListenerEvent( + PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED) && idMatch(r.subId, subId, phoneId)) { try { r.callback.onPreciseCallStateChanged(mPreciseCallState[phoneId]); @@ -1859,7 +1917,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } if (notifyCallAttributes && r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED) + PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED) && idMatch(r.subId, subId, phoneId)) { try { r.callback.onCallAttributesChanged(mCallAttributes[phoneId]); @@ -1908,7 +1966,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mImsReasonInfo.set(phoneId, imsReasonInfo); for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES) + PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED) && idMatch(r.subId, subId, phoneId)) { try { if (DBG_LOC) { @@ -1940,8 +1998,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mSrvccState[phoneId] = state; for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) && - idMatch(r.subId, subId, phoneId)) { + PhoneStateListener.EVENT_SRVCC_STATE_CHANGED) + && idMatch(r.subId, subId, phoneId)) { try { if (DBG_LOC) { log("notifySrvccStateChanged: mSrvccState=" + state + " r=" + r); @@ -1969,7 +2027,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { log("notifyOemHookRawEventForSubscriber: r=" + r + " subId=" + subId); } if ((r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT)) + PhoneStateListener.EVENT_OEM_HOOK_RAW)) && idMatch(r.subId, subId, phoneId)) { try { r.callback.onOemHookRawEvent(rawData); @@ -1997,7 +2055,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE)) { + PhoneStateListener.EVENT_PHONE_CAPABILITY_CHANGED)) { try { r.callback.onPhoneCapabilityChanged(capability); } catch (RemoteException ex) { @@ -2022,7 +2080,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { synchronized (mRecords) { for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE)) { + PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED)) { try { r.callback.onActiveDataSubIdChanged(activeDataSubId); } catch (RemoteException ex) { @@ -2049,7 +2107,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED) + PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED) && idMatch(r.subId, subId, phoneId)) { try { r.callback.onRadioPowerStateChanged(state); @@ -2078,7 +2136,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST) + PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED) && idMatch(r.subId, subId, phoneId)) { try { r.callback.onEmergencyNumberListChanged(mEmergencyNumberList); @@ -2110,7 +2168,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { for (Record r : mRecords) { // Send to all listeners regardless of subscription if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL)) { + PhoneStateListener.EVENT_OUTGOING_EMERGENCY_CALL)) { try { r.callback.onOutgoingEmergencyCall(emergencyNumber, subId); } catch (RemoteException ex) { @@ -2134,7 +2192,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { for (Record r : mRecords) { // Send to all listeners regardless of subscription if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS)) { + PhoneStateListener.EVENT_OUTGOING_EMERGENCY_SMS)) { try { r.callback.onOutgoingEmergencySms(emergencyNumber, subId); } catch (RemoteException ex) { @@ -2164,7 +2222,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED) + PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED) && idMatch(r.subId, subId, phoneId)) { try { r.callback.onCallAttributesChanged(mCallAttributes[phoneId]); @@ -2195,7 +2253,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (validatePhoneId(phoneId)) { for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_REGISTRATION_FAILURE) + PhoneStateListener.EVENT_REGISTRATION_FAILURE) && idMatch(r.subId, subId, phoneId)) { try { r.callback.onRegistrationFailed( @@ -2238,7 +2296,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo); for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_BARRING_INFO) + PhoneStateListener.EVENT_BARRING_INFO_CHANGED) && idMatch(r.subId, subId, phoneId)) { try { if (DBG_LOC) { @@ -2258,6 +2316,81 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } + /** + * Send a notification to registrants that the configs of physical channel has changed for + * a particular subscription. + * + * @param subId the subId + * @param configs a list of {@link PhysicalChannelConfig}, the configs of physical channel. + */ + public void notifyPhysicalChannelConfigForSubscriber( + int subId, List configs) { + if (!checkNotifyPermission("notifyPhysicalChannelConfig()")) { + return; + } + + if (VDBG) { + log("notifyPhysicalChannelConfig: subId=" + subId + " configs=" + configs); + } + + synchronized (mRecords) { + int phoneId = SubscriptionManager.getPhoneId(subId); + if (validatePhoneId(phoneId)) { + mPhysicalChannelConfigs.set(phoneId, configs.get(phoneId)); + for (Record r : mRecords) { + if (r.matchPhoneStateListenerEvent( + PhoneStateListener.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED) + && idMatch(r.subId, subId, phoneId)) { + try { + if (DBG_LOC) { + log("notifyPhysicalChannelConfig: " + + "mPhysicalChannelConfigs=" + + configs + " r=" + r); + } + r.callback.onPhysicalChannelConfigChanged(configs); + } catch (RemoteException ex) { + mRemoveList.add(r.binder); + } + } + } + } + handleRemoveListLocked(); + } + } + + /** + * Notify that the data enabled has changed. + * + * @param enabled True if data is enabled, otherwise disabled. + * @param reason Reason for data enabled/disabled. See {@code DATA_*} in + * {@link TelephonyManager}. + */ + public void notifyDataEnabled(boolean enabled, + @TelephonyManager.DataEnabledReason int reason) { + if (!checkNotifyPermission("notifyDataEnabled()")) { + return; + } + + if (VDBG) { + log("notifyDataEnabled: enabled=" + enabled + " reason=" + reason); + } + + mIsDataEnabled = enabled; + mDataEnabledReason = reason; + synchronized (mRecords) { + for (Record r : mRecords) { + if (r.matchPhoneStateListenerEvent( + PhoneStateListener.EVENT_DATA_ENABLED_CHANGED)) { + try { + r.callback.onDataEnabledChanged(enabled, reason); + } catch (RemoteException ex) { + mRemoveList.add(r.binder); + } + } + } + handleRemoveListLocked(); + } + } @Override public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { @@ -2310,6 +2443,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mEmergencyNumberList=" + mEmergencyNumberList); pw.println("mDefaultPhoneId=" + mDefaultPhoneId); pw.println("mDefaultSubId=" + mDefaultSubId); + pw.println("mPhysicalChannelConfigs=" + mPhysicalChannelConfigs); + pw.println("mIsDataEnabled=" + mIsDataEnabled); + pw.println("mDataEnabledReason=" + mDataEnabledReason); pw.decreaseIndent(); @@ -2538,22 +2674,29 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { == PackageManager.PERMISSION_GRANTED; } - private boolean checkListenerPermission(int events, int subId, String callingPackage, + private boolean checkListenerPermission(Set events, int subId, String callingPackage, @Nullable String callingFeatureId, String message) { LocationAccessPolicy.LocationPermissionQuery.Builder locationQueryBuilder = new LocationAccessPolicy.LocationPermissionQuery.Builder() - .setCallingPackage(callingPackage) - .setMethod(message + " events: " + events) - .setCallingPid(Binder.getCallingPid()) - .setCallingUid(Binder.getCallingUid()); + .setCallingPackage(callingPackage) + .setMethod(message + " events: " + events) + .setCallingPid(Binder.getCallingPid()) + .setCallingUid(Binder.getCallingUid()); - if ((events & ENFORCE_LOCATION_PERMISSION_MASK) != 0) { + boolean shouldCheckLocationPermissions = false; + + if (isLocationPermissionRequired(events)) { // Everything that requires fine location started in Q. So far... locationQueryBuilder.setMinSdkVersionForFine(Build.VERSION_CODES.Q); // If we're enforcing fine starting in Q, we also want to enforce coarse even for // older SDK versions. locationQueryBuilder.setMinSdkVersionForCoarse(0); + shouldCheckLocationPermissions = true; + } + boolean isPermissionCheckSuccessful = true; + + if (shouldCheckLocationPermissions) { LocationAccessPolicy.LocationPermissionResult result = LocationAccessPolicy.checkLocationPermission( mContext, locationQueryBuilder.build()); @@ -2562,18 +2705,18 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { throw new SecurityException("Unable to listen for events " + events + " due to " + "insufficient location permissions."); case DENIED_SOFT: - return false; + isPermissionCheckSuccessful = false; } } - if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) { + if (isPhoneStatePermissionRequired(events)) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, callingFeatureId, message)) { - return false; + isPermissionCheckSuccessful = false; } } - if ((events & ENFORCE_PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) { + if (isPrecisePhoneStatePermissionRequired(events)) { // check if calling app has either permission READ_PRECISE_PHONE_STATE // or with carrier privileges try { @@ -2584,47 +2727,46 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - if ((events & READ_ACTIVE_EMERGENCY_SESSION_PERMISSION_MASK) != 0) { + if (isActiveEmergencySessionPermissionRequired(events)) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION, null); } - if ((events & PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) != 0) { + if ((events.contains(PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED))) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH, null); } - if ((events & READ_PRIVILEGED_PHONE_STATE_PERMISSION_MASK) != 0) { + if (isPrivilegedPhoneStatePermissionRequired(events)) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); } - - return true; + return isPermissionCheckSuccessful; } private void handleRemoveListLocked() { int size = mRemoveList.size(); if (VDBG) log("handleRemoveListLocked: mRemoveList.size()=" + size); if (size > 0) { - for (IBinder b: mRemoveList) { + for (IBinder b : mRemoveList) { remove(b); } mRemoveList.clear(); } } - private boolean validateEventsAndUserLocked(Record r, int events) { + private boolean validateEventAndUserLocked(Record r, int event) { int foregroundUser; long callingIdentity = Binder.clearCallingIdentity(); boolean valid = false; try { foregroundUser = ActivityManager.getCurrentUser(); valid = UserHandle.getUserId(r.callerUid) == foregroundUser - && r.matchPhoneStateListenerEvent(events); + && r.matchPhoneStateListenerEvent(event); if (DBG | DBG_LOC) { - log("validateEventsAndUserLocked: valid=" + valid + log("validateEventAndUserLocked: valid=" + valid + " r.callerUid=" + r.callerUid + " foregroundUser=" + foregroundUser - + " r.events=" + r.events + " events=" + events); + + " r.eventList=" + r.eventList + " event=" + event); } } finally { Binder.restoreCallingIdentity(callingIdentity); @@ -2677,6 +2819,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } + /** + * Note -- this method should only be used at the site of a permission check if you need to + * explicitly allow apps below a certain SDK level access regardless of location permissions. + * If you don't need app compat logic, use {@link #checkFineLocationAccess(Record)}. + */ private boolean checkFineLocationAccess(Record r, int minSdk) { LocationAccessPolicy.LocationPermissionQuery query = new LocationAccessPolicy.LocationPermissionQuery.Builder() @@ -2695,6 +2842,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { }); } + /** + * Note -- this method should only be used at the site of a permission check if you need to + * explicitly allow apps below a certain SDK level access regardless of location permissions. + * If you don't need app compat logic, use {@link #checkCoarseLocationAccess(Record)}. + */ private boolean checkCoarseLocationAccess(Record r, int minSdk) { LocationAccessPolicy.LocationPermissionQuery query = new LocationAccessPolicy.LocationPermissionQuery.Builder() @@ -2714,9 +2866,14 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } private void checkPossibleMissNotify(Record r, int phoneId) { - int events = r.events; + Set events = r.eventList; - if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { + if (events == null || events.isEmpty()) { + log("checkPossibleMissNotify: events = null."); + return; + } + + if ((events.contains(PhoneStateListener.EVENT_SERVICE_STATE_CHANGED))) { try { if (VDBG) log("checkPossibleMissNotify: onServiceStateChanged state=" + mServiceState[phoneId]); @@ -2735,8 +2892,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0 - || (events & PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) != 0) { + if (events.contains(PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED) + || events.contains( + PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) { try { if (mSignalStrength[phoneId] != null) { SignalStrength signalStrength = mSignalStrength[phoneId]; @@ -2751,7 +2909,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { + if (events.contains(PhoneStateListener.EVENT_SIGNAL_STRENGTH_CHANGED)) { try { if (mSignalStrength[phoneId] != null) { int gsmSignalStrength = mSignalStrength[phoneId] @@ -2768,7 +2926,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) { + if (validateEventAndUserLocked(r, PhoneStateListener.EVENT_CELL_INFO_CHANGED)) { try { if (DBG_LOC) { log("checkPossibleMissNotify: onCellInfoChanged[" + phoneId + "] = " @@ -2783,7 +2941,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - if ((events & PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE) != 0) { + if (events.contains(PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED)) { try { if (VDBG) { log("checkPossibleMissNotify: onUserMobileDataStateChanged phoneId=" @@ -2795,7 +2953,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - if ((events & PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED) != 0) { + if (events.contains(PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED)) { try { if (VDBG) { log("checkPossibleMissNotify: onDisplayInfoChanged phoneId=" @@ -2809,7 +2967,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { + if (events.contains(PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)) { try { if (VDBG) { log("checkPossibleMissNotify: onMessageWaitingIndicatorChanged phoneId=" @@ -2822,7 +2980,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { + if (events.contains(PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)) { try { if (VDBG) { log("checkPossibleMissNotify: onCallForwardingIndicatorChanged phoneId=" @@ -2835,7 +2993,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) { + if (validateEventAndUserLocked(r, PhoneStateListener.EVENT_CELL_LOCATION_CHANGED)) { try { if (DBG_LOC) { log("checkPossibleMissNotify: onCellLocationChanged mCellIdentity = " @@ -2851,7 +3009,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { + if (events.contains(PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED)) { try { if (DBG) { log("checkPossibleMissNotify: onDataConnectionStateChanged(mDataConnectionState" diff --git a/telephony/java/android/telephony/PhoneCapability.java b/telephony/java/android/telephony/PhoneCapability.java index b785037e51c12..6571858fc4ae3 100644 --- a/telephony/java/android/telephony/PhoneCapability.java +++ b/telephony/java/android/telephony/PhoneCapability.java @@ -28,8 +28,6 @@ import java.util.Objects; /** * Define capability of a modem group. That is, the capabilities * are shared between those modems defined by list of modem IDs. - * - * @hide */ public final class PhoneCapability implements Parcelable { // Hardcoded default DSDS capability. diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java index af62ba4b93a11..327d6313c4dc1 100644 --- a/telephony/java/android/telephony/PhysicalChannelConfig.java +++ b/telephony/java/android/telephony/PhysicalChannelConfig.java @@ -17,6 +17,8 @@ package android.telephony; import android.annotation.IntDef; +import android.annotation.IntRange; +import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; import android.telephony.Annotation.NetworkType; @@ -26,12 +28,10 @@ import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.Objects; -/** - * @hide - */ public final class PhysicalChannelConfig implements Parcelable { // TODO(b/72993578) consolidate these enums in a central location. + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef({CONNECTION_PRIMARY_SERVING, CONNECTION_SECONDARY_SERVING, CONNECTION_UNKNOWN}) public @interface ConnectionStatus {} @@ -47,7 +47,13 @@ public final class PhysicalChannelConfig implements Parcelable { public static final int CONNECTION_SECONDARY_SERVING = 2; /** Connection status is unknown. */ - public static final int CONNECTION_UNKNOWN = Integer.MAX_VALUE; + public static final int CONNECTION_UNKNOWN = -1; + + /** Channel number is unknown. */ + public static final int CHANNEL_NUMBER_UNKNOWN = -1; + + /** Physical Cell Id is unknown. */ + public static final int PHYSICAL_CELL_ID_UNKNOWN = -1; /** * Connection status of the cell. @@ -75,7 +81,7 @@ public final class PhysicalChannelConfig implements Parcelable { private int mFrequencyRange; /** - * The absolute radio frequency channel number, {@link Integer#MAX_VALUE} if unknown. + * The absolute radio frequency channel number, {@link #CHANNEL_NUMBER_UNKNOWN} if unknown. */ private int mChannelNumber; @@ -86,7 +92,7 @@ public final class PhysicalChannelConfig implements Parcelable { private int[] mContextIds; /** - * The physical cell identifier for this cell - PCI, PSC, {@link Integer#MAX_VALUE} if known. + * The physical cell identifier for this cell - PCI, PSC, {@link #PHYSICAL_CELL_ID_UNKNOWN} */ private int mPhysicalCellId; @@ -96,7 +102,7 @@ public final class PhysicalChannelConfig implements Parcelable { } @Override - public void writeToParcel(Parcel dest, int flags) { + public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mCellConnectionStatus); dest.writeInt(mCellBandwidthDownlinkKhz); dest.writeInt(mRat); @@ -120,6 +126,7 @@ public final class PhysicalChannelConfig implements Parcelable { * physical channel has no data call mapped to it. * * @return an integer list indicates the data call ids. + * @hide */ public int[] getContextIds() { return mContextIds; @@ -131,6 +138,7 @@ public final class PhysicalChannelConfig implements Parcelable { * @see {@link ServiceState#FREQUENCY_RANGE_MID} * @see {@link ServiceState#FREQUENCY_RANGE_HIGH} * @see {@link ServiceState#FREQUENCY_RANGE_MMWAVE} + * @hide */ @ServiceState.FrequencyRange public int getFrequencyRange() { @@ -139,7 +147,7 @@ public final class PhysicalChannelConfig implements Parcelable { /** * @return the absolute radio frequency channel number for this physical channel, - * {@link Integer#MAX_VALUE} if unknown. + * {@link #CHANNEL_NUMBER_UNKNOWN} if unknown. */ public int getChannelNumber() { return mChannelNumber; @@ -152,18 +160,20 @@ public final class PhysicalChannelConfig implements Parcelable { * In EUTRAN, this value is physical layer cell identity. The range is [0, 503]. * Reference: 3GPP TS 36.211 section 6.11. * - * In 5G RAN, this value is physical layer cell identity. The range is [0, 1008]. + * In 5G RAN, this value is physical layer cell identity. The range is [0, 1007]. * Reference: 3GPP TS 38.211 section 7.4.2.1. * - * @return the physical cell identifier for this cell, {@link Integer#MAX_VALUE} if unknown. + * @return the physical cell identifier for this cell, {@link #PHYSICAL_CELL_ID_UNKNOWN} + * if {@link android.telephony.CellInfo#UNAVAILABLE}. */ + @IntRange(from = 0, to = 1007) public int getPhysicalCellId() { return mPhysicalCellId; } /**The radio technology for this physical channel. */ @NetworkType - public int getRat() { + public int getNetworkType() { return mRat; } @@ -181,7 +191,10 @@ public final class PhysicalChannelConfig implements Parcelable { return mCellConnectionStatus; } - /** @return String representation of the connection status */ + /** + * @return String representation of the connection status + * @hide + */ private String getConnectionStatusString() { switch(mCellConnectionStatus) { case CONNECTION_PRIMARY_SERVING: @@ -274,7 +287,10 @@ public final class PhysicalChannelConfig implements Parcelable { mPhysicalCellId = builder.mPhysicalCellId; } - /** The builder of {@code PhysicalChannelConfig}. */ + /** + * The builder of {@code PhysicalChannelConfig}. + * @hide + */ public static final class Builder { private int mRat; private int mFrequencyRange; @@ -284,60 +300,51 @@ public final class PhysicalChannelConfig implements Parcelable { private int[] mContextIds; private int mPhysicalCellId; - /** @hide */ public Builder() { mRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN; mFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN; - mChannelNumber = Integer.MAX_VALUE; + mChannelNumber = CHANNEL_NUMBER_UNKNOWN; mCellBandwidthDownlinkKhz = 0; mCellConnectionStatus = CONNECTION_UNKNOWN; mContextIds = new int[0]; - mPhysicalCellId = Integer.MAX_VALUE; + mPhysicalCellId = PHYSICAL_CELL_ID_UNKNOWN; } - /** @hide */ public PhysicalChannelConfig build() { return new PhysicalChannelConfig(this); } - /** @hide */ public Builder setRat(int rat) { this.mRat = rat; return this; } - /** @hide */ public Builder setFrequencyRange(int frequencyRange) { this.mFrequencyRange = frequencyRange; return this; } - /** @hide */ public Builder setChannelNumber(int channelNumber) { this.mChannelNumber = channelNumber; return this; } - /** @hide */ public Builder setCellBandwidthDownlinkKhz(int cellBandwidthDownlinkKhz) { this.mCellBandwidthDownlinkKhz = cellBandwidthDownlinkKhz; return this; } - /** @hide */ public Builder setCellConnectionStatus(int connectionStatus) { this.mCellConnectionStatus = connectionStatus; return this; } - /** @hide */ public Builder setContextIds(int[] contextIds) { if (contextIds != null) Arrays.sort(contextIds); this.mContextIds = contextIds; return this; } - /** @hide */ public Builder setPhysicalCellId(int physicalCellId) { this.mPhysicalCellId = physicalCellId; return this; diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index c05e90b28fa82..a25f79e72cf46 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -124,6 +124,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.UUID; import java.util.concurrent.Executor; import java.util.function.Consumer; @@ -155,6 +156,7 @@ import java.util.function.Consumer; public class TelephonyManager { private static final String TAG = "TelephonyManager"; + private TelephonyRegistryManager mTelephonyRegistryMgr; /** * To expand the error codes for {@link TelephonyManager#updateAvailableNetworks} and * {@link TelephonyManager#setPreferredOpportunisticDataSubscription}. @@ -5569,8 +5571,7 @@ public class TelephonyManager { // /** - * Registers a listener object to receive notification of changes - * in specified telephony states. + * Registers a listener object to receive notification of changes in specified telephony states. *

* To register a listener, pass a {@link PhoneStateListener} and specify at least one telephony * state of interest in the events argument. @@ -5580,13 +5581,15 @@ public class TelephonyManager { * values. *

* To un-register a listener, pass the listener object and set the events argument to - * {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0). + * {@link PhoneStateListener#LISTEN_NONE} (0). * * If this TelephonyManager object has been created with {@link #createForSubscriptionId}, * applies to the given subId. Otherwise, applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. To listen events for multiple subIds, + * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}. To listen events for multiple subIds, * pass a separate listener object to each TelephonyManager object created with - * {@link #createForSubscriptionId}. + * {@link #createForSubscriptionId}. Only {@link PhoneStateListener#LISTEN_CALL_STATE} event can + * be used to receive changes for all subIds through + * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}. * * Note: if you call this method while in the middle of a binder transaction, you must * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A @@ -5596,23 +5599,28 @@ public class TelephonyManager { * instability. If a process has registered too many listeners without unregistering them, it * may encounter an {@link IllegalStateException} when trying to register more listeners. * - * @param listener The {@link PhoneStateListener} object to register - * (or unregister) - * @param events The telephony state(s) of interest to the listener, - * as a bitwise-OR combination of {@link PhoneStateListener} - * LISTEN_ flags. + * @param listener The {@link PhoneStateListener} object to register (or unregister) + * @param events The telephony state(s) of interest to the listener, as a bitwise-OR combination + * of {@link PhoneStateListener} LISTEN_ flags. + * @deprecated Use {@link #registerPhoneStateListener(Executor, PhoneStateListener)}. */ + @Deprecated public void listen(PhoneStateListener listener, int events) { - if (mContext == null) return; - boolean notifyNow = (getITelephony() != null); - TelephonyRegistryManager telephonyRegistry = - (TelephonyRegistryManager) - mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); - if (telephonyRegistry != null) { - telephonyRegistry.listenForSubscriber(mSubId, getOpPackageName(), getAttributionTag(), - listener, events, notifyNow); + if (!listener.isExecutorSet()) { + throw new IllegalStateException("PhoneStateListener should be created on a thread " + + "with Looper.myLooper() != null"); + } + boolean notifyNow = getITelephony() != null; + mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class); + if (mTelephonyRegistryMgr != null) { + if (events != PhoneStateListener.LISTEN_NONE) { + mTelephonyRegistryMgr.registerPhoneStateListenerWithEvents(mSubId, + getOpPackageName(), getAttributionTag(), listener, events, notifyNow); + } else { + unregisterPhoneStateListener(listener); + } } else { - Rlog.w(TAG, "telephony registry not ready."); + throw new IllegalStateException("telephony service is null."); } } @@ -14583,4 +14591,71 @@ public class TelephonyManager { e.execute(() -> callback.onAuthenticationFailure(GBA_FAILURE_REASON_FEATURE_NOT_READY)); } } + + /** + * Registers a listener object to receive notification of changes in specified telephony states. + *

+ * To register a listener, pass a {@link PhoneStateListener} which implements + * interfaces of events. For example, + * FakeServiceStateChangedListener extends {@link PhoneStateListener} implements + * {@link PhoneStateListener.ServiceStateChangedListener}. + * + * At registration, and when a specified telephony state changes, the telephony manager invokes + * the appropriate callback method on the listener object and passes the current (updated) + * values. + *

+ * + * If this TelephonyManager object has been created with {@link #createForSubscriptionId}, + * applies to the given subId. Otherwise, applies to + * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}. To listen events for multiple subIds, + * pass a separate listener object to each TelephonyManager object created with + * {@link #createForSubscriptionId}. Only {@link PhoneStateListener.CallStateChangedListener} + * can be used to receive changes for all subIds through + * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID}. + * + * Note: if you call this method while in the middle of a binder transaction, you must + * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A + * {@link SecurityException} will be thrown otherwise. + * + * This API should be used sparingly -- large numbers of listeners will cause system + * instability. If a process has registered too many listeners without unregistering them, it + * may encounter an {@link IllegalStateException} when trying to register more listeners. + * + * @param executor The executor of where the callback will execute. + * @param listener The {@link PhoneStateListener} object to register. + */ + public void registerPhoneStateListener(@NonNull @CallbackExecutor Executor executor, + @NonNull PhoneStateListener listener) { + if (executor == null || listener == null) { + throw new IllegalArgumentException("PhoneStateListener and executor must be non-null"); + } + mTelephonyRegistryMgr = (TelephonyRegistryManager) + mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); + if (mTelephonyRegistryMgr != null) { + mTelephonyRegistryMgr.registerPhoneStateListener(executor, mSubId, + getOpPackageName(), getAttributionTag(), listener, getITelephony() != null); + } else { + throw new IllegalStateException("telephony service is null."); + } + } + + /** + * Unregister an existing {@link PhoneStateListener}. + * + * @param listener The {@link PhoneStateListener} object to unregister. + */ + public void unregisterPhoneStateListener(@NonNull PhoneStateListener listener) { + + if (mContext == null) { + throw new IllegalStateException("telephony service is null."); + } + + mTelephonyRegistryMgr = mContext.getSystemService(TelephonyRegistryManager.class); + if (mTelephonyRegistryMgr != null) { + mTelephonyRegistryMgr.unregisterPhoneStateListener(mSubId, getOpPackageName(), + getAttributionTag(), listener, getITelephony() != null); + } else { + throw new IllegalStateException("telephony service is null."); + } + } }