Merge "Integrate IKeystoreAuthorization aidl's addAuthToken with Keystore SPI."
diff --git a/core/api/current.txt b/core/api/current.txt
index 252c33c..d1906c6 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -385,6 +385,7 @@
field public static final int calendarViewShown = 16843596; // 0x101034c
field public static final int calendarViewStyle = 16843613; // 0x101035d
field public static final int canControlMagnification = 16844039; // 0x1010507
+ field public static final int canPauseRecording = 16844311; // 0x1010617
field public static final int canPerformGestures = 16844045; // 0x101050d
field public static final int canRecord = 16844060; // 0x101051c
field @Deprecated public static final int canRequestEnhancedWebAccessibility = 16843736; // 0x10103d8
@@ -24265,6 +24266,7 @@
}
public final class TvInputInfo implements android.os.Parcelable {
+ method public boolean canPauseRecording();
method public boolean canRecord();
method @Deprecated public android.content.Intent createSettingsIntent();
method public android.content.Intent createSetupIntent();
@@ -24298,6 +24300,7 @@
public static final class TvInputInfo.Builder {
ctor public TvInputInfo.Builder(android.content.Context, android.content.ComponentName);
method public android.media.tv.TvInputInfo build();
+ method @NonNull public android.media.tv.TvInputInfo.Builder setCanPauseRecording(boolean);
method public android.media.tv.TvInputInfo.Builder setCanRecord(boolean);
method public android.media.tv.TvInputInfo.Builder setExtras(android.os.Bundle);
method public android.media.tv.TvInputInfo.Builder setTunerCount(int);
@@ -24389,7 +24392,9 @@
method public void notifyRecordingStopped(android.net.Uri);
method public void notifyTuned(android.net.Uri);
method public void onAppPrivateCommand(@NonNull String, android.os.Bundle);
+ method public void onPauseRecording(@NonNull android.os.Bundle);
method public abstract void onRelease();
+ method public void onResumeRecording(@NonNull android.os.Bundle);
method public abstract void onStartRecording(@Nullable android.net.Uri);
method public void onStartRecording(@Nullable android.net.Uri, @NonNull android.os.Bundle);
method public abstract void onStopRecording();
@@ -24439,7 +24444,11 @@
public class TvRecordingClient {
ctor public TvRecordingClient(android.content.Context, String, @NonNull android.media.tv.TvRecordingClient.RecordingCallback, android.os.Handler);
+ method public void pauseRecording();
+ method public void pauseRecording(@NonNull android.os.Bundle);
method public void release();
+ method public void resumeRecording();
+ method public void resumeRecording(@NonNull android.os.Bundle);
method public void sendAppPrivateCommand(@NonNull String, android.os.Bundle);
method public void startRecording(@Nullable android.net.Uri);
method public void startRecording(@Nullable android.net.Uri, @NonNull android.os.Bundle);
@@ -40486,6 +40495,12 @@
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<android.telephony.PhoneCapability> CREATOR;
+ }
+
public class PhoneNumberFormattingTextWatcher implements android.text.TextWatcher {
ctor public PhoneNumberFormattingTextWatcher();
ctor public PhoneNumberFormattingTextWatcher(String);
@@ -40497,12 +40512,13 @@
public class PhoneNumberUtils {
ctor public PhoneNumberUtils();
method public static void addTtsSpan(android.text.Spannable, int, int);
+ method public static boolean areSamePhoneNumber(@NonNull String, @NonNull String, @NonNull String);
method @Deprecated public static String calledPartyBCDFragmentToString(byte[], int, int);
method public static String calledPartyBCDFragmentToString(byte[], int, int, int);
method @Deprecated public static String calledPartyBCDToString(byte[], int, int);
method public static String calledPartyBCDToString(byte[], int, int, int);
- method public static boolean compare(String, String);
- method public static boolean compare(android.content.Context, String, String);
+ method @Deprecated public static boolean compare(String, String);
+ method @Deprecated public static boolean compare(android.content.Context, String, String);
method public static String convertKeypadLettersToDigits(String);
method public static android.text.style.TtsSpan createTtsSpan(String);
method public static CharSequence createTtsSpannable(CharSequence);
@@ -40554,10 +40570,10 @@
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<android.telephony.CellInfo>);
@@ -40565,36 +40581,140 @@
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<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>>);
- 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<android.telephony.CellInfo>);
+ }
+
+ 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<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>>);
+ }
+
+ 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<android.telephony.PhysicalChannelConfig> CREATOR;
+ field public static final int PHYSICAL_CELL_ID_UNKNOWN = -1; // 0xffffffff
}
public final class PreciseDataConnectionState implements android.os.Parcelable {
@@ -40676,6 +40796,32 @@
field public static final int INVALID = 2147483647; // 0x7fffffff
}
+ public final class SignalThresholdInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getRadioAccessNetworkType();
+ method public int getSignalMeasurementType();
+ method @NonNull public int[] getThresholds();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.SignalThresholdInfo> CREATOR;
+ field public static final int SIGNAL_MEASUREMENT_TYPE_RSCP = 2; // 0x2
+ field public static final int SIGNAL_MEASUREMENT_TYPE_RSRP = 3; // 0x3
+ field public static final int SIGNAL_MEASUREMENT_TYPE_RSRQ = 4; // 0x4
+ field public static final int SIGNAL_MEASUREMENT_TYPE_RSSI = 1; // 0x1
+ field public static final int SIGNAL_MEASUREMENT_TYPE_RSSNR = 5; // 0x5
+ field public static final int SIGNAL_MEASUREMENT_TYPE_SSRSRP = 6; // 0x6
+ field public static final int SIGNAL_MEASUREMENT_TYPE_SSRSRQ = 7; // 0x7
+ field public static final int SIGNAL_MEASUREMENT_TYPE_SSSINR = 8; // 0x8
+ field public static final int SIGNAL_MEASUREMENT_TYPE_UNKNOWN = 0; // 0x0
+ }
+
+ public static final class SignalThresholdInfo.Builder {
+ ctor public SignalThresholdInfo.Builder();
+ method @NonNull public android.telephony.SignalThresholdInfo build();
+ method @NonNull public android.telephony.SignalThresholdInfo.Builder setRadioAccessNetworkType(int);
+ method @NonNull public android.telephony.SignalThresholdInfo.Builder setSignalMeasurementType(int);
+ method @NonNull public android.telephony.SignalThresholdInfo.Builder setThresholds(@NonNull int[]);
+ }
+
public final class SmsManager {
method public String createAppSpecificSmsToken(android.app.PendingIntent);
method @Nullable public String createAppSpecificSmsTokenWithPackageInfo(@Nullable String, @NonNull android.app.PendingIntent);
@@ -41105,7 +41251,8 @@
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 +41275,7 @@
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<android.telephony.AvailableNetworkInfo>, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
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";
@@ -41149,6 +41297,7 @@
field public static final int AUTHTYPE_EAP_SIM = 128; // 0x80
field public static final int CALL_COMPOSER_STATUS_OFF = 0; // 0x0
field public static final int CALL_COMPOSER_STATUS_ON = 1; // 0x1
+ field public static final int CALL_COMPOSER_STATUS_ON_NO_PICTURES = 2; // 0x2
field public static final int CALL_STATE_IDLE = 0; // 0x0
field public static final int CALL_STATE_OFFHOOK = 2; // 0x2
field public static final int CALL_STATE_RINGING = 1; // 0x1
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 03e80fc..e768ea6 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -9813,17 +9813,87 @@
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<android.telephony.PhysicalChannelConfig>);
+ }
+
+ 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/app/search/OWNERS b/core/java/android/app/search/OWNERS
new file mode 100644
index 0000000..92835c2
--- /dev/null
+++ b/core/java/android/app/search/OWNERS
@@ -0,0 +1,2 @@
+hyunyoungs@google.com
+sfufa@google.com
diff --git a/core/java/android/net/vcn/VcnTransportInfo.java b/core/java/android/net/vcn/VcnTransportInfo.java
new file mode 100644
index 0000000..4d8cf91
--- /dev/null
+++ b/core/java/android/net/vcn/VcnTransportInfo.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.vcn;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.TransportInfo;
+import android.net.wifi.WifiInfo;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.SubscriptionManager;
+
+import java.util.Objects;
+
+/**
+ * VcnTransportInfo contains information about the VCN's underlying transports for SysUi.
+ *
+ * <p>Presence of this class in the NetworkCapabilities.TransportInfo implies that the network is a
+ * VCN.
+ *
+ * <p>VcnTransportInfo must exist on top of either an underlying Wifi or Cellular Network. If the
+ * underlying Network is WiFi, the subId will be {@link
+ * SubscriptionManager#INVALID_SUBSCRIPTION_ID}. If the underlying Network is Cellular, the WifiInfo
+ * will be {@code null}.
+ *
+ * @hide
+ */
+public class VcnTransportInfo implements TransportInfo, Parcelable {
+ @Nullable private final WifiInfo mWifiInfo;
+ private final int mSubId;
+
+ public VcnTransportInfo(@NonNull WifiInfo wifiInfo) {
+ this(wifiInfo, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ }
+
+ public VcnTransportInfo(int subId) {
+ this(null /* wifiInfo */, subId);
+ }
+
+ private VcnTransportInfo(@Nullable WifiInfo wifiInfo, int subId) {
+ if (wifiInfo == null && subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ throw new IllegalArgumentException(
+ "VcnTransportInfo requires either non-null WifiInfo or valid subId");
+ }
+
+ mWifiInfo = wifiInfo;
+ mSubId = subId;
+ }
+
+ /**
+ * Get the {@link WifiInfo} for this VcnTransportInfo.
+ *
+ * <p>If the underlying Network for the associated VCN is Cellular, returns null.
+ *
+ * @return the WifiInfo if there is an underlying WiFi connection, else null.
+ */
+ @Nullable
+ public WifiInfo getWifiInfo() {
+ return mWifiInfo;
+ }
+
+ /**
+ * Get the subId for the VCN Network associated with this VcnTransportInfo.
+ *
+ * <p>If the underlying Network for the associated VCN is WiFi, returns {@link
+ * SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
+ *
+ * @return the Subscription ID if a cellular underlying Network is present, else {@link
+ * android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID}.
+ */
+ public int getSubId() {
+ return mSubId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mWifiInfo, mSubId);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof VcnTransportInfo)) return false;
+ final VcnTransportInfo that = (VcnTransportInfo) o;
+
+ return Objects.equals(mWifiInfo, that.mWifiInfo) && mSubId == that.mSubId;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {}
+
+ /** Implement the Parcelable interface */
+ public static final @NonNull Creator<VcnTransportInfo> CREATOR =
+ new Creator<VcnTransportInfo>() {
+ public VcnTransportInfo createFromParcel(Parcel in) {
+ // return null instead of a default VcnTransportInfo to avoid leaking
+ // information about this being a VCN Network (instead of macro cellular, etc)
+ return null;
+ }
+
+ public VcnTransportInfo[] newArray(int size) {
+ return new VcnTransportInfo[size];
+ }
+ };
+}
diff --git a/core/java/android/service/search/OWNERS b/core/java/android/service/search/OWNERS
new file mode 100644
index 0000000..92835c2
--- /dev/null
+++ b/core/java/android/service/search/OWNERS
@@ -0,0 +1,2 @@
+hyunyoungs@google.com
+sfufa@google.com
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index d6ae434..03d3755 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.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 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 @@
*
* @see #onServiceStateChanged
* @see ServiceState
+ * @deprecated Use {@link ServiceStateChangedListener} instead.
*/
+ @Deprecated
public static final int LISTEN_SERVICE_STATE = 0x00000001;
/**
@@ -122,8 +136,7 @@
* {@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 @@
* voicemail icon.
*
* @see #onMessageWaitingIndicatorChanged
+ * @deprecated Use {@link MessageWaitingIndicatorChangedListener} instead.
*/
+ @Deprecated
public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 0x00000004;
/**
@@ -150,7 +165,9 @@
* {@link TelephonyManager#hasCarrierPrivileges}).
*
* @see #onCallForwardingIndicatorChanged
+ * @deprecated Use {@link CallForwardingIndicatorChangedListener} instead.
*/
+ @Deprecated
public static final int LISTEN_CALL_FORWARDING_INDICATOR = 0x00000008;
/**
@@ -166,7 +183,9 @@
* instead.
*
* @see #onCellLocationChanged
+ * @deprecated Use {@link CellLocationChangedListener} instead.
*/
+ @Deprecated
public static final int LISTEN_CELL_LOCATION = 0x00000010;
/**
@@ -174,14 +193,18 @@
* {@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 @@
* data-traffic icon.
*
* @see #onDataActivity
+ * @deprecated Use {@link DataActivityListener} instead.
*/
+ @Deprecated
public static final int LISTEN_DATA_ACTIVITY = 0x00000080;
/**
@@ -202,7 +227,9 @@
* icon.
*
* @see #onSignalStrengthsChanged
+ * @deprecated Use {@link SignalStrengthsChangedListener} instead.
*/
+ @Deprecated
public static final int LISTEN_SIGNAL_STRENGTHS = 0x00000100;
/**
@@ -212,7 +239,9 @@
* @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 @@
* permission.
*
* @see #onCellInfoChanged
+ * @deprecated Use {@link CellInfoChangedListener} instead.
*/
+ @Deprecated
public static final int LISTEN_CELL_INFO = 0x00000400;
/**
@@ -235,8 +266,10 @@
* (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 @@
* (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 @@
* READ_PRECISE_PHONE_STATE}
* @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo)
*
- * @deprecated Use {@link TelephonyManager#getModemActivityInfo()}
+ * @deprecated Use {@link TelephonyManager#requestModemActivityInfo} instead.
* @hide
*/
@Deprecated
@@ -272,7 +307,9 @@
*
* @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 @@
/**
* 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 @@
*
* @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 @@
* @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 @@
* {@link TelephonyManager#hasCarrierPrivileges}).
*
* @see #onDisplayInfoChanged
+ * @deprecated Use {@link DisplayInfoChangedListener} instead.
*/
+ @Deprecated
public static final int LISTEN_DISPLAY_INFO_CHANGED = 0x00100000;
/**
@@ -356,7 +402,9 @@
*
* @see #onPhoneCapabilityChanged
* @hide
+ * @deprecated Use {@link PhoneCapabilityChangedListener} instead.
*/
+ @Deprecated
public static final int LISTEN_PHONE_CAPABILITY_CHANGE = 0x00200000;
/**
@@ -366,17 +414,19 @@
* 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.
*
- * <p>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 @@
*
* <p>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 @@
* 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 @@
*
* @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 @@
* (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.
*
- * <p>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 @@
/**
* Listen for the emergency number placed from an outgoing SMS.
*
- * <p>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 @@
* 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 @@
* 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}).
+ * <p>
+ * 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).
+ * <p>
+ * 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.
+ *
+ * <p>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).
+ *
+ * <p>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.
+ *
+ * <p>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.
+ *
+ * <p>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}.
+ *
+ * <p>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.
+ *
+ * <p>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}
+ *
+ * <p>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}.
+ *
+ * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or
+ * the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+ *
+ * <p>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.
+ *
+ * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or
+ * the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}).
+ *
+ * <p>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.
+ *
+ * <p>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.
+ *
+ * <p>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 @@
/**
* @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 @@
*/
@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 @@
* 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.
+ * <p>
+ * Reports the state of Telephony (mobile) calls on the device for the registered s
+ * ubscription.
+ * <p>
+ * 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.
+ * <p>
+ * 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> 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()}.
+ *
+ * <p>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.
+ * <p> 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<Integer, List<EmergencyNumber>> 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.
+ *
+ * <p>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().
+ *
+ * <p>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.
+ *
+ * <p>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<PhysicalChannelConfig> 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 @@
* 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.
* <p>
* 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 @@
* same as above, but with the network type. Both called.
*/
public void onDataConnectionStateChanged(int state, int networkType) {
+ // default implementation empty
}
/**
@@ -745,6 +2057,7 @@
* @param cellInfo is the list of currently visible cells.
*/
public void onCellInfoChanged(List<CellInfo> cellInfo) {
+ // default implementation empty
}
/**
@@ -758,7 +2071,7 @@
* @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 @@
* @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 @@
* @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 @@
*
* @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 @@
*/
@SystemApi
public void onSrvccStateChanged(@SrvccState int srvccState) {
+ // default implementation empty
}
@@ -873,6 +2187,7 @@
*/
@SystemApi
public void onVoiceActivationStateChanged(@SimActivationState int state) {
+ // default implementation empty
}
/**
@@ -889,6 +2204,7 @@
* @hide
*/
public void onDataActivationStateChanged(@SimActivationState int state) {
+ // default implementation empty
}
/**
@@ -916,7 +2232,7 @@
*
* @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 @@
/**
* 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 @@
* @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 @@
* 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 @@
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 @@
Binder.withCleanCallingIdentity(
() -> mExecutor.execute(() -> psl.onBarringInfoChanged(barringInfo)));
}
- }
+ public void onPhysicalChannelConfigChanged(List<PhysicalChannelConfig> 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 3673ae7..a9548b0 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.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.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 java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.Executor;
/**
@@ -206,7 +212,7 @@
}
/**
- * 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 @@
* @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 @@
}
}
+ /**
+ * 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<PhysicalChannelConfig> 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<Integer> getEventsFromListener(@NonNull PhoneStateListener listener) {
+
+ Set<Integer> 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<Integer> getEventsFromBitmask(int eventMask) {
+
+ Set<Integer> 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.
+ * <p>
+ * 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.
+ * <p>
+ *
+ * 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 <b>must</b>
+ * 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<Integer> 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/android/view/textclassifier/OWNERS b/core/java/android/view/textclassifier/OWNERS
index ac80d9f..4bcdeea 100644
--- a/core/java/android/view/textclassifier/OWNERS
+++ b/core/java/android/view/textclassifier/OWNERS
@@ -6,3 +6,5 @@
svetoslavganov@google.com
augale@google.com
joannechung@google.com
+tonymak@google.com
+licha@google.com
diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
index d2dc7c2..854fb17 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.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 @@
void onRegistrationFailed(in CellIdentity cellIdentity,
String chosenPlmn, int domain, int causeCode, int additionalCauseCode);
void onBarringInfoChanged(in BarringInfo barringInfo);
+ void onPhysicalChannelConfigChanged(in List<PhysicalChannelConfig> 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 5f2dcc3..2a73dac 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -41,16 +41,8 @@
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 @@
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<PhysicalChannelConfig> configs);
+ void notifyDataEnabled(boolean enabled, int reason);
}
diff --git a/core/java/com/android/internal/widget/OWNERS b/core/java/com/android/internal/widget/OWNERS
index cca39ea..ae566c3 100644
--- a/core/java/com/android/internal/widget/OWNERS
+++ b/core/java/com/android/internal/widget/OWNERS
@@ -1 +1,7 @@
per-file PointerLocationView.java = michaelwr@google.com, svv@google.com
+
+# LockSettings related
+per-file *LockPattern* = file:/services/core/java/com/android/server/locksettings/OWNERS
+per-file *LockScreen* = file:/services/core/java/com/android/server/locksettings/OWNERS
+per-file *Lockscreen* = file:/services/core/java/com/android/server/locksettings/OWNERS
+per-file *LockSettings* = file:/services/core/java/com/android/server/locksettings/OWNERS
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 22dd765..dc98aaf 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -1810,7 +1810,7 @@
heap_tagging_level = M_HEAP_TAGGING_LEVEL_NONE;
break;
}
- android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &heap_tagging_level, sizeof(heap_tagging_level));
+ mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, heap_tagging_level);
// Now that we've used the flag, clear it so that we don't pass unknown flags to the ART runtime.
runtime_flags &= ~RuntimeFlags::MEMORY_TAG_LEVEL_MASK;
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 2f1bcdc..4b3d82a 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -8968,6 +8968,11 @@
changed at runtime by calling
{@link android.media.tv.TvInputManager#updateTvInputInfo(android.media.tv.TvInputInfo)}. -->
<attr name="tunerCount" format="integer" />
+ <!-- Attribute whether the TV input service can pause recording programs.
+ This value can be changed at runtime by calling
+ {@link android.media.tv.TvInputManager#updateTvInputInfo(android.media.tv.TvInputInfo)}
+ . -->
+ <attr name="canPauseRecording" format="boolean" />
</declare-styleable>
<!-- Attributes that can be used with <code>rating-system-definition</code> tags inside of the
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index e00aff1..a0be068 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3043,6 +3043,7 @@
=============================================================== -->
<public-group type="attr" first-id="0x01010617">
+ <public name="canPauseRecording" />
<!-- attribute definitions go here -->
</public-group>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 1143467..8ac00dc 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -110,7 +110,7 @@
<!-- Displayed as the title for a success/failure report enabling/disabling caller ID. -->
<string name="ClipMmi">Incoming Caller ID</string>
<!-- Displayed as the title for a success/failure report enabling/disabling caller ID. -->
- <string name="ClirMmi">Outgoing Caller ID</string>
+ <string name="ClirMmi">Hide Outgoing Caller ID</string>
<!-- Displayed as the title for a success/failure report enabling/disabling connected line ID. -->
<string name="ColpMmi">Connected Line ID</string>
<!-- Displayed as the title for a success/failure report enabling/disabling connected line ID restriction. -->
diff --git a/core/tests/coretests/src/android/view/autofill/OWNERS b/core/tests/coretests/src/android/view/autofill/OWNERS
new file mode 100644
index 0000000..9a30e82
--- /dev/null
+++ b/core/tests/coretests/src/android/view/autofill/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 351486
+
+include /core/java/android/view/autofill/OWNERS
diff --git a/core/tests/coretests/src/android/view/contentcapture/OWNERS b/core/tests/coretests/src/android/view/contentcapture/OWNERS
new file mode 100644
index 0000000..24561c5
--- /dev/null
+++ b/core/tests/coretests/src/android/view/contentcapture/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 544200
+
+include /core/java/android/view/contentcapture/OWNERS
diff --git a/core/tests/coretests/src/android/view/textclassifier/OWNERS b/core/tests/coretests/src/android/view/textclassifier/OWNERS
new file mode 100644
index 0000000..46b3cb8
--- /dev/null
+++ b/core/tests/coretests/src/android/view/textclassifier/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/textclassifier/OWNERS
diff --git a/keystore/java/android/security/keystore2/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/keystore2/KeyStoreCryptoOperationChunkedStreamer.java
index 6c733ba..33e8ded 100644
--- a/keystore/java/android/security/keystore2/KeyStoreCryptoOperationChunkedStreamer.java
+++ b/keystore/java/android/security/keystore2/KeyStoreCryptoOperationChunkedStreamer.java
@@ -139,7 +139,9 @@
int inputConsumed = ArrayUtils.copy(input, inputOffset, mChunk, mChunkLength,
inputLength);
inputLength -= inputConsumed;
- inputOffset += inputOffset;
+ inputOffset += inputConsumed;
+ mChunkLength += inputConsumed;
+ if (mChunkLength < mChunkSizeMax) return output;
byte[] o = mKeyStoreStream.update(mChunk);
if (o != null) {
output = ArrayUtils.concat(output, o);
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
index 1fbb672..5d7fdff 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -91,6 +91,8 @@
// For the recording session
void startRecording(in IBinder sessionToken, in Uri programUri, in Bundle params, int userId);
void stopRecording(in IBinder sessionToken, int userId);
+ void pauseRecording(in IBinder sessionToken, in Bundle params, int userId);
+ void resumeRecording(in IBinder sessionToken, in Bundle params, int userId);
// For TV input hardware binding
List<TvInputHardwareInfo> getHardwareList();
diff --git a/media/java/android/media/tv/ITvInputSession.aidl b/media/java/android/media/tv/ITvInputSession.aidl
index 24b87d5..158cf21 100644
--- a/media/java/android/media/tv/ITvInputSession.aidl
+++ b/media/java/android/media/tv/ITvInputSession.aidl
@@ -58,4 +58,6 @@
// For the recording session
void startRecording(in Uri programUri, in Bundle params);
void stopRecording();
+ void pauseRecording(in Bundle params);
+ void resumeRecording(in Bundle params);
}
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index e89d33d..abccf8d 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -68,6 +68,8 @@
private static final int DO_TIME_SHIFT_ENABLE_POSITION_TRACKING = 19;
private static final int DO_START_RECORDING = 20;
private static final int DO_STOP_RECORDING = 21;
+ private static final int DO_PAUSE_RECORDING = 22;
+ private static final int DO_RESUME_RECORDING = 23;
private final boolean mIsRecordingSession;
private final HandlerCaller mCaller;
@@ -224,6 +226,14 @@
mTvInputRecordingSessionImpl.stopRecording();
break;
}
+ case DO_PAUSE_RECORDING: {
+ mTvInputRecordingSessionImpl.pauseRecording((Bundle) msg.obj);
+ break;
+ }
+ case DO_RESUME_RECORDING: {
+ mTvInputRecordingSessionImpl.resumeRecording((Bundle) msg.obj);
+ break;
+ }
default: {
Log.w(TAG, "Unhandled message code: " + msg.what);
break;
@@ -363,6 +373,16 @@
mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_STOP_RECORDING));
}
+ @Override
+ public void pauseRecording(@Nullable Bundle params) {
+ mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_PAUSE_RECORDING, params));
+ }
+
+ @Override
+ public void resumeRecording(@Nullable Bundle params) {
+ mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_RESUME_RECORDING, params));
+ }
+
private final class TvInputEventReceiver extends InputEventReceiver {
public TvInputEventReceiver(InputChannel inputChannel, Looper looper) {
super(inputChannel, looper);
diff --git a/media/java/android/media/tv/TvInputHardwareInfo.java b/media/java/android/media/tv/TvInputHardwareInfo.java
index b12f7c5..1249e0d 100644
--- a/media/java/android/media/tv/TvInputHardwareInfo.java
+++ b/media/java/android/media/tv/TvInputHardwareInfo.java
@@ -188,6 +188,17 @@
mCableConnectionStatus = source.readInt();
}
+ /** @hide */
+ public Builder toBuilder() {
+ return new Builder()
+ .deviceId(mDeviceId)
+ .type(mType)
+ .audioType(mAudioType)
+ .audioAddress(mAudioAddress)
+ .hdmiPortId(mHdmiPortId)
+ .cableConnectionStatus(mCableConnectionStatus);
+ }
+
public static final class Builder {
private Integer mDeviceId = null;
private Integer mType = null;
diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java
index 195ad5b..54cb2bf 100644
--- a/media/java/android/media/tv/TvInputInfo.java
+++ b/media/java/android/media/tv/TvInputInfo.java
@@ -143,6 +143,7 @@
// Attributes from XML meta data.
private final String mSetupActivity;
private final boolean mCanRecord;
+ private final boolean mCanPauseRecording;
private final int mTunerCount;
// Attributes specific to HDMI
@@ -264,8 +265,8 @@
private TvInputInfo(ResolveInfo service, String id, int type, boolean isHardwareInput,
CharSequence label, int labelResId, Icon icon, Icon iconStandby, Icon iconDisconnected,
- String setupActivity, boolean canRecord, int tunerCount, HdmiDeviceInfo hdmiDeviceInfo,
- boolean isConnectedToHdmiSwitch,
+ String setupActivity, boolean canRecord, boolean canPauseRecording, int tunerCount,
+ HdmiDeviceInfo hdmiDeviceInfo, boolean isConnectedToHdmiSwitch,
@HdmiAddressRelativePosition int hdmiConnectionRelativePosition, String parentId,
Bundle extras) {
mService = service;
@@ -279,6 +280,7 @@
mIconDisconnected = iconDisconnected;
mSetupActivity = setupActivity;
mCanRecord = canRecord;
+ mCanPauseRecording = canPauseRecording;
mTunerCount = tunerCount;
mHdmiDeviceInfo = hdmiDeviceInfo;
mIsConnectedToHdmiSwitch = isConnectedToHdmiSwitch;
@@ -386,6 +388,14 @@
}
/**
+ * Returns {@code true} if this TV input can pause recording TV programs,
+ * {@code false} otherwise.
+ */
+ public boolean canPauseRecording() {
+ return mCanPauseRecording;
+ }
+
+ /**
* Returns domain-specific extras associated with this TV input.
*/
public Bundle getExtras() {
@@ -571,6 +581,7 @@
&& Objects.equals(mIconDisconnected, obj.mIconDisconnected)
&& TextUtils.equals(mSetupActivity, obj.mSetupActivity)
&& mCanRecord == obj.mCanRecord
+ && mCanPauseRecording == obj.mCanPauseRecording
&& mTunerCount == obj.mTunerCount
&& Objects.equals(mHdmiDeviceInfo, obj.mHdmiDeviceInfo)
&& mIsConnectedToHdmiSwitch == obj.mIsConnectedToHdmiSwitch
@@ -606,6 +617,7 @@
dest.writeParcelable(mIconDisconnected, flags);
dest.writeString(mSetupActivity);
dest.writeByte(mCanRecord ? (byte) 1 : 0);
+ dest.writeByte(mCanPauseRecording ? (byte) 1 : 0);
dest.writeInt(mTunerCount);
dest.writeParcelable(mHdmiDeviceInfo, flags);
dest.writeByte(mIsConnectedToHdmiSwitch ? (byte) 1 : 0);
@@ -648,6 +660,7 @@
mIconDisconnected = in.readParcelable(null);
mSetupActivity = in.readString();
mCanRecord = in.readByte() == 1;
+ mCanPauseRecording = in.readByte() == 1;
mTunerCount = in.readInt();
mHdmiDeviceInfo = in.readParcelable(null);
mIsConnectedToHdmiSwitch = in.readByte() == 1;
@@ -695,6 +708,7 @@
private Icon mIconDisconnected;
private String mSetupActivity;
private Boolean mCanRecord;
+ private Boolean mCanPauseRecording;
private Integer mTunerCount;
private TvInputHardwareInfo mTvInputHardwareInfo;
private HdmiDeviceInfo mHdmiDeviceInfo;
@@ -879,6 +893,18 @@
}
/**
+ * Sets whether this TV input can pause recording TV programs or not.
+ *
+ * @param canPauseRecording Whether this TV input can pause recording TV programs.
+ * @return This Builder object to allow for chaining of calls to builder methods.
+ */
+ @NonNull
+ public Builder setCanPauseRecording(boolean canPauseRecording) {
+ this.mCanPauseRecording = canPauseRecording;
+ return this;
+ }
+
+ /**
* Sets domain-specific extras associated with this TV input.
*
* @param extras Domain-specific extras associated with this TV input. Keys <em>must</em> be
@@ -927,7 +953,9 @@
parseServiceMetadata(type);
return new TvInputInfo(mResolveInfo, id, type, isHardwareInput, mLabel, mLabelResId,
mIcon, mIconStandby, mIconDisconnected, mSetupActivity,
- mCanRecord == null ? false : mCanRecord, mTunerCount == null ? 0 : mTunerCount,
+ mCanRecord == null ? false : mCanRecord,
+ mCanPauseRecording == null ? false : mCanPauseRecording,
+ mTunerCount == null ? 0 : mTunerCount,
mHdmiDeviceInfo, isConnectedToHdmiSwitch, hdmiConnectionRelativePosition,
mParentId, mExtras);
}
@@ -997,6 +1025,12 @@
mTunerCount = sa.getInt(
com.android.internal.R.styleable.TvInputService_tunerCount, 1);
}
+ if (mCanPauseRecording == null) {
+ mCanPauseRecording = sa.getBoolean(
+ com.android.internal.R.styleable.TvInputService_canPauseRecording,
+ false);
+ }
+
sa.recycle();
} catch (IOException | XmlPullParserException e) {
throw new IllegalStateException("Failed reading meta-data for " + si.packageName, e);
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 98a01a4..6341dc2 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -2476,6 +2476,40 @@
}
/**
+ * Pauses TV program recording in the current recording session.
+ *
+ * @param params A set of extra parameters which might be handled with this event.
+ */
+ void pauseRecording(@NonNull Bundle params) {
+ if (mToken == null) {
+ Log.w(TAG, "The session has been already released");
+ return;
+ }
+ try {
+ mService.pauseRecording(mToken, params, mUserId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Resumes TV program recording in the current recording session.
+ *
+ * @param params A set of extra parameters which might be handled with this event.
+ */
+ void resumeRecording(@NonNull Bundle params) {
+ if (mToken == null) {
+ Log.w(TAG, "The session has been already released");
+ return;
+ }
+ try {
+ mService.resumeRecording(mToken, params, mUserId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Calls {@link TvInputService.Session#appPrivateCommand(String, Bundle)
* TvInputService.Session.appPrivateCommand()} on the current TvView.
*
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index abbf478..0fe9d50 100755
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -1852,6 +1852,28 @@
/**
+ * Called when the application requests to pause TV program recording. Recording must pause
+ * immediately when this method is called.
+ *
+ * If the pause request cannot be fulfilled, the session must call
+ * {@link #notifyError(int)}.
+ *
+ * @param params Domain-specific data for recording request.
+ */
+ public void onPauseRecording(@NonNull Bundle params) { }
+
+ /**
+ * Called when the application requests to resume TV program recording. Recording must
+ * resume immediately when this method is called.
+ *
+ * If the resume request cannot be fulfilled, the session must call
+ * {@link #notifyError(int)}.
+ *
+ * @param params Domain-specific data for recording request.
+ */
+ public void onResumeRecording(@NonNull Bundle params) { }
+
+ /**
* Called when the application requests to release all the resources held by this recording
* session.
*/
@@ -1903,6 +1925,22 @@
}
/**
+ * Calls {@link #onPauseRecording(Bundle)}.
+ *
+ */
+ void pauseRecording(@NonNull Bundle params) {
+ onPauseRecording(params);
+ }
+
+ /**
+ * Calls {@link #onResumeRecording(Bundle)}.
+ *
+ */
+ void resumeRecording(@NonNull Bundle params) {
+ onResumeRecording(params);
+ }
+
+ /**
* Calls {@link #onAppPrivateCommand(String, Bundle)}.
*/
void appPrivateCommand(String action, Bundle data) {
diff --git a/media/java/android/media/tv/TvRecordingClient.java b/media/java/android/media/tv/TvRecordingClient.java
index 23fadac..180e2bd 100644
--- a/media/java/android/media/tv/TvRecordingClient.java
+++ b/media/java/android/media/tv/TvRecordingClient.java
@@ -30,6 +30,7 @@
import android.util.Pair;
import java.util.ArrayDeque;
+import java.util.Objects;
import java.util.Queue;
/**
@@ -49,6 +50,8 @@
private boolean mIsRecordingStarted;
private boolean mIsTuned;
+ private boolean mIsPaused;
+ private boolean mIsRecordingStopping;
private final Queue<Pair<String, Bundle>> mPendingAppPrivateCommands = new ArrayDeque<>();
/**
@@ -113,17 +116,22 @@
if (TextUtils.isEmpty(inputId)) {
throw new IllegalArgumentException("inputId cannot be null or an empty string");
}
- if (mIsRecordingStarted) {
+ if (mIsRecordingStarted && !mIsPaused) {
throw new IllegalStateException("tune failed - recording already started");
}
if (mSessionCallback != null && TextUtils.equals(mSessionCallback.mInputId, inputId)) {
if (mSession != null) {
+ mSessionCallback.mChannelUri = channelUri;
mSession.tune(channelUri, params);
} else {
mSessionCallback.mChannelUri = channelUri;
mSessionCallback.mConnectionParams = params;
}
+ mIsTuned = false;
} else {
+ if (mIsPaused) {
+ throw new IllegalStateException("tune failed - inputId is changed during pause");
+ }
resetInternal();
mSessionCallback = new MySessionCallback(inputId, channelUri, params);
if (mTvInputManager != null) {
@@ -148,6 +156,8 @@
mSession.release();
mIsTuned = false;
mIsRecordingStarted = false;
+ mIsPaused = false;
+ mIsRecordingStopping = false;
mSession = null;
}
}
@@ -169,7 +179,8 @@
*
* @param programUri The URI for the TV program to record, built by
* {@link TvContract#buildProgramUri(long)}. Can be {@code null}.
- * @throws IllegalStateException If {@link #tune} request hasn't been handled yet.
+ * @throws IllegalStateException If {@link #tune} request hasn't been handled yet or during
+ * pause.
*/
public void startRecording(@Nullable Uri programUri) {
startRecording(programUri, Bundle.EMPTY);
@@ -195,11 +206,16 @@
* @param params Domain-specific data for this request. Keys <em>must</em> be a scoped
* name, i.e. prefixed with a package name you own, so that different developers will
* not create conflicting keys.
- * @throws IllegalStateException If {@link #tune} request hasn't been handled yet.
+ * @throws IllegalStateException If {@link #tune} request hasn't been handled yet or during
+ * pause.
*/
public void startRecording(@Nullable Uri programUri, @NonNull Bundle params) {
- if (!mIsTuned) {
- throw new IllegalStateException("startRecording failed - not yet tuned");
+ if (mIsRecordingStopping || !mIsTuned || mIsPaused) {
+ throw new IllegalStateException("startRecording failed -"
+ + "recording not yet stopped or not yet tuned or paused");
+ }
+ if (mIsRecordingStarted) {
+ Log.w(TAG, "startRecording failed - recording already started");
}
if (mSession != null) {
mSession.startRecording(programUri, params);
@@ -225,6 +241,103 @@
}
if (mSession != null) {
mSession.stopRecording();
+ if (mIsRecordingStarted) {
+ mIsRecordingStopping = true;
+ }
+ }
+ }
+
+ /**
+ * Pause TV program recording in the current recording session. Recording is expected to pause
+ * immediately when this method is called. If recording has not yet started in the current
+ * recording session, this method does nothing.
+ *
+ * <p>In pause status, the application can tune during recording. To continue recording,
+ * please call {@link TvRecordingClient#resumeRecording()} to resume instead of
+ * {@link TvRecordingClient#startRecording(Uri)}. Application can stop
+ * the recording with {@link TvRecordingClient#stopRecording()} in recording pause status.
+ *
+ * <p>If the pause request cannot be fulfilled, the recording session will respond by calling
+ * {@link RecordingCallback#onError(int)}.
+ */
+ public void pauseRecording() {
+ pauseRecording(Bundle.EMPTY);
+ }
+
+ /**
+ * Pause TV program recording in the current recording session. Recording is expected to pause
+ * immediately when this method is called. If recording has not yet started in the current
+ * recording session, this method does nothing.
+ *
+ * <p>In pause status, the application can tune during recording. To continue recording,
+ * please call {@link TvRecordingClient#resumeRecording()} to resume instead of
+ * {@link TvRecordingClient#startRecording(Uri)}. Application can stop
+ * the recording with {@link TvRecordingClient#stopRecording()} in recording pause status.
+ *
+ * <p>If the pause request cannot be fulfilled, the recording session will respond by calling
+ * {@link RecordingCallback#onError(int)}.
+ *
+ * @param params Domain-specific data for this request.
+ */
+ public void pauseRecording(@NonNull Bundle params) {
+ if (!mIsRecordingStarted || mIsRecordingStopping) {
+ throw new IllegalStateException(
+ "pauseRecording failed - recording not yet started or stopping");
+ }
+ TvInputInfo info = mTvInputManager.getTvInputInfo(mSessionCallback.mInputId);
+ if (info == null || !info.canPauseRecording()) {
+ throw new UnsupportedOperationException(
+ "pauseRecording failed - operation not supported");
+ }
+ if (mIsPaused) {
+ Log.w(TAG, "pauseRecording failed - recording already paused");
+ }
+ if (mSession != null) {
+ mSession.pauseRecording(params);
+ mIsPaused = true;
+ }
+ }
+
+ /**
+ * Resume TV program recording only in recording pause status in the current recording session.
+ * Recording is expected to resume immediately when this method is called. If recording has not
+ * yet paused in the current recording session, this method does nothing.
+ *
+ * <p>When record is resumed, the recording is continue and can not re-tune. Application can
+ * stop the recording with {@link TvRecordingClient#stopRecording()} after record resumed.
+ *
+ * <p>If the pause request cannot be fulfilled, the recording session will respond by calling
+ * {@link RecordingCallback#onError(int)}.
+ */
+ public void resumeRecording() {
+ resumeRecording(Bundle.EMPTY);
+ }
+
+ /**
+ * Resume TV program recording only in recording pause status in the current recording session.
+ * Recording is expected to resume immediately when this method is called. If recording has not
+ * yet paused in the current recording session, this method does nothing.
+ *
+ * <p>When record is resumed, the recording is continues and can not re-tune. Application can
+ * stop the recording with {@link TvRecordingClient#stopRecording()} after record resumed.
+ *
+ * <p>If the resume request cannot be fulfilled, the recording session will respond by calling
+ * {@link RecordingCallback#onError(int)}.
+ *
+ * @param params Domain-specific data for this request.
+ */
+ public void resumeRecording(@NonNull Bundle params) {
+ if (!mIsRecordingStarted || mIsRecordingStopping || !mIsTuned) {
+ throw new IllegalStateException(
+ "resumeRecording failed - recording not yet started or stopping or "
+ + "not yet tuned");
+ }
+ if (!mIsPaused) {
+ Log.w(TAG, "resumeRecording failed - recording not yet paused");
+ }
+ if (mSession != null) {
+ mSession.resumeRecording(params);
+ mIsPaused = false;
}
}
@@ -367,6 +480,10 @@
Log.w(TAG, "onTuned - session not created");
return;
}
+ if (mIsTuned || !Objects.equals(mChannelUri, channelUri)) {
+ Log.w(TAG, "onTuned - already tuned or not yet tuned to last channel");
+ return;
+ }
mIsTuned = true;
mCallback.onTuned(channelUri);
}
@@ -382,6 +499,8 @@
}
mIsTuned = false;
mIsRecordingStarted = false;
+ mIsPaused = false;
+ mIsRecordingStopping = false;
mSessionCallback = null;
mSession = null;
if (mCallback != null) {
@@ -398,7 +517,13 @@
Log.w(TAG, "onRecordingStopped - session not created");
return;
}
+ if (!mIsRecordingStarted) {
+ Log.w(TAG, "onRecordingStopped - recording not yet started");
+ return;
+ }
mIsRecordingStarted = false;
+ mIsPaused = false;
+ mIsRecordingStopping = false;
mCallback.onRecordingStopped(recordedProgramUri);
}
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index c63cf06..2b5e9cd 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -291,7 +291,7 @@
<item>256K</item>
<item>1M</item>
<item>4M</item>
- <item>16M</item>
+ <item>8M</item>
</string-array>
<!-- Titles for logd limit size lowram selection preference. [CHAR LIMIT=14] -->
@@ -309,7 +309,7 @@
<item>262144</item>
<item>1048576</item>
<item>4194304</item>
- <item>16777216</item>
+ <item>8388608</item>
</string-array>
<!-- Summaries for logd limit size selection preference. [CHAR LIMIT=50]-->
@@ -319,7 +319,7 @@
<item>256K per log buffer</item>
<item>1M per log buffer</item>
<item>4M per log buffer</item>
- <item>16M per log buffer</item>
+ <item>8M per log buffer</item>
</string-array>
<!-- Values for logpersist state selection preference. -->
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 741a680..4b6862c 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -156,6 +156,7 @@
<uses-permission android:name="android.permission.MANAGE_CONTENT_SUGGESTIONS" />
<uses-permission android:name="android.permission.MANAGE_APP_PREDICTIONS" />
<uses-permission android:name="android.permission.MANAGE_SEARCH_UI" />
+ <uses-permission android:name="android.permission.MANAGE_SMARTSPACE" />
<uses-permission android:name="android.permission.NETWORK_SETTINGS" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.SET_TIME" />
@@ -345,6 +346,9 @@
<uses-permission android:name="android.permission.WIFI_ACCESS_COEX_UNSAFE_CHANNELS" />
<uses-permission android:name="android.permission.WIFI_UPDATE_COEX_UNSAFE_CHANNELS" />
+ <!-- Permission required for CTS test - CtsSensorPrivacyTestCases -->
+ <uses-permission android:name="android.permission.MANAGE_SENSOR_PRIVACY" />
+
<application android:label="@string/app_label"
android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index 309d4b0..c5a35ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -29,7 +29,6 @@
import android.net.ConnectivityManager.NetworkCallback;
import android.net.IConnectivityManager;
import android.net.Network;
-import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.os.Handler;
import android.os.RemoteException;
@@ -66,12 +65,8 @@
private static final String TAG = "SecurityController";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private static final NetworkRequest REQUEST = new NetworkRequest.Builder()
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
- .setUids(null)
- .build();
+ private static final NetworkRequest REQUEST =
+ new NetworkRequest.Builder().clearCapabilities().build();
private static final int NO_NETWORK = -1;
private static final String VPN_BRANDED_META_DATA = "com.android.systemui.IS_BRANDED";
diff --git a/packages/services/CameraExtensionsProxy/OWNERS b/packages/services/CameraExtensionsProxy/OWNERS
new file mode 100644
index 0000000..f48a95c
--- /dev/null
+++ b/packages/services/CameraExtensionsProxy/OWNERS
@@ -0,0 +1 @@
+include platform/frameworks/av:/camera/OWNERS
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 5f6e8df..5560f81 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.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.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.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 @@
int callerUid;
int callerPid;
- int events;
+ Set<Integer> 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 @@
+ onSubscriptionsChangedListenerCallback
+ " onOpportunisticSubscriptionsChangedListenererCallback="
+ onOpportunisticSubscriptionsChangedListenerCallback + " subId=" + subId
- + " phoneId=" + phoneId + " events=" + Integer.toHexString(events) + "}";
+ + " phoneId=" + phoneId + " events=" + eventList + "}";
}
}
@@ -306,6 +311,12 @@
private final LocalLog mListenLog = new LocalLog(200);
+ private List<PhysicalChannelConfig> 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 @@
private List<Map<Pair<Integer, ApnSetting>, 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<Integer> REQUIRE_PRECISE_PHONE_STATE_PERMISSION;
+ static {
+ REQUIRE_PRECISE_PHONE_STATE_PERMISSION = new HashSet<Integer>();
+ 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<Integer> 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<Integer> 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<Integer> 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<Integer> events) {
+ return events.contains(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_CALL)
+ || events.contains(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_SMS);
+ }
+
+ private boolean isPrivilegedPhoneStatePermissionRequired(Set<Integer> 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 @@
cutListToSize(mImsReasonInfo, mNumPhones);
cutListToSize(mPreciseDataConnectionStates, mNumPhones);
cutListToSize(mBarringInfo, mNumPhones);
+ cutListToSize(mPhysicalChannelConfigs, mNumPhones);
return;
}
@@ -528,6 +563,7 @@
mPreciseDataConnectionStates.add(new ArrayMap<>());
mBarringInfo.add(i, new BarringInfo());
mTelephonyDisplayInfos[i] = null;
+ mPhysicalChannelConfigs.add(i, new PhysicalChannelConfig.Builder().build());
}
}
@@ -588,6 +624,7 @@
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 @@
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 @@
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 @@
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 @@
}
}
- @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<Integer> 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<Integer> 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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
}
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
}
+ /**
+ * 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<PhysicalChannelConfig> 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 @@
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 @@
== PackageManager.PERMISSION_GRANTED;
}
- private boolean checkListenerPermission(int events, int subId, String callingPackage,
+ private boolean checkListenerPermission(Set<Integer> 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 @@
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 @@
}
}
- 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 @@
}
}
+ /**
+ * 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 @@
});
}
+ /**
+ * 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 @@
}
private void checkPossibleMissNotify(Record r, int phoneId) {
- int events = r.events;
+ Set<Integer> 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 @@
}
}
- 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 @@
}
}
- 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 @@
}
}
- 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 @@
}
}
- 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 @@
}
}
- 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 @@
}
}
- 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 @@
}
}
- 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 @@
}
}
- 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 @@
}
}
- 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/services/core/java/com/android/server/connectivity/PacProxyInstaller.java b/services/core/java/com/android/server/connectivity/PacProxyInstaller.java
index aadaf4d..5dc8c1a 100644
--- a/services/core/java/com/android/server/connectivity/PacProxyInstaller.java
+++ b/services/core/java/com/android/server/connectivity/PacProxyInstaller.java
@@ -16,6 +16,7 @@
package com.android.server.connectivity;
+import android.annotation.NonNull;
import android.annotation.WorkerThread;
import android.app.AlarmManager;
import android.app.PendingIntent;
@@ -71,10 +72,6 @@
private static final int DELAY_LONG = 4;
private static final long MAX_PAC_SIZE = 20 * 1000 * 1000;
- // Return values for #setCurrentProxyScriptUrl
- public static final boolean DONT_SEND_BROADCAST = false;
- public static final boolean DO_SEND_BROADCAST = true;
-
private String mCurrentPac;
@GuardedBy("mProxyLock")
private volatile Uri mPacUrl = Uri.EMPTY;
@@ -93,7 +90,7 @@
private volatile boolean mHasSentBroadcast;
private volatile boolean mHasDownloaded;
- private Handler mConnectivityHandler;
+ private final Handler mConnectivityHandler;
private final int mProxyMessage;
/**
@@ -102,6 +99,13 @@
private final Object mProxyLock = new Object();
/**
+ * Lock ensuring consistency between the values of mHasSentBroadcast, mHasDownloaded, the
+ * last URL and port, and the broadcast message being sent with the correct arguments.
+ * TODO : this should probably protect all instances of these variables
+ */
+ private final Object mBroadcastStateLock = new Object();
+
+ /**
* Runnable to download PAC script.
* The behavior relies on the assumption it always runs on mNetThread to guarantee that the
* latest data fetched from mPacUrl is stored in mProxyService.
@@ -146,7 +150,7 @@
}
}
- public PacProxyInstaller(Context context, Handler handler, int proxyMessage) {
+ public PacProxyInstaller(@NonNull Context context, @NonNull Handler handler, int proxyMessage) {
mContext = context;
mLastPort = -1;
final HandlerThread netThread = new HandlerThread("android.pacproxyinstaller",
@@ -176,31 +180,27 @@
* PacProxyInstaller will trigger a new broadcast when it is ready.
*
* @param proxy Proxy information that is about to be broadcast.
- * @return Returns whether the broadcast should be sent : either DO_ or DONT_SEND_BROADCAST
*/
- public synchronized boolean setCurrentProxyScriptUrl(ProxyInfo proxy) {
- if (!Uri.EMPTY.equals(proxy.getPacFileUrl())) {
- if (proxy.getPacFileUrl().equals(mPacUrl) && (proxy.getPort() > 0)) {
- // Allow to send broadcast, nothing to do.
- return DO_SEND_BROADCAST;
- }
- mPacUrl = proxy.getPacFileUrl();
- mCurrentDelay = DELAY_1;
- mHasSentBroadcast = false;
- mHasDownloaded = false;
- getAlarmManager().cancel(mPacRefreshIntent);
- bind();
- return DONT_SEND_BROADCAST;
- } else {
- getAlarmManager().cancel(mPacRefreshIntent);
- synchronized (mProxyLock) {
- mPacUrl = Uri.EMPTY;
- mCurrentPac = null;
- if (mProxyService != null) {
- unbind();
+ public void setCurrentProxyScriptUrl(@NonNull ProxyInfo proxy) {
+ synchronized (mBroadcastStateLock) {
+ if (!Uri.EMPTY.equals(proxy.getPacFileUrl())) {
+ if (proxy.getPacFileUrl().equals(mPacUrl) && (proxy.getPort() > 0)) return;
+ mPacUrl = proxy.getPacFileUrl();
+ mCurrentDelay = DELAY_1;
+ mHasSentBroadcast = false;
+ mHasDownloaded = false;
+ getAlarmManager().cancel(mPacRefreshIntent);
+ bind();
+ } else {
+ getAlarmManager().cancel(mPacRefreshIntent);
+ synchronized (mProxyLock) {
+ mPacUrl = Uri.EMPTY;
+ mCurrentPac = null;
+ if (mProxyService != null) {
+ unbind();
+ }
}
}
- return DO_SEND_BROADCAST;
}
}
@@ -275,6 +275,7 @@
getAlarmManager().set(AlarmManager.ELAPSED_REALTIME, timeTillTrigger, mPacRefreshIntent);
}
+ @GuardedBy("mProxyLock")
private void setCurrentProxyScript(String script) {
if (mProxyService == null) {
Log.e(TAG, "setCurrentProxyScript: no proxy service");
@@ -347,6 +348,9 @@
public void setProxyPort(int port) {
if (mLastPort != -1) {
// Always need to send if port changed
+ // TODO: Here lacks synchronization because this write cannot
+ // guarantee that it's visible from sendProxyIfNeeded() when
+ // it's called by a Runnable which is post by mNetThread.
mHasSentBroadcast = false;
}
mLastPort = port;
@@ -386,13 +390,15 @@
mConnectivityHandler.sendMessage(mConnectivityHandler.obtainMessage(mProxyMessage, proxy));
}
- private synchronized void sendProxyIfNeeded() {
- if (!mHasDownloaded || (mLastPort == -1)) {
- return;
- }
- if (!mHasSentBroadcast) {
- sendPacBroadcast(ProxyInfo.buildPacProxy(mPacUrl, mLastPort));
- mHasSentBroadcast = true;
+ private void sendProxyIfNeeded() {
+ synchronized (mBroadcastStateLock) {
+ if (!mHasDownloaded || (mLastPort == -1)) {
+ return;
+ }
+ if (!mHasSentBroadcast) {
+ sendPacBroadcast(ProxyInfo.buildPacProxy(mPacUrl, mLastPort));
+ mHasSentBroadcast = true;
+ }
}
}
}
diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java
index d83ff83..b618d2b 100644
--- a/services/core/java/com/android/server/connectivity/ProxyTracker.java
+++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java
@@ -226,9 +226,9 @@
final ProxyInfo defaultProxy = getDefaultProxy();
final ProxyInfo proxyInfo = null != defaultProxy ?
defaultProxy : ProxyInfo.buildDirectProxy("", 0, Collections.emptyList());
+ mPacProxyInstaller.setCurrentProxyScriptUrl(proxyInfo);
- if (mPacProxyInstaller.setCurrentProxyScriptUrl(proxyInfo)
- == PacProxyInstaller.DONT_SEND_BROADCAST) {
+ if (!shouldSendBroadcast(proxyInfo)) {
return;
}
if (DBG) Log.d(TAG, "sending Proxy Broadcast for " + proxyInfo);
@@ -244,6 +244,13 @@
}
}
+ private boolean shouldSendBroadcast(ProxyInfo proxy) {
+ if (Uri.EMPTY.equals(proxy.getPacFileUrl())) return false;
+ if (proxy.getPacFileUrl().equals(proxy.getPacFileUrl())
+ && (proxy.getPort() > 0)) return true;
+ return true;
+ }
+
/**
* Sets the global proxy in memory. Also writes the values to the global settings of the device.
*
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
index 289290b..fbec915 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
@@ -224,6 +224,10 @@
for (UserInfo user : rebootEscrowUsers) {
allUsersUnlocked &= restoreRebootEscrowForUser(user.id, escrowKey, kk);
}
+
+ // Clear the old key in keystore. A new key will be generated by new RoR requests.
+ mKeyStoreManager.clearKeyStoreEncryptionKey();
+
onEscrowRestoreComplete(allUsersUnlocked);
}
@@ -273,9 +277,6 @@
} catch (IOException e) {
Slog.w(TAG, "Could not load reboot escrow data for user " + userId, e);
return false;
- } finally {
- // Clear the old key in keystore. A new key will be generated by new RoR requests.
- mKeyStoreManager.clearKeyStoreEncryptionKey();
}
}
diff --git a/services/core/java/com/android/server/tv/TvInputHal.java b/services/core/java/com/android/server/tv/TvInputHal.java
index 42f12eb..0772503 100644
--- a/services/core/java/com/android/server/tv/TvInputHal.java
+++ b/services/core/java/com/android/server/tv/TvInputHal.java
@@ -51,7 +51,8 @@
public interface Callback {
void onDeviceAvailable(TvInputHardwareInfo info, TvStreamConfig[] configs);
void onDeviceUnavailable(int deviceId);
- void onStreamConfigurationChanged(int deviceId, TvStreamConfig[] configs);
+ void onStreamConfigurationChanged(int deviceId, TvStreamConfig[] configs,
+ int cableConnectionStatus);
void onFirstFrameCaptured(int deviceId, int streamId);
}
@@ -142,8 +143,9 @@
mHandler.obtainMessage(EVENT_DEVICE_UNAVAILABLE, deviceId, 0).sendToTarget();
}
- private void streamConfigsChangedFromNative(int deviceId) {
- mHandler.obtainMessage(EVENT_STREAM_CONFIGURATION_CHANGED, deviceId, 0).sendToTarget();
+ private void streamConfigsChangedFromNative(int deviceId, int cableConnectionStatus) {
+ mHandler.obtainMessage(EVENT_STREAM_CONFIGURATION_CHANGED, deviceId,
+ cableConnectionStatus).sendToTarget();
}
private void firstFrameCapturedFromNative(int deviceId, int streamId) {
@@ -184,6 +186,7 @@
case EVENT_STREAM_CONFIGURATION_CHANGED: {
TvStreamConfig[] configs;
int deviceId = msg.arg1;
+ int cableConnectionStatus = msg.arg2;
synchronized (mLock) {
if (DEBUG) {
Slog.d(TAG, "EVENT_STREAM_CONFIGURATION_CHANGED: deviceId = " + deviceId);
@@ -191,7 +194,7 @@
retrieveStreamConfigsLocked(deviceId);
configs = mStreamConfigs.get(deviceId);
}
- mCallback.onStreamConfigurationChanged(deviceId, configs);
+ mCallback.onStreamConfigurationChanged(deviceId, configs, cableConnectionStatus);
break;
}
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 2314afc..3dfb99e 100755
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -156,6 +156,7 @@
synchronized (mLock) {
Connection connection = new Connection(info);
connection.updateConfigsLocked(configs);
+ connection.updateCableConnectionStatusLocked(info.getCableConnectionStatus());
mConnections.put(info.getDeviceId(), connection);
buildHardwareListLocked();
mHandler.obtainMessage(
@@ -202,7 +203,8 @@
}
@Override
- public void onStreamConfigurationChanged(int deviceId, TvStreamConfig[] configs) {
+ public void onStreamConfigurationChanged(int deviceId, TvStreamConfig[] configs,
+ int cableConnectionStatus) {
synchronized (mLock) {
Connection connection = mConnections.get(deviceId);
if (connection == null) {
@@ -211,12 +213,22 @@
return;
}
int previousConfigsLength = connection.getConfigsLengthLocked();
+ int previousCableConnectionStatus = connection.getInputStateLocked();
connection.updateConfigsLocked(configs);
String inputId = mHardwareInputIdMap.get(deviceId);
- if (inputId != null
- && (previousConfigsLength == 0) != (connection.getConfigsLengthLocked() == 0)) {
- mHandler.obtainMessage(ListenerHandler.STATE_CHANGED,
- connection.getInputStateLocked(), 0, inputId).sendToTarget();
+ if (inputId != null) {
+ if (connection.updateCableConnectionStatusLocked(cableConnectionStatus)) {
+ if (previousCableConnectionStatus != connection.getInputStateLocked()) {
+ mHandler.obtainMessage(ListenerHandler.STATE_CHANGED,
+ connection.getInputStateLocked(), 0, inputId).sendToTarget();
+ }
+ } else {
+ if ((previousConfigsLength == 0)
+ != (connection.getConfigsLengthLocked() == 0)) {
+ mHandler.obtainMessage(ListenerHandler.STATE_CHANGED,
+ connection.getInputStateLocked(), 0, inputId).sendToTarget();
+ }
+ }
}
ITvInputHardwareCallback callback = connection.getCallbackLocked();
if (callback != null) {
@@ -624,7 +636,7 @@
}
private class Connection implements IBinder.DeathRecipient {
- private final TvInputHardwareInfo mHardwareInfo;
+ private TvInputHardwareInfo mHardwareInfo;
private TvInputInfo mInfo;
private TvInputHardwareImpl mHardware = null;
private ITvInputHardwareCallback mCallback;
@@ -633,6 +645,7 @@
private Integer mResolvedUserId = null;
private Runnable mOnFirstFrameCaptured;
private ResourceClientProfile mResourceClientProfile = null;
+ private boolean mIsCableConnectionStatusUpdated = false;
public Connection(TvInputHardwareInfo hardwareInfo) {
mHardwareInfo = hardwareInfo;
@@ -735,6 +748,17 @@
+ " }";
}
+ public boolean updateCableConnectionStatusLocked(int cableConnectionStatus) {
+ // Update connection status only if it's not default value
+ if (cableConnectionStatus != TvInputHardwareInfo.CABLE_CONNECTION_STATUS_UNKNOWN
+ || mIsCableConnectionStatusUpdated) {
+ mIsCableConnectionStatusUpdated = true;
+ mHardwareInfo = mHardwareInfo.toBuilder()
+ .cableConnectionStatus(cableConnectionStatus).build();
+ }
+ return mIsCableConnectionStatusUpdated;
+ }
+
private int getConfigsLengthLocked() {
return mConfigs == null ? 0 : mConfigs.length;
}
@@ -742,7 +766,9 @@
private int getInputStateLocked() {
int configsLength = getConfigsLengthLocked();
if (configsLength > 0) {
- return INPUT_STATE_CONNECTED;
+ if (!mIsCableConnectionStatusUpdated) {
+ return INPUT_STATE_CONNECTED;
+ }
}
switch (mHardwareInfo.getCableConnectionStatus()) {
case TvInputHardwareInfo.CABLE_CONNECTION_STATUS_CONNECTED:
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 6cd0258..d858ae4 100755
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -20,6 +20,7 @@
import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED;
import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED_STANDBY;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.BroadcastReceiver;
@@ -1728,6 +1729,46 @@
}
@Override
+ public void pauseRecording(IBinder sessionToken, @NonNull Bundle params, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
+ userId, "pauseRecording");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ try {
+ getSessionLocked(sessionToken, callingUid, resolvedUserId)
+ .pauseRecording(params);
+ } catch (RemoteException | SessionNotFoundException e) {
+ Slog.e(TAG, "error in pauseRecording", e);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void resumeRecording(IBinder sessionToken, @NonNull Bundle params, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
+ userId, "resumeRecording");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ try {
+ getSessionLocked(sessionToken, callingUid, resolvedUserId)
+ .resumeRecording(params);
+ } catch (RemoteException | SessionNotFoundException e) {
+ Slog.e(TAG, "error in resumeRecording", e);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
public List<TvInputHardwareInfo> getHardwareList() throws RemoteException {
if (mContext.checkCallingPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
!= PackageManager.PERMISSION_GRANTED) {
diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp
index 4e1a234..a5311f3 100644
--- a/services/core/jni/com_android_server_tv_TvInputHal.cpp
+++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp
@@ -261,7 +261,7 @@
void onDeviceAvailable(const TvInputDeviceInfo& info);
void onDeviceUnavailable(int deviceId);
- void onStreamConfigurationsChanged(int deviceId);
+ void onStreamConfigurationsChanged(int deviceId, int cableConnectionStatus);
void onCaptured(int deviceId, int streamId, uint32_t seq, bool succeeded);
private:
@@ -519,7 +519,7 @@
deviceId);
}
-void JTvInputHal::onStreamConfigurationsChanged(int deviceId) {
+void JTvInputHal::onStreamConfigurationsChanged(int deviceId, int cableConnectionStatus) {
{
Mutex::Autolock autoLock(&mLock);
KeyedVector<int, Connection>& connections = mConnections.editValueFor(deviceId);
@@ -529,10 +529,8 @@
connections.clear();
}
JNIEnv* env = AndroidRuntime::getJNIEnv();
- env->CallVoidMethod(
- mThiz,
- gTvInputHalClassInfo.streamConfigsChanged,
- deviceId);
+ env->CallVoidMethod(mThiz, gTvInputHalClassInfo.streamConfigsChanged, deviceId,
+ cableConnectionStatus);
}
void JTvInputHal::onCaptured(int deviceId, int streamId, uint32_t seq, bool succeeded) {
@@ -572,7 +570,8 @@
mHal->onDeviceUnavailable(mEvent.deviceInfo.deviceId);
} break;
case TvInputEventType::STREAM_CONFIGURATIONS_CHANGED: {
- mHal->onStreamConfigurationsChanged(mEvent.deviceInfo.deviceId);
+ int cableConnectionStatus = static_cast<int>(mEvent.deviceInfo.cableConnectionStatus);
+ mHal->onStreamConfigurationsChanged(mEvent.deviceInfo.deviceId, cableConnectionStatus);
} break;
default:
ALOGE("Unrecognizable event");
@@ -688,9 +687,8 @@
"deviceAvailableFromNative", "(Landroid/media/tv/TvInputHardwareInfo;)V");
GET_METHOD_ID(
gTvInputHalClassInfo.deviceUnavailable, clazz, "deviceUnavailableFromNative", "(I)V");
- GET_METHOD_ID(
- gTvInputHalClassInfo.streamConfigsChanged, clazz,
- "streamConfigsChangedFromNative", "(I)V");
+ GET_METHOD_ID(gTvInputHalClassInfo.streamConfigsChanged, clazz,
+ "streamConfigsChangedFromNative", "(II)V");
GET_METHOD_ID(
gTvInputHalClassInfo.firstFrameCaptured, clazz,
"firstFrameCapturedFromNative", "(II)V");
diff --git a/services/searchui/OWNERS b/services/searchui/OWNERS
new file mode 100644
index 0000000..92835c2
--- /dev/null
+++ b/services/searchui/OWNERS
@@ -0,0 +1,2 @@
+hyunyoungs@google.com
+sfufa@google.com
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 724a9e4..e55720c 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -109,6 +109,20 @@
*/
public abstract class Connection extends Conferenceable {
+ /**@hide*/
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "STATE_", value = {
+ STATE_INITIALIZING,
+ STATE_NEW,
+ STATE_RINGING,
+ STATE_DIALING,
+ STATE_ACTIVE,
+ STATE_HOLDING,
+ STATE_DISCONNECTED,
+ STATE_PULLING_CALL
+ })
+ public @interface ConnectionState {}
+
/**
* The connection is initializing. This is generally the first state for a {@code Connection}
* returned by a {@link ConnectionService}.
diff --git a/telephony/common/com/android/internal/telephony/SipMessageParsingUtils.java b/telephony/common/com/android/internal/telephony/SipMessageParsingUtils.java
new file mode 100644
index 0000000..c7e7cd5
--- /dev/null
+++ b/telephony/common/com/android/internal/telephony/SipMessageParsingUtils.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import android.net.Uri;
+import android.util.Log;
+import android.util.Pair;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Utility methods for parsing parts of {@link android.telephony.ims.SipMessage}s.
+ * See RFC 3261 for more information.
+ * @hide
+ */
+// Note: This is lightweight in order to avoid a full SIP stack import in frameworks/base.
+public class SipMessageParsingUtils {
+ private static final String TAG = "SipMessageParsingUtils";
+ // "Method" in request-line
+ // Request-Line = Method SP Request-URI SP SIP-Version CRLF
+ private static final String[] SIP_REQUEST_METHODS = new String[] {"INVITE", "ACK", "OPTIONS",
+ "BYE", "CANCEL", "REGISTER", "PRACK", "SUBSCRIBE", "NOTIFY", "PUBLISH", "INFO", "REFER",
+ "MESSAGE", "UPDATE"};
+
+ // SIP Version 2.0 (corresponding to RCS 3261), set in "SIP-Version" of Status-Line and
+ // Request-Line
+ //
+ // Request-Line = Method SP Request-URI SP SIP-Version CRLF
+ // Status-Line = SIP-Version SP Status-Code SP Reason-Phrase CRLF
+ private static final String SIP_VERSION_2 = "SIP/2.0";
+
+ // headers are formatted Key:Value
+ private static final String HEADER_KEY_VALUE_SEPARATOR = ":";
+ // Multiple of the same header can be concatenated and put into one header Key:Value pair, for
+ // example "v: XX1;branch=YY1,XX2;branch=YY2". This needs to be treated as two "v:" headers.
+ private static final String SUBHEADER_VALUE_SEPARATOR = ",";
+
+ // SIP header parameters have the format ";paramName=paramValue"
+ private static final String PARAM_SEPARATOR = ";";
+ // parameters are formatted paramName=ParamValue
+ private static final String PARAM_KEY_VALUE_SEPARATOR = "=";
+
+ // The via branch parameter definition
+ private static final String BRANCH_PARAM_KEY = "branch";
+
+ // via header key
+ private static final String VIA_SIP_HEADER_KEY = "via";
+ // compact form of the via header key
+ private static final String VIA_SIP_HEADER_KEY_COMPACT = "v";
+
+ /**
+ * @return true if the SIP message start line is considered a request (based on known request
+ * methods).
+ */
+ public static boolean isSipRequest(String startLine) {
+ String[] splitLine = splitStartLineAndVerify(startLine);
+ if (splitLine == null) return false;
+ return verifySipRequest(splitLine);
+ }
+
+ /**
+ * Return the via branch parameter, which is used to identify the transaction ID (request and
+ * response pair) in a SIP transaction.
+ * @param headerString The string containing the headers of the SIP message.
+ */
+ public static String getTransactionId(String headerString) {
+ // search for Via: or v: parameter, we only care about the first one.
+ List<Pair<String, String>> headers = parseHeaders(headerString, true,
+ VIA_SIP_HEADER_KEY, VIA_SIP_HEADER_KEY_COMPACT);
+ for (Pair<String, String> header : headers) {
+ // Headers can also be concatenated together using a "," between each header value.
+ // format becomes v: XX1;branch=YY1,XX2;branch=YY2. Need to extract only the first ID's
+ // branch param YY1.
+ String[] subHeaders = header.second.split(SUBHEADER_VALUE_SEPARATOR);
+ for (String subHeader : subHeaders) {
+ // Search for ;branch=z9hG4bKXXXXXX and return parameter value
+ String[] params = subHeader.split(PARAM_SEPARATOR);
+ if (params.length < 2) {
+ // This param doesn't include a branch param, move to next param.
+ Log.w(TAG, "getTransactionId: via detected without branch param:"
+ + subHeader);
+ continue;
+ }
+ // by spec, each param can only appear once in a header.
+ for (String param : params) {
+ String[] pair = param.split(PARAM_KEY_VALUE_SEPARATOR);
+ if (pair.length < 2) {
+ // ignore info before the first parameter
+ continue;
+ }
+ if (pair.length > 2) {
+ Log.w(TAG,
+ "getTransactionId: unexpected parameter" + Arrays.toString(pair));
+ }
+ // Trim whitespace in parameter
+ pair[0] = pair[0].trim();
+ pair[1] = pair[1].trim();
+ if (BRANCH_PARAM_KEY.equalsIgnoreCase(pair[0])) {
+ // There can be multiple "Via" headers in the SIP message, however we want
+ // to return the first once found, as this corresponds with the transaction
+ // that is relevant here.
+ return pair[1];
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private static String[] splitStartLineAndVerify(String startLine) {
+ String[] splitLine = startLine.split(" ");
+ if (isStartLineMalformed(splitLine)) return null;
+ return splitLine;
+ }
+
+ private static boolean isStartLineMalformed(String[] startLine) {
+ if (startLine == null || startLine.length == 0) {
+ return true;
+ }
+ // start lines contain three segments separated by spaces (SP):
+ // Request-Line = Method SP Request-URI SP SIP-Version CRLF
+ // Status-Line = SIP-Version SP Status-Code SP Reason-Phrase CRLF
+ return (startLine.length != 3);
+ }
+
+ private static boolean verifySipRequest(String[] request) {
+ // Request-Line = Method SP Request-URI SP SIP-Version CRLF
+ boolean verified = request[2].contains(SIP_VERSION_2);
+ verified &= (Uri.parse(request[1]).getScheme() != null);
+ verified &= Arrays.stream(SIP_REQUEST_METHODS).anyMatch(s -> request[0].contains(s));
+ return verified;
+ }
+
+ private static boolean verifySipResponse(String[] response) {
+ // Status-Line = SIP-Version SP Status-Code SP Reason-Phrase CRLF
+ boolean verified = response[0].contains(SIP_VERSION_2);
+ int statusCode = Integer.parseInt(response[1]);
+ verified &= (statusCode >= 100 && statusCode < 700);
+ return verified;
+ }
+
+ /**
+ * Parse a String representation of the Header portion of the SIP Message and re-structure it
+ * into a List of key->value pairs representing each header in the order that they appeared in
+ * the message.
+ *
+ * @param headerString The raw string containing all headers
+ * @param stopAtFirstMatch Return early when the first match is found from matching header keys.
+ * @param matchingHeaderKeys An optional list of Strings containing header keys that should be
+ * returned if they exist. If none exist, all keys will be returned.
+ * (This is internally an equalsIgnoreMatch comparison).
+ * @return the matched header keys and values.
+ */
+ private static List<Pair<String, String>> parseHeaders(String headerString,
+ boolean stopAtFirstMatch, String... matchingHeaderKeys) {
+ // Ensure there is no leading whitespace
+ headerString = removeLeadingWhitespace(headerString);
+
+ List<Pair<String, String>> result = new ArrayList<>();
+ // Split the string line-by-line.
+ String[] headerLines = headerString.split("\\r?\\n");
+ if (headerLines.length == 0) {
+ return Collections.emptyList();
+ }
+
+ String headerKey = null;
+ StringBuilder headerValueSegment = new StringBuilder();
+ // loop through each line, either parsing a "key: value" pair or appending values that span
+ // multiple lines.
+ for (String line : headerLines) {
+ // This line is a continuation of the last line if it starts with whitespace or tab
+ if (line.startsWith("\t") || line.startsWith(" ")) {
+ headerValueSegment.append(removeLeadingWhitespace(line));
+ continue;
+ }
+ // This line is the start of a new key, If headerKey/value is already populated from a
+ // previous key/value pair, add it to list of parsed header pairs.
+ if (headerKey != null) {
+ final String key = headerKey;
+ if (matchingHeaderKeys == null || matchingHeaderKeys.length == 0
+ || Arrays.stream(matchingHeaderKeys).anyMatch(
+ (s) -> s.equalsIgnoreCase(key))) {
+ result.add(new Pair<>(key, headerValueSegment.toString()));
+ if (stopAtFirstMatch) {
+ return result;
+ }
+ }
+ headerKey = null;
+ headerValueSegment = new StringBuilder();
+ }
+
+ // Format is "Key:Value", ignore any ":" after the first.
+ String[] pair = line.split(HEADER_KEY_VALUE_SEPARATOR, 2);
+ if (pair.length < 2) {
+ // malformed line, skip
+ Log.w(TAG, "parseHeaders - received malformed line: " + line);
+ continue;
+ }
+
+ headerKey = pair[0].trim();
+ for (int i = 1; i < pair.length; i++) {
+ headerValueSegment.append(removeLeadingWhitespace(pair[i]));
+ }
+ }
+ // Pick up the last pending header being parsed, if it exists.
+ if (headerKey != null) {
+ final String key = headerKey;
+ if (matchingHeaderKeys == null || matchingHeaderKeys.length == 0
+ || Arrays.stream(matchingHeaderKeys).anyMatch(
+ (s) -> s.equalsIgnoreCase(key))) {
+ result.add(new Pair<>(key, headerValueSegment.toString()));
+ }
+ }
+
+ return result;
+ }
+
+ private static String removeLeadingWhitespace(String line) {
+ return line.replaceFirst("^\\s*", "");
+ }
+}
diff --git a/telephony/java/android/telephony/PhoneCapability.java b/telephony/java/android/telephony/PhoneCapability.java
index b785037..6571858 100644
--- a/telephony/java/android/telephony/PhoneCapability.java
+++ b/telephony/java/android/telephony/PhoneCapability.java
@@ -28,8 +28,6 @@
/**
* 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/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index ed09d53..1273aa3a 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -478,7 +478,9 @@
/**
* Compare phone numbers a and b, return true if they're identical enough for caller ID purposes.
+ * @deprecated use {@link #areSamePhoneNumber(String, String, String)} instead
*/
+ @Deprecated
public static boolean compare(String a, String b) {
// We've used loose comparation at least Eclair, which may change in the future.
@@ -489,7 +491,9 @@
* Compare phone numbers a and b, and return true if they're identical
* enough for caller ID purposes. Checks a resource to determine whether
* to use a strict or loose comparison algorithm.
+ * @deprecated use {@link #areSamePhoneNumber(String, String, String)} instead
*/
+ @Deprecated
public static boolean compare(Context context, String a, String b) {
boolean useStrict = context.getResources().getBoolean(
com.android.internal.R.bool.config_use_strict_phone_number_comparation);
@@ -3218,7 +3222,7 @@
}
// The conversion map is not defined (this is default). Skip conversion.
- if (sConvertToEmergencyMap == null || sConvertToEmergencyMap.length == 0 ) {
+ if (sConvertToEmergencyMap == null || sConvertToEmergencyMap.length == 0) {
return number;
}
@@ -3254,4 +3258,47 @@
}
return number;
}
+
+ /**
+ * Determines if two phone numbers are the same.
+ * <p>
+ * Matching is based on <a href="https://github.com/google/libphonenumber>libphonenumber</a>.
+ * Unlike {@link #compare(String, String)}, matching takes into account national
+ * dialing plans rather than simply matching the last 7 digits of the two phone numbers. As a
+ * result, it is expected that some numbers which would match using the previous method will no
+ * longer match using this new approach.
+ *
+ * @param number1
+ * @param number2
+ * @param defaultCountryIso The lowercase two letter ISO 3166-1 country code. Used when parsing
+ * the phone numbers where it is not possible to determine the country
+ * associated with a phone number based on the number alone. It
+ * is recommended to pass in
+ * {@link TelephonyManager#getNetworkCountryIso()}.
+ * @return True if the two given phone number are same.
+ */
+ public static boolean areSamePhoneNumber(@NonNull String number1,
+ @NonNull String number2, @NonNull String defaultCountryIso) {
+ PhoneNumberUtil util = PhoneNumberUtil.getInstance();
+ PhoneNumber n1;
+ PhoneNumber n2;
+ defaultCountryIso = defaultCountryIso.toUpperCase();
+ try {
+ n1 = util.parseAndKeepRawInput(number1, defaultCountryIso);
+ n2 = util.parseAndKeepRawInput(number2, defaultCountryIso);
+ } catch (NumberParseException e) {
+ return false;
+ }
+
+ PhoneNumberUtil.MatchType matchType = util.isNumberMatch(n1, n2);
+ if (matchType == PhoneNumberUtil.MatchType.EXACT_MATCH
+ || matchType == PhoneNumberUtil.MatchType.NSN_MATCH) {
+ return true;
+ } else if (matchType == PhoneNumberUtil.MatchType.SHORT_NSN_MATCH) {
+ return (n1.getNationalNumber() == n2.getNationalNumber()
+ && n1.getCountryCode() == n2.getCountryCode());
+ } else {
+ return false;
+ }
+ }
}
diff --git a/telephony/java/android/telephony/PhysicalChannelConfig.java b/telephony/java/android/telephony/PhysicalChannelConfig.java
index af62ba4..327d631 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.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 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 @@
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 @@
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 @@
}
@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 @@
* 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 @@
* @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 @@
/**
* @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 @@
* 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 @@
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 @@
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 @@
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/SignalThresholdInfo.java b/telephony/java/android/telephony/SignalThresholdInfo.java
index 8a472ad..bb9c0da3 100644
--- a/telephony/java/android/telephony/SignalThresholdInfo.java
+++ b/telephony/java/android/telephony/SignalThresholdInfo.java
@@ -28,13 +28,11 @@
/**
* Defines the threshold value of the signal strength.
- * @hide
*/
public final class SignalThresholdInfo implements Parcelable {
/**
* Unknown signal measurement type.
- * @hide
*/
public static final int SIGNAL_MEASUREMENT_TYPE_UNKNOWN = 0;
@@ -44,7 +42,6 @@
* Used RAN: {@link AccessNetworkConstants.AccessNetworkType#GERAN},
* {@link AccessNetworkConstants.AccessNetworkType#CDMA2000}
* Reference: 3GPP TS 27.007 section 8.5.
- * @hide
*/
public static final int SIGNAL_MEASUREMENT_TYPE_RSSI = 1;
@@ -53,7 +50,6 @@
* Range: -120 dBm to -25 dBm;
* Used RAN: {@link AccessNetworkConstants.AccessNetworkType#UTRAN}
* Reference: 3GPP TS 25.123, section 9.1.1.1
- * @hide
*/
public static final int SIGNAL_MEASUREMENT_TYPE_RSCP = 2;
@@ -62,7 +58,6 @@
* Range: -140 dBm to -44 dBm;
* Used RAN: {@link AccessNetworkConstants.AccessNetworkType#EUTRAN}
* Reference: 3GPP TS 36.133 9.1.4
- * @hide
*/
public static final int SIGNAL_MEASUREMENT_TYPE_RSRP = 3;
@@ -71,7 +66,6 @@
* Range: -34 dB to 3 dB;
* Used RAN: {@link AccessNetworkConstants.AccessNetworkType#EUTRAN}
* Reference: 3GPP TS 36.133 9.1.7
- * @hide
*/
public static final int SIGNAL_MEASUREMENT_TYPE_RSRQ = 4;
@@ -79,7 +73,6 @@
* Reference Signal Signal to Noise Ratio
* Range: -20 dB to 30 dB;
* Used RAN: {@link AccessNetworkConstants.AccessNetworkType#EUTRAN}
- * @hide
*/
public static final int SIGNAL_MEASUREMENT_TYPE_RSSNR = 5;
@@ -88,7 +81,6 @@
* Range: -140 dBm to -44 dBm.
* Used RAN: {@link AccessNetworkConstants.AccessNetworkType#NGRAN}
* Reference: 3GPP TS 38.215.
- * @hide
*/
public static final int SIGNAL_MEASUREMENT_TYPE_SSRSRP = 6;
@@ -97,7 +89,6 @@
* Range: -43 dB to 20 dB.
* Used RAN: {@link AccessNetworkConstants.AccessNetworkType#NGRAN}
* Reference: 3GPP TS 38.133 section 10.1.11.1.
- * @hide
*/
public static final int SIGNAL_MEASUREMENT_TYPE_SSRSRQ = 7;
@@ -106,7 +97,6 @@
* Range: -23 dB to 40 dB
* Used RAN: {@link AccessNetworkConstants.AccessNetworkType#NGRAN}
* Reference: 3GPP TS 38.215 section 5.1.*, 3GPP TS 38.133 section 10.1.16.1.
- * @hide
*/
public static final int SIGNAL_MEASUREMENT_TYPE_SSSINR = 8;
@@ -316,8 +306,6 @@
/**
* Builder class to create {@link SignalThresholdInfo} objects.
- *
- * @hide
*/
public static final class Builder {
private int mRan = AccessNetworkConstants.AccessNetworkType.UNKNOWN;
@@ -378,12 +366,22 @@
}
/**
- * Set the signal threshold values of the corresponding signal measurement type.
+ * Set the signal strength thresholds of the corresponding signal measurement type.
*
* The range and unit must reference specific SignalMeasurementType.
*
* @param thresholds array of integer as the signal threshold values
* @return the builder to facilitate the chaining
+ *
+ * @see #SIGNAL_MEASUREMENT_TYPE_RSSI
+ * @see #SIGNAL_MEASUREMENT_TYPE_RSCP
+ * @see #SIGNAL_MEASUREMENT_TYPE_RSRP
+ * @see #SIGNAL_MEASUREMENT_TYPE_RSRQ
+ * @see #SIGNAL_MEASUREMENT_TYPE_RSSNR
+ * @see #SIGNAL_MEASUREMENT_TYPE_SSRSRP
+ * @see #SIGNAL_MEASUREMENT_TYPE_SSRSRQ
+ * @see #SIGNAL_MEASUREMENT_TYPE_SSSINR
+ * @see #getThresholds() for more details on signal strength thresholds
*/
public @NonNull Builder setThresholds(@NonNull int[] thresholds) {
Objects.requireNonNull(thresholds, "thresholds must not be null");
@@ -423,8 +421,6 @@
* Get the radio access network type.
*
* @return radio access network type
- *
- * @hide
*/
public @AccessNetworkConstants.RadioAccessNetworkType int getRadioAccessNetworkType() {
return mRan;
@@ -434,8 +430,6 @@
* Get the signal measurement type.
*
* @return the SignalMeasurementType value
- *
- * @hide
*/
public @SignalMeasurementType int getSignalMeasurementType() {
return mSignalMeasurementType;
@@ -457,11 +451,24 @@
}
/**
- * Get the signal threshold values.
+ * Get the signal strength thresholds.
+ *
+ * Signal strength thresholds are a list of integer used for suggesting signal level and signal
+ * reporting criteria. The range and unit must reference specific SignalMeasurementType.
+ *
+ * Please refer to https://source.android.com/devices/tech/connect/signal-strength on how signal
+ * strength thresholds are used for signal strength reporting.
*
* @return array of integer of the signal thresholds
*
- * @hide
+ * @see #SIGNAL_MEASUREMENT_TYPE_RSSI
+ * @see #SIGNAL_MEASUREMENT_TYPE_RSCP
+ * @see #SIGNAL_MEASUREMENT_TYPE_RSRP
+ * @see #SIGNAL_MEASUREMENT_TYPE_RSRQ
+ * @see #SIGNAL_MEASUREMENT_TYPE_RSSNR
+ * @see #SIGNAL_MEASUREMENT_TYPE_SSRSRP
+ * @see #SIGNAL_MEASUREMENT_TYPE_SSRSRQ
+ * @see #SIGNAL_MEASUREMENT_TYPE_SSSINR
*/
public @NonNull int[] getThresholds() {
return mThresholds.clone();
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c05e90b..f39ee09 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -124,6 +124,7 @@
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 @@
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 @@
//
/**
- * 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.
* <p>
* 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 @@
* values.
* <p>
* 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 <b>must</b>
* call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A
@@ -5596,23 +5599,28 @@
* 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.");
}
}
@@ -8689,11 +8697,18 @@
*/
public static final int CALL_COMPOSER_STATUS_ON = 1;
+ /**
+ * Call composer status indicating that sending/receiving pictures is disabled.
+ * All other attachments are still enabled in this state.
+ */
+ public static final int CALL_COMPOSER_STATUS_ON_NO_PICTURES = 2;
+
/** @hide */
@IntDef(prefix = {"CALL_COMPOSER_STATUS_"},
value = {
CALL_COMPOSER_STATUS_ON,
CALL_COMPOSER_STATUS_OFF,
+ CALL_COMPOSER_STATUS_ON_NO_PICTURES,
})
public @interface CallComposerStatus {}
@@ -8701,8 +8716,9 @@
* Set the user-set status for enriched calling with call composer.
*
* @param status user-set status for enriched calling with call composer;
- * it must be a value of either {@link #CALL_COMPOSER_STATUS_ON}
- * or {@link #CALL_COMPOSER_STATUS_OFF}.
+ * it must be any of {@link #CALL_COMPOSER_STATUS_ON}
+ * {@link #CALL_COMPOSER_STATUS_OFF},
+ * or {@link #CALL_COMPOSER_STATUS_ON_NO_PICTURES}
*
* <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
* given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
@@ -8712,7 +8728,8 @@
*/
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public void setCallComposerStatus(@CallComposerStatus int status) {
- if (status != CALL_COMPOSER_STATUS_ON && status != CALL_COMPOSER_STATUS_OFF) {
+ if (status > CALL_COMPOSER_STATUS_ON_NO_PICTURES
+ || status < CALL_COMPOSER_STATUS_OFF) {
throw new IllegalArgumentException("requested status is invalid");
}
try {
@@ -8734,8 +8751,9 @@
*
* @throws SecurityException if the caller does not have the permission.
*
- * @return the user-set status for enriched calling with call composer either
- * {@link #CALL_COMPOSER_STATUS_ON} or {@link #CALL_COMPOSER_STATUS_OFF}.
+ * @return the user-set status for enriched calling with call composer, any of
+ * {@link #CALL_COMPOSER_STATUS_ON}, {@link #CALL_COMPOSER_STATUS_OFF}, or
+ * {@link #CALL_COMPOSER_STATUS_ON_NO_PICTURES}.
*/
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public @CallComposerStatus int getCallComposerStatus() {
@@ -14583,4 +14601,71 @@
e.execute(() -> callback.onAuthenticationFailure(GBA_FAILURE_REASON_FEATURE_NOT_READY));
}
}
+
+ /**
+ * Registers a listener object to receive notification of changes in specified telephony states.
+ * <p>
+ * 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.
+ * <p>
+ *
+ * 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 <b>must</b>
+ * 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.");
+ }
+ }
}
diff --git a/telephony/java/android/telephony/ims/DelegateRegistrationState.java b/telephony/java/android/telephony/ims/DelegateRegistrationState.java
index 66281ed..fd206c1 100644
--- a/telephony/java/android/telephony/ims/DelegateRegistrationState.java
+++ b/telephony/java/android/telephony/ims/DelegateRegistrationState.java
@@ -320,4 +320,11 @@
public int hashCode() {
return Objects.hash(mRegisteredTags, mDeregisteringTags, mDeregisteredTags);
}
+
+ @Override
+ public String toString() {
+ return "DelegateRegistrationState{ registered={" + mRegisteredTags
+ + "}, deregistering={" + mDeregisteringTags + "}, deregistered={"
+ + mDeregisteredTags + "}}";
+ }
}
diff --git a/telephony/java/android/telephony/ims/SipMessage.java b/telephony/java/android/telephony/ims/SipMessage.java
index 1539224..006cca8 100644
--- a/telephony/java/android/telephony/ims/SipMessage.java
+++ b/telephony/java/android/telephony/ims/SipMessage.java
@@ -22,6 +22,8 @@
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.internal.telephony.SipMessageParsingUtils;
+
import java.util.Arrays;
import java.util.Objects;
@@ -38,9 +40,6 @@
// Should not be set to true for production!
private static final boolean IS_DEBUGGING = Build.IS_ENG;
- private static final String[] SIP_REQUEST_METHODS = new String[] {"INVITE", "ACK", "OPTIONS",
- "BYE", "CANCEL", "REGISTER"};
-
private final String mStartLine;
private final String mHeaderSection;
private final byte[] mContent;
@@ -72,6 +71,7 @@
mContent = new byte[source.readInt()];
source.readByteArray(mContent);
}
+
/**
* @return The start line of the SIP message, which contains either the request-line or
* status-line.
@@ -128,34 +128,25 @@
} else {
b.append(sanitizeStartLineRequest(mStartLine));
}
- b.append("], [");
- b.append("Header: [");
+ b.append("], Header: [");
if (IS_DEBUGGING) {
b.append(mHeaderSection);
} else {
// only identify transaction id/call ID when it is available.
b.append("***");
}
- b.append("], ");
- b.append("Content: [NOT SHOWN]");
+ b.append("], Content: ");
+ b.append(getContent().length == 0 ? "[NONE]" : "[NOT SHOWN]");
return b.toString();
}
/**
- * Start lines containing requests are formatted: METHOD SP Request-URI SP SIP-Version CRLF.
* Detect if this is a REQUEST and redact Request-URI portion here, as it contains PII.
*/
private String sanitizeStartLineRequest(String startLine) {
+ if (!SipMessageParsingUtils.isSipRequest(startLine)) return startLine;
String[] splitLine = startLine.split(" ");
- if (splitLine == null || splitLine.length == 0) {
- return "(INVALID STARTLINE)";
- }
- for (String method : SIP_REQUEST_METHODS) {
- if (splitLine[0].contains(method)) {
- return splitLine[0] + " <Request-URI> " + splitLine[2];
- }
- }
- return startLine;
+ return splitLine[0] + " <Request-URI> " + splitLine[2];
}
@Override
diff --git a/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java
index 522ad81..9d91901 100644
--- a/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java
+++ b/telephony/java/android/telephony/ims/aidl/SipDelegateAidlWrapper.java
@@ -28,6 +28,10 @@
import android.telephony.ims.SipDelegateManager;
import android.telephony.ims.SipMessage;
import android.telephony.ims.stub.SipDelegate;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.telephony.SipMessageParsingUtils;
import java.util.ArrayList;
import java.util.Set;
@@ -40,6 +44,7 @@
* @hide
*/
public class SipDelegateAidlWrapper implements DelegateStateCallback, DelegateMessageCallback {
+ private static final String LOG_TAG = "SipDelegateAW";
private final ISipDelegate.Stub mDelegateBinder = new ISipDelegate.Stub() {
@Override
@@ -183,11 +188,15 @@
}
private void notifyLocalMessageFailedToBeReceived(SipMessage m, int reason) {
- //TODO: parse transaction ID or throw IllegalArgumentException if the SipMessage
- // transaction ID can not be parsed.
+ String transactionId = SipMessageParsingUtils.getTransactionId(m.getHeaderSection());
+ if (TextUtils.isEmpty(transactionId)) {
+ Log.w(LOG_TAG, "failure to parse SipMessage.");
+ throw new IllegalArgumentException("Malformed SipMessage, can not determine "
+ + "transaction ID.");
+ }
SipDelegate d = mDelegate;
if (d != null) {
- mExecutor.execute(() -> d.notifyMessageReceiveError(null, reason));
+ mExecutor.execute(() -> d.notifyMessageReceiveError(transactionId, reason));
}
}
}
diff --git a/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java b/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java
index a35039b..c877aca 100644
--- a/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java
+++ b/telephony/java/android/telephony/ims/aidl/SipDelegateConnectionAidlWrapper.java
@@ -28,9 +28,12 @@
import android.telephony.ims.stub.DelegateConnectionMessageCallback;
import android.telephony.ims.stub.DelegateConnectionStateCallback;
import android.telephony.ims.stub.SipDelegate;
+import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
+import com.android.internal.telephony.SipMessageParsingUtils;
+
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.Executor;
@@ -265,9 +268,13 @@
}
private void notifyLocalMessageFailedToSend(SipMessage m, int reason) {
- //TODO: parse transaction ID or throw IllegalArgumentException if the SipMessage
- // transaction ID can not be parsed.
+ String transactionId = SipMessageParsingUtils.getTransactionId(m.getHeaderSection());
+ if (TextUtils.isEmpty(transactionId)) {
+ Log.w(LOG_TAG, "sendMessage detected a malformed SipMessage and can not get a "
+ + "transaction ID.");
+ throw new IllegalArgumentException("Could not send SipMessage due to malformed header");
+ }
mExecutor.execute(() ->
- mMessageCallback.onMessageSendFailure(null, reason));
+ mMessageCallback.onMessageSendFailure(transactionId, reason));
}
}
diff --git a/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java b/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
index d2cb976..d9734a7 100644
--- a/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
+++ b/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
@@ -18,15 +18,12 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
-import android.net.Uri;
import android.telephony.ims.ImsException;
import android.telephony.ims.RcsContactUceCapability;
import android.telephony.ims.RcsUceAdapter;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.RcsFeature;
-import java.util.List;
-
/**
* The interface of the capabilities event listener for ImsService to notify the framework of the
* UCE request and status updated.
@@ -84,25 +81,4 @@
* Telephony stack has crashed.
*/
void onUnpublish() throws ImsException;
-
- /**
- * Inform the framework of a query for this device's UCE capabilities.
- * <p>
- * The framework will respond via the
- * {@link OptionsRequestCallback#onRespondToCapabilityRequest} or
- * {@link OptionsRequestCallback#onRespondToCapabilityRequestWithError}
- * @param contactUri The URI associated with the remote contact that is
- * requesting capabilities.
- * @param remoteCapabilities The remote contact's capability information.
- * @param callback The callback of this request which is sent from the remote user.
- * @throws ImsException If this {@link RcsCapabilityExchangeImplBase} instance is not
- * currently connected to the framework. This can happen if the {@link RcsFeature} is not
- * {@link ImsFeature#STATE_READY} and the {@link RcsFeature} has not received
- * the {@link ImsFeature#onFeatureReady()} callback. This may also happen in rare
- * cases when the Telephony stack has crashed.
- * @hide
- */
- void onRemoteCapabilityRequest(@NonNull Uri contactUri,
- @NonNull List<String> remoteCapabilities,
- @NonNull OptionsRequestCallback callback) throws ImsException;
}
diff --git a/tests/net/common/java/android/net/CaptivePortalDataTest.kt b/tests/net/common/java/android/net/CaptivePortalDataTest.kt
index 8710d23..2cb16d3372 100644
--- a/tests/net/common/java/android/net/CaptivePortalDataTest.kt
+++ b/tests/net/common/java/android/net/CaptivePortalDataTest.kt
@@ -18,12 +18,15 @@
import android.os.Build
import androidx.test.filters.SmallTest
+import com.android.modules.utils.build.SdkLevel
import com.android.testutils.assertParcelSane
import com.android.testutils.assertParcelingIsLossless
+import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.DevSdkIgnoreRunner
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import kotlin.test.assertEquals
@@ -33,6 +36,9 @@
@RunWith(DevSdkIgnoreRunner::class)
@IgnoreUpTo(Build.VERSION_CODES.Q)
class CaptivePortalDataTest {
+ @Rule @JvmField
+ val ignoreRule = DevSdkIgnoreRule()
+
private val data = CaptivePortalData.Builder()
.setRefreshTime(123L)
.setUserPortalUrl(Uri.parse("https://portal.example.com/test"))
@@ -41,7 +47,11 @@
.setBytesRemaining(456L)
.setExpiryTime(789L)
.setCaptive(true)
- .setVenueFriendlyName("venue friendly name")
+ .apply {
+ if (SdkLevel.isAtLeastS()) {
+ setVenueFriendlyName("venue friendly name")
+ }
+ }
.build()
private fun makeBuilder() = CaptivePortalData.Builder(data)
@@ -67,8 +77,11 @@
assertNotEqualsAfterChange { it.setBytesRemaining(789L) }
assertNotEqualsAfterChange { it.setExpiryTime(12L) }
assertNotEqualsAfterChange { it.setCaptive(false) }
- assertNotEqualsAfterChange { it.setVenueFriendlyName("another friendly name") }
- assertNotEqualsAfterChange { it.setVenueFriendlyName(null) }
+
+ if (SdkLevel.isAtLeastS()) {
+ assertNotEqualsAfterChange { it.setVenueFriendlyName("another friendly name") }
+ assertNotEqualsAfterChange { it.setVenueFriendlyName(null) }
+ }
}
@Test
@@ -111,7 +124,7 @@
assertFalse(makeBuilder().setCaptive(false).build().isCaptive)
}
- @Test
+ @Test @IgnoreUpTo(Build.VERSION_CODES.R)
fun testVenueFriendlyName() {
assertEquals("venue friendly name", data.venueFriendlyName)
}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index b6e6816..3687073 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -8429,6 +8429,7 @@
mCm.registerNetworkCallback(genericRequest, genericNetworkCallback);
mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
+ waitForIdle();
final ConnectivityService.NetworkRequestInfo[] nriOutput = mService.requestsSortedById();
@@ -8490,4 +8491,20 @@
assertVpnUidRangesUpdated(true, newRanges, VPN_UID);
assertVpnUidRangesUpdated(false, vpnRanges, VPN_UID);
}
+
+ @Test
+ public void testInvalidRequestTypes() {
+ final int[] invalidReqTypeInts = new int[] {-1, NetworkRequest.Type.NONE.ordinal(),
+ NetworkRequest.Type.LISTEN.ordinal(), NetworkRequest.Type.values().length};
+ final NetworkCapabilities nc = new NetworkCapabilities().addTransportType(TRANSPORT_WIFI);
+
+ for (int reqTypeInt : invalidReqTypeInts) {
+ assertThrows("Expect throws for invalid request type " + reqTypeInt,
+ IllegalArgumentException.class,
+ () -> mService.requestNetwork(nc, reqTypeInt, null, 0, null,
+ ConnectivityManager.TYPE_NONE, mContext.getPackageName(),
+ getAttributionTag())
+ );
+ }
+ }
}
diff --git a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
new file mode 100644
index 0000000..3156190
--- /dev/null
+++ b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.vcn;
+
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+
+import android.net.wifi.WifiInfo;
+import android.os.Parcel;
+
+import org.junit.Test;
+
+public class VcnTransportInfoTest {
+ private static final int SUB_ID = 1;
+ private static final int NETWORK_ID = 5;
+ private static final WifiInfo WIFI_INFO =
+ new WifiInfo.Builder().setNetworkId(NETWORK_ID).build();
+
+ private static final VcnTransportInfo CELL_UNDERLYING_INFO = new VcnTransportInfo(SUB_ID);
+ private static final VcnTransportInfo WIFI_UNDERLYING_INFO = new VcnTransportInfo(WIFI_INFO);
+
+ @Test
+ public void testGetWifiInfo() {
+ assertEquals(WIFI_INFO, WIFI_UNDERLYING_INFO.getWifiInfo());
+
+ assertNull(CELL_UNDERLYING_INFO.getWifiInfo());
+ }
+
+ @Test
+ public void testGetSubId() {
+ assertEquals(SUB_ID, CELL_UNDERLYING_INFO.getSubId());
+
+ assertEquals(INVALID_SUBSCRIPTION_ID, WIFI_UNDERLYING_INFO.getSubId());
+ }
+
+ @Test
+ public void testEquals() {
+ assertEquals(CELL_UNDERLYING_INFO, CELL_UNDERLYING_INFO);
+ assertEquals(WIFI_UNDERLYING_INFO, WIFI_UNDERLYING_INFO);
+ assertNotEquals(CELL_UNDERLYING_INFO, WIFI_UNDERLYING_INFO);
+ }
+
+ @Test
+ public void testParcelUnparcel() {
+ verifyParcelingIsNull(CELL_UNDERLYING_INFO);
+ verifyParcelingIsNull(WIFI_UNDERLYING_INFO);
+ }
+
+ private void verifyParcelingIsNull(VcnTransportInfo vcnTransportInfo) {
+ Parcel parcel = Parcel.obtain();
+ vcnTransportInfo.writeToParcel(parcel, 0 /* flags */);
+ assertNull(VcnTransportInfo.CREATOR.createFromParcel(parcel));
+ }
+}