Merge "Use plain bytes for rule serializers"
diff --git a/api/current.txt b/api/current.txt
index bab334b..91a253e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6726,7 +6726,8 @@
method @Nullable public String getAlwaysOnVpnPackage(@NonNull android.content.ComponentName);
method @NonNull @WorkerThread public android.os.Bundle getApplicationRestrictions(@Nullable android.content.ComponentName, String);
method @Deprecated @Nullable public String getApplicationRestrictionsManagingPackage(@NonNull android.content.ComponentName);
- method public boolean getAutoTimeRequired();
+ method public boolean getAutoTime(@NonNull android.content.ComponentName);
+ method @Deprecated public boolean getAutoTimeRequired();
method @NonNull public java.util.List<android.os.UserHandle> getBindDeviceAdminTargetUsers(@NonNull android.content.ComponentName);
method public boolean getBluetoothContactSharingDisabled(@NonNull android.content.ComponentName);
method public boolean getCameraDisabled(@Nullable android.content.ComponentName);
@@ -6842,7 +6843,8 @@
method public boolean setApplicationHidden(@NonNull android.content.ComponentName, String, boolean);
method @WorkerThread public void setApplicationRestrictions(@Nullable android.content.ComponentName, String, android.os.Bundle);
method @Deprecated public void setApplicationRestrictionsManagingPackage(@NonNull android.content.ComponentName, @Nullable String) throws android.content.pm.PackageManager.NameNotFoundException;
- method public void setAutoTimeRequired(@NonNull android.content.ComponentName, boolean);
+ method public void setAutoTime(@NonNull android.content.ComponentName, boolean);
+ method @Deprecated public void setAutoTimeRequired(@NonNull android.content.ComponentName, boolean);
method public void setBackupServiceEnabled(@NonNull android.content.ComponentName, boolean);
method public void setBluetoothContactSharingDisabled(@NonNull android.content.ComponentName, boolean);
method public void setCameraDisabled(@NonNull android.content.ComponentName, boolean);
@@ -44373,6 +44375,8 @@
public static final class AccessNetworkConstants.NgranBands {
field public static final int BAND_1 = 1; // 0x1
field public static final int BAND_12 = 12; // 0xc
+ field public static final int BAND_14 = 14; // 0xe
+ field public static final int BAND_18 = 18; // 0x12
field public static final int BAND_2 = 2; // 0x2
field public static final int BAND_20 = 20; // 0x14
field public static final int BAND_25 = 25; // 0x19
@@ -44381,15 +44385,19 @@
field public static final int BAND_260 = 260; // 0x104
field public static final int BAND_261 = 261; // 0x105
field public static final int BAND_28 = 28; // 0x1c
+ field public static final int BAND_29 = 29; // 0x1d
field public static final int BAND_3 = 3; // 0x3
+ field public static final int BAND_30 = 30; // 0x1e
field public static final int BAND_34 = 34; // 0x22
field public static final int BAND_38 = 38; // 0x26
field public static final int BAND_39 = 39; // 0x27
field public static final int BAND_40 = 40; // 0x28
field public static final int BAND_41 = 41; // 0x29
+ field public static final int BAND_48 = 48; // 0x30
field public static final int BAND_5 = 5; // 0x5
field public static final int BAND_50 = 50; // 0x32
field public static final int BAND_51 = 51; // 0x33
+ field public static final int BAND_65 = 65; // 0x41
field public static final int BAND_66 = 66; // 0x42
field public static final int BAND_7 = 7; // 0x7
field public static final int BAND_70 = 70; // 0x46
@@ -44407,6 +44415,7 @@
field public static final int BAND_83 = 83; // 0x53
field public static final int BAND_84 = 84; // 0x54
field public static final int BAND_86 = 86; // 0x56
+ field public static final int BAND_90 = 90; // 0x5a
}
public static final class AccessNetworkConstants.UtranBand {
@@ -46038,6 +46047,193 @@
}
+package android.telephony.ims {
+
+ public final class ImsReasonInfo implements android.os.Parcelable {
+ ctor public ImsReasonInfo(int, int, @Nullable String);
+ method public int describeContents();
+ method public int getCode();
+ method public int getExtraCode();
+ method @Nullable public String getExtraMessage();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final int CODE_ACCESS_CLASS_BLOCKED = 1512; // 0x5e8
+ field public static final int CODE_ANSWERED_ELSEWHERE = 1014; // 0x3f6
+ field public static final int CODE_BLACKLISTED_CALL_ID = 506; // 0x1fa
+ field public static final int CODE_CALL_BARRED = 240; // 0xf0
+ field public static final int CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE = 1100; // 0x44c
+ field public static final int CODE_CALL_END_CAUSE_CALL_PULL = 1016; // 0x3f8
+ field public static final int CODE_CALL_PULL_OUT_OF_SYNC = 1015; // 0x3f7
+ field public static final int CODE_DATA_DISABLED = 1406; // 0x57e
+ field public static final int CODE_DATA_LIMIT_REACHED = 1405; // 0x57d
+ field public static final int CODE_DIAL_MODIFIED_TO_DIAL = 246; // 0xf6
+ field public static final int CODE_DIAL_MODIFIED_TO_DIAL_VIDEO = 247; // 0xf7
+ field public static final int CODE_DIAL_MODIFIED_TO_SS = 245; // 0xf5
+ field public static final int CODE_DIAL_MODIFIED_TO_USSD = 244; // 0xf4
+ field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL = 248; // 0xf8
+ field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 249; // 0xf9
+ field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_SS = 250; // 0xfa
+ field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_USSD = 251; // 0xfb
+ field public static final int CODE_ECBM_NOT_SUPPORTED = 901; // 0x385
+ field public static final int CODE_EMERGENCY_PERM_FAILURE = 364; // 0x16c
+ field public static final int CODE_EMERGENCY_TEMP_FAILURE = 363; // 0x16b
+ field public static final int CODE_EPDG_TUNNEL_ESTABLISH_FAILURE = 1400; // 0x578
+ field public static final int CODE_EPDG_TUNNEL_LOST_CONNECTION = 1402; // 0x57a
+ field public static final int CODE_EPDG_TUNNEL_REKEY_FAILURE = 1401; // 0x579
+ field public static final int CODE_FDN_BLOCKED = 241; // 0xf1
+ field public static final int CODE_IKEV2_AUTH_FAILURE = 1408; // 0x580
+ field public static final int CODE_IMEI_NOT_ACCEPTED = 243; // 0xf3
+ field public static final int CODE_IWLAN_DPD_FAILURE = 1300; // 0x514
+ field public static final int CODE_LOCAL_CALL_BUSY = 142; // 0x8e
+ field public static final int CODE_LOCAL_CALL_CS_RETRY_REQUIRED = 146; // 0x92
+ field public static final int CODE_LOCAL_CALL_DECLINE = 143; // 0x8f
+ field public static final int CODE_LOCAL_CALL_EXCEEDED = 141; // 0x8d
+ field public static final int CODE_LOCAL_CALL_RESOURCE_RESERVATION_FAILED = 145; // 0x91
+ field public static final int CODE_LOCAL_CALL_TERMINATED = 148; // 0x94
+ field public static final int CODE_LOCAL_CALL_VCC_ON_PROGRESSING = 144; // 0x90
+ field public static final int CODE_LOCAL_CALL_VOLTE_RETRY_REQUIRED = 147; // 0x93
+ field public static final int CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE = 108; // 0x6c
+ field public static final int CODE_LOCAL_HO_NOT_FEASIBLE = 149; // 0x95
+ field public static final int CODE_LOCAL_ILLEGAL_ARGUMENT = 101; // 0x65
+ field public static final int CODE_LOCAL_ILLEGAL_STATE = 102; // 0x66
+ field public static final int CODE_LOCAL_IMS_SERVICE_DOWN = 106; // 0x6a
+ field public static final int CODE_LOCAL_INTERNAL_ERROR = 103; // 0x67
+ field public static final int CODE_LOCAL_LOW_BATTERY = 112; // 0x70
+ field public static final int CODE_LOCAL_NETWORK_IP_CHANGED = 124; // 0x7c
+ field public static final int CODE_LOCAL_NETWORK_NO_LTE_COVERAGE = 122; // 0x7a
+ field public static final int CODE_LOCAL_NETWORK_NO_SERVICE = 121; // 0x79
+ field public static final int CODE_LOCAL_NETWORK_ROAMING = 123; // 0x7b
+ field public static final int CODE_LOCAL_NOT_REGISTERED = 132; // 0x84
+ field public static final int CODE_LOCAL_NO_PENDING_CALL = 107; // 0x6b
+ field public static final int CODE_LOCAL_POWER_OFF = 111; // 0x6f
+ field public static final int CODE_LOCAL_SERVICE_UNAVAILABLE = 131; // 0x83
+ field public static final int CODE_LOW_BATTERY = 505; // 0x1f9
+ field public static final int CODE_MAXIMUM_NUMBER_OF_CALLS_REACHED = 1403; // 0x57b
+ field public static final int CODE_MEDIA_INIT_FAILED = 401; // 0x191
+ field public static final int CODE_MEDIA_NOT_ACCEPTABLE = 403; // 0x193
+ field public static final int CODE_MEDIA_NO_DATA = 402; // 0x192
+ field public static final int CODE_MEDIA_UNSPECIFIED = 404; // 0x194
+ field public static final int CODE_MULTIENDPOINT_NOT_SUPPORTED = 902; // 0x386
+ field public static final int CODE_NETWORK_DETACH = 1513; // 0x5e9
+ field public static final int CODE_NETWORK_REJECT = 1504; // 0x5e0
+ field public static final int CODE_NETWORK_RESP_TIMEOUT = 1503; // 0x5df
+ field public static final int CODE_NO_CSFB_IN_CS_ROAM = 1516; // 0x5ec
+ field public static final int CODE_NO_VALID_SIM = 1501; // 0x5dd
+ field public static final int CODE_OEM_CAUSE_1 = 61441; // 0xf001
+ field public static final int CODE_OEM_CAUSE_10 = 61450; // 0xf00a
+ field public static final int CODE_OEM_CAUSE_11 = 61451; // 0xf00b
+ field public static final int CODE_OEM_CAUSE_12 = 61452; // 0xf00c
+ field public static final int CODE_OEM_CAUSE_13 = 61453; // 0xf00d
+ field public static final int CODE_OEM_CAUSE_14 = 61454; // 0xf00e
+ field public static final int CODE_OEM_CAUSE_15 = 61455; // 0xf00f
+ field public static final int CODE_OEM_CAUSE_2 = 61442; // 0xf002
+ field public static final int CODE_OEM_CAUSE_3 = 61443; // 0xf003
+ field public static final int CODE_OEM_CAUSE_4 = 61444; // 0xf004
+ field public static final int CODE_OEM_CAUSE_5 = 61445; // 0xf005
+ field public static final int CODE_OEM_CAUSE_6 = 61446; // 0xf006
+ field public static final int CODE_OEM_CAUSE_7 = 61447; // 0xf007
+ field public static final int CODE_OEM_CAUSE_8 = 61448; // 0xf008
+ field public static final int CODE_OEM_CAUSE_9 = 61449; // 0xf009
+ field public static final int CODE_RADIO_ACCESS_FAILURE = 1505; // 0x5e1
+ field public static final int CODE_RADIO_INTERNAL_ERROR = 1502; // 0x5de
+ field public static final int CODE_RADIO_LINK_FAILURE = 1506; // 0x5e2
+ field public static final int CODE_RADIO_LINK_LOST = 1507; // 0x5e3
+ field public static final int CODE_RADIO_OFF = 1500; // 0x5dc
+ field public static final int CODE_RADIO_RELEASE_ABNORMAL = 1511; // 0x5e7
+ field public static final int CODE_RADIO_RELEASE_NORMAL = 1510; // 0x5e6
+ field public static final int CODE_RADIO_SETUP_FAILURE = 1509; // 0x5e5
+ field public static final int CODE_RADIO_UPLINK_FAILURE = 1508; // 0x5e4
+ field public static final int CODE_REGISTRATION_ERROR = 1000; // 0x3e8
+ field public static final int CODE_REJECTED_ELSEWHERE = 1017; // 0x3f9
+ field public static final int CODE_REJECT_1X_COLLISION = 1603; // 0x643
+ field public static final int CODE_REJECT_CALL_ON_OTHER_SUB = 1602; // 0x642
+ field public static final int CODE_REJECT_CALL_TYPE_NOT_ALLOWED = 1605; // 0x645
+ field public static final int CODE_REJECT_CONFERENCE_TTY_NOT_ALLOWED = 1617; // 0x651
+ field public static final int CODE_REJECT_INTERNAL_ERROR = 1612; // 0x64c
+ field public static final int CODE_REJECT_MAX_CALL_LIMIT_REACHED = 1608; // 0x648
+ field public static final int CODE_REJECT_ONGOING_CALL_SETUP = 1607; // 0x647
+ field public static final int CODE_REJECT_ONGOING_CALL_TRANSFER = 1611; // 0x64b
+ field public static final int CODE_REJECT_ONGOING_CALL_UPGRADE = 1616; // 0x650
+ field public static final int CODE_REJECT_ONGOING_CALL_WAITING_DISABLED = 1601; // 0x641
+ field public static final int CODE_REJECT_ONGOING_CONFERENCE_CALL = 1618; // 0x652
+ field public static final int CODE_REJECT_ONGOING_CS_CALL = 1621; // 0x655
+ field public static final int CODE_REJECT_ONGOING_E911_CALL = 1606; // 0x646
+ field public static final int CODE_REJECT_ONGOING_ENCRYPTED_CALL = 1620; // 0x654
+ field public static final int CODE_REJECT_ONGOING_HANDOVER = 1614; // 0x64e
+ field public static final int CODE_REJECT_QOS_FAILURE = 1613; // 0x64d
+ field public static final int CODE_REJECT_SERVICE_NOT_REGISTERED = 1604; // 0x644
+ field public static final int CODE_REJECT_UNKNOWN = 1600; // 0x640
+ field public static final int CODE_REJECT_UNSUPPORTED_SDP_HEADERS = 1610; // 0x64a
+ field public static final int CODE_REJECT_UNSUPPORTED_SIP_HEADERS = 1609; // 0x649
+ field public static final int CODE_REJECT_VT_AVPF_NOT_ALLOWED = 1619; // 0x653
+ field public static final int CODE_REJECT_VT_TTY_NOT_ALLOWED = 1615; // 0x64f
+ field public static final int CODE_REMOTE_CALL_DECLINE = 1404; // 0x57c
+ field public static final int CODE_SESSION_MODIFICATION_FAILED = 1517; // 0x5ed
+ field public static final int CODE_SIP_ALTERNATE_EMERGENCY_CALL = 1514; // 0x5ea
+ field public static final int CODE_SIP_AMBIGUOUS = 376; // 0x178
+ field public static final int CODE_SIP_BAD_ADDRESS = 337; // 0x151
+ field public static final int CODE_SIP_BAD_REQUEST = 331; // 0x14b
+ field public static final int CODE_SIP_BUSY = 338; // 0x152
+ field public static final int CODE_SIP_CALL_OR_TRANS_DOES_NOT_EXIST = 372; // 0x174
+ field public static final int CODE_SIP_CLIENT_ERROR = 342; // 0x156
+ field public static final int CODE_SIP_EXTENSION_REQUIRED = 370; // 0x172
+ field public static final int CODE_SIP_FORBIDDEN = 332; // 0x14c
+ field public static final int CODE_SIP_GLOBAL_ERROR = 362; // 0x16a
+ field public static final int CODE_SIP_INTERVAL_TOO_BRIEF = 371; // 0x173
+ field public static final int CODE_SIP_LOOP_DETECTED = 373; // 0x175
+ field public static final int CODE_SIP_METHOD_NOT_ALLOWED = 366; // 0x16e
+ field public static final int CODE_SIP_NOT_ACCEPTABLE = 340; // 0x154
+ field public static final int CODE_SIP_NOT_FOUND = 333; // 0x14d
+ field public static final int CODE_SIP_NOT_REACHABLE = 341; // 0x155
+ field public static final int CODE_SIP_NOT_SUPPORTED = 334; // 0x14e
+ field public static final int CODE_SIP_PROXY_AUTHENTICATION_REQUIRED = 367; // 0x16f
+ field public static final int CODE_SIP_REDIRECTED = 321; // 0x141
+ field public static final int CODE_SIP_REQUEST_CANCELLED = 339; // 0x153
+ field public static final int CODE_SIP_REQUEST_ENTITY_TOO_LARGE = 368; // 0x170
+ field public static final int CODE_SIP_REQUEST_PENDING = 377; // 0x179
+ field public static final int CODE_SIP_REQUEST_TIMEOUT = 335; // 0x14f
+ field public static final int CODE_SIP_REQUEST_URI_TOO_LARGE = 369; // 0x171
+ field public static final int CODE_SIP_SERVER_ERROR = 354; // 0x162
+ field public static final int CODE_SIP_SERVER_INTERNAL_ERROR = 351; // 0x15f
+ field public static final int CODE_SIP_SERVER_TIMEOUT = 353; // 0x161
+ field public static final int CODE_SIP_SERVICE_UNAVAILABLE = 352; // 0x160
+ field public static final int CODE_SIP_TEMPRARILY_UNAVAILABLE = 336; // 0x150
+ field public static final int CODE_SIP_TOO_MANY_HOPS = 374; // 0x176
+ field public static final int CODE_SIP_TRANSACTION_DOES_NOT_EXIST = 343; // 0x157
+ field public static final int CODE_SIP_UNDECIPHERABLE = 378; // 0x17a
+ field public static final int CODE_SIP_USER_MARKED_UNWANTED = 365; // 0x16d
+ field public static final int CODE_SIP_USER_REJECTED = 361; // 0x169
+ field public static final int CODE_SUPP_SVC_CANCELLED = 1202; // 0x4b2
+ field public static final int CODE_SUPP_SVC_FAILED = 1201; // 0x4b1
+ field public static final int CODE_SUPP_SVC_REINVITE_COLLISION = 1203; // 0x4b3
+ field public static final int CODE_TIMEOUT_1XX_WAITING = 201; // 0xc9
+ field public static final int CODE_TIMEOUT_NO_ANSWER = 202; // 0xca
+ field public static final int CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE = 203; // 0xcb
+ field public static final int CODE_UNSPECIFIED = 0; // 0x0
+ field public static final int CODE_USER_CANCELLED_SESSION_MODIFICATION = 512; // 0x200
+ field public static final int CODE_USER_DECLINE = 504; // 0x1f8
+ field public static final int CODE_USER_IGNORE = 503; // 0x1f7
+ field public static final int CODE_USER_NOANSWER = 502; // 0x1f6
+ field public static final int CODE_USER_REJECTED_SESSION_MODIFICATION = 511; // 0x1ff
+ field public static final int CODE_USER_TERMINATED = 501; // 0x1f5
+ field public static final int CODE_USER_TERMINATED_BY_REMOTE = 510; // 0x1fe
+ field public static final int CODE_UT_CB_PASSWORD_MISMATCH = 821; // 0x335
+ field public static final int CODE_UT_NETWORK_ERROR = 804; // 0x324
+ field public static final int CODE_UT_NOT_SUPPORTED = 801; // 0x321
+ field public static final int CODE_UT_OPERATION_NOT_ALLOWED = 803; // 0x323
+ field public static final int CODE_UT_SERVICE_UNAVAILABLE = 802; // 0x322
+ field public static final int CODE_UT_SS_MODIFIED_TO_DIAL = 822; // 0x336
+ field public static final int CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO = 825; // 0x339
+ field public static final int CODE_UT_SS_MODIFIED_TO_SS = 824; // 0x338
+ field public static final int CODE_UT_SS_MODIFIED_TO_USSD = 823; // 0x337
+ field public static final int CODE_WIFI_LOST = 1407; // 0x57f
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsReasonInfo> CREATOR;
+ field public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3; // 0x3
+ field public static final int EXTRA_CODE_CALL_RETRY_NORMAL = 1; // 0x1
+ field public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2; // 0x2
+ }
+
+}
+
package android.telephony.mbms {
public class DownloadProgressListener {
diff --git a/api/system-current.txt b/api/system-current.txt
index 7f0050c..8bb1983 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1329,6 +1329,11 @@
package android.bluetooth {
+ public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile {
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
+ }
+
public final class BluetoothAdapter {
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean addOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean connectAllEnabledProfiles(@NonNull android.bluetooth.BluetoothDevice);
@@ -1341,10 +1346,14 @@
method public boolean isBleScanAlwaysAvailable();
method public boolean isLeEnabled();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean removeOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setActiveDevice(@Nullable android.bluetooth.BluetoothDevice, int);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean setScanMode(int, int);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean setScanMode(int);
field public static final String ACTION_BLE_STATE_CHANGED = "android.bluetooth.adapter.action.BLE_STATE_CHANGED";
field public static final String ACTION_REQUEST_BLE_SCAN_ALWAYS_AVAILABLE = "android.bluetooth.adapter.action.REQUEST_BLE_SCAN_ALWAYS_AVAILABLE";
+ field public static final int ACTIVE_DEVICE_ALL = 2; // 0x2
+ field public static final int ACTIVE_DEVICE_AUDIO = 0; // 0x0
+ field public static final int ACTIVE_DEVICE_PHONE_CALL = 1; // 0x1
}
public static interface BluetoothAdapter.OnMetadataChangedListener {
@@ -1389,7 +1398,14 @@
public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile {
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean connect(android.bluetooth.BluetoothDevice);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean disconnect(android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setPriority(android.bluetooth.BluetoothDevice, int);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setPriority(android.bluetooth.BluetoothDevice, int);
+ }
+
+ public final class BluetoothHearingAid implements android.bluetooth.BluetoothProfile {
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
+ method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
}
public final class BluetoothPan implements android.bluetooth.BluetoothProfile {
@@ -1408,9 +1424,12 @@
}
public interface BluetoothProfile {
+ field public static final int CONNECTION_POLICY_ALLOWED = 100; // 0x64
+ field public static final int CONNECTION_POLICY_FORBIDDEN = 0; // 0x0
+ field public static final int CONNECTION_POLICY_UNKNOWN = -1; // 0xffffffff
field public static final int PAN = 5; // 0x5
- field public static final int PRIORITY_OFF = 0; // 0x0
- field public static final int PRIORITY_ON = 100; // 0x64
+ field @Deprecated public static final int PRIORITY_OFF = 0; // 0x0
+ field @Deprecated public static final int PRIORITY_ON = 100; // 0x64
}
}
@@ -8032,7 +8051,7 @@
}
public static class CallScreeningService.CallResponse.Builder {
- method public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallFurther(boolean);
+ method @NonNull public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallViaAudioProcessing(boolean);
}
public abstract class Conference extends android.telecom.Conferenceable {
@@ -10082,186 +10101,6 @@
}
public final class ImsReasonInfo implements android.os.Parcelable {
- ctor public ImsReasonInfo(int, int, String);
- method public int describeContents();
- method public int getCode();
- method public int getExtraCode();
- method public String getExtraMessage();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CODE_ACCESS_CLASS_BLOCKED = 1512; // 0x5e8
- field public static final int CODE_ANSWERED_ELSEWHERE = 1014; // 0x3f6
- field public static final int CODE_BLACKLISTED_CALL_ID = 506; // 0x1fa
- field public static final int CODE_CALL_BARRED = 240; // 0xf0
- field public static final int CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE = 1100; // 0x44c
- field public static final int CODE_CALL_END_CAUSE_CALL_PULL = 1016; // 0x3f8
- field public static final int CODE_CALL_PULL_OUT_OF_SYNC = 1015; // 0x3f7
- field public static final int CODE_DATA_DISABLED = 1406; // 0x57e
- field public static final int CODE_DATA_LIMIT_REACHED = 1405; // 0x57d
- field public static final int CODE_DIAL_MODIFIED_TO_DIAL = 246; // 0xf6
- field public static final int CODE_DIAL_MODIFIED_TO_DIAL_VIDEO = 247; // 0xf7
- field public static final int CODE_DIAL_MODIFIED_TO_SS = 245; // 0xf5
- field public static final int CODE_DIAL_MODIFIED_TO_USSD = 244; // 0xf4
- field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL = 248; // 0xf8
- field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 249; // 0xf9
- field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_SS = 250; // 0xfa
- field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_USSD = 251; // 0xfb
- field public static final int CODE_ECBM_NOT_SUPPORTED = 901; // 0x385
- field public static final int CODE_EMERGENCY_PERM_FAILURE = 364; // 0x16c
- field public static final int CODE_EMERGENCY_TEMP_FAILURE = 363; // 0x16b
- field public static final int CODE_EPDG_TUNNEL_ESTABLISH_FAILURE = 1400; // 0x578
- field public static final int CODE_EPDG_TUNNEL_LOST_CONNECTION = 1402; // 0x57a
- field public static final int CODE_EPDG_TUNNEL_REKEY_FAILURE = 1401; // 0x579
- field public static final int CODE_FDN_BLOCKED = 241; // 0xf1
- field public static final int CODE_IKEV2_AUTH_FAILURE = 1408; // 0x580
- field public static final int CODE_IMEI_NOT_ACCEPTED = 243; // 0xf3
- field public static final int CODE_IWLAN_DPD_FAILURE = 1300; // 0x514
- field public static final int CODE_LOCAL_CALL_BUSY = 142; // 0x8e
- field public static final int CODE_LOCAL_CALL_CS_RETRY_REQUIRED = 146; // 0x92
- field public static final int CODE_LOCAL_CALL_DECLINE = 143; // 0x8f
- field public static final int CODE_LOCAL_CALL_EXCEEDED = 141; // 0x8d
- field public static final int CODE_LOCAL_CALL_RESOURCE_RESERVATION_FAILED = 145; // 0x91
- field public static final int CODE_LOCAL_CALL_TERMINATED = 148; // 0x94
- field public static final int CODE_LOCAL_CALL_VCC_ON_PROGRESSING = 144; // 0x90
- field public static final int CODE_LOCAL_CALL_VOLTE_RETRY_REQUIRED = 147; // 0x93
- field public static final int CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE = 108; // 0x6c
- field public static final int CODE_LOCAL_HO_NOT_FEASIBLE = 149; // 0x95
- field public static final int CODE_LOCAL_ILLEGAL_ARGUMENT = 101; // 0x65
- field public static final int CODE_LOCAL_ILLEGAL_STATE = 102; // 0x66
- field public static final int CODE_LOCAL_IMS_SERVICE_DOWN = 106; // 0x6a
- field public static final int CODE_LOCAL_INTERNAL_ERROR = 103; // 0x67
- field public static final int CODE_LOCAL_LOW_BATTERY = 112; // 0x70
- field public static final int CODE_LOCAL_NETWORK_IP_CHANGED = 124; // 0x7c
- field public static final int CODE_LOCAL_NETWORK_NO_LTE_COVERAGE = 122; // 0x7a
- field public static final int CODE_LOCAL_NETWORK_NO_SERVICE = 121; // 0x79
- field public static final int CODE_LOCAL_NETWORK_ROAMING = 123; // 0x7b
- field public static final int CODE_LOCAL_NOT_REGISTERED = 132; // 0x84
- field public static final int CODE_LOCAL_NO_PENDING_CALL = 107; // 0x6b
- field public static final int CODE_LOCAL_POWER_OFF = 111; // 0x6f
- field public static final int CODE_LOCAL_SERVICE_UNAVAILABLE = 131; // 0x83
- field public static final int CODE_LOW_BATTERY = 505; // 0x1f9
- field public static final int CODE_MAXIMUM_NUMBER_OF_CALLS_REACHED = 1403; // 0x57b
- field public static final int CODE_MEDIA_INIT_FAILED = 401; // 0x191
- field public static final int CODE_MEDIA_NOT_ACCEPTABLE = 403; // 0x193
- field public static final int CODE_MEDIA_NO_DATA = 402; // 0x192
- field public static final int CODE_MEDIA_UNSPECIFIED = 404; // 0x194
- field public static final int CODE_MULTIENDPOINT_NOT_SUPPORTED = 902; // 0x386
- field public static final int CODE_NETWORK_DETACH = 1513; // 0x5e9
- field public static final int CODE_NETWORK_REJECT = 1504; // 0x5e0
- field public static final int CODE_NETWORK_RESP_TIMEOUT = 1503; // 0x5df
- field public static final int CODE_NO_CSFB_IN_CS_ROAM = 1516; // 0x5ec
- field public static final int CODE_NO_VALID_SIM = 1501; // 0x5dd
- field public static final int CODE_OEM_CAUSE_1 = 61441; // 0xf001
- field public static final int CODE_OEM_CAUSE_10 = 61450; // 0xf00a
- field public static final int CODE_OEM_CAUSE_11 = 61451; // 0xf00b
- field public static final int CODE_OEM_CAUSE_12 = 61452; // 0xf00c
- field public static final int CODE_OEM_CAUSE_13 = 61453; // 0xf00d
- field public static final int CODE_OEM_CAUSE_14 = 61454; // 0xf00e
- field public static final int CODE_OEM_CAUSE_15 = 61455; // 0xf00f
- field public static final int CODE_OEM_CAUSE_2 = 61442; // 0xf002
- field public static final int CODE_OEM_CAUSE_3 = 61443; // 0xf003
- field public static final int CODE_OEM_CAUSE_4 = 61444; // 0xf004
- field public static final int CODE_OEM_CAUSE_5 = 61445; // 0xf005
- field public static final int CODE_OEM_CAUSE_6 = 61446; // 0xf006
- field public static final int CODE_OEM_CAUSE_7 = 61447; // 0xf007
- field public static final int CODE_OEM_CAUSE_8 = 61448; // 0xf008
- field public static final int CODE_OEM_CAUSE_9 = 61449; // 0xf009
- field public static final int CODE_RADIO_ACCESS_FAILURE = 1505; // 0x5e1
- field public static final int CODE_RADIO_INTERNAL_ERROR = 1502; // 0x5de
- field public static final int CODE_RADIO_LINK_FAILURE = 1506; // 0x5e2
- field public static final int CODE_RADIO_LINK_LOST = 1507; // 0x5e3
- field public static final int CODE_RADIO_OFF = 1500; // 0x5dc
- field public static final int CODE_RADIO_RELEASE_ABNORMAL = 1511; // 0x5e7
- field public static final int CODE_RADIO_RELEASE_NORMAL = 1510; // 0x5e6
- field public static final int CODE_RADIO_SETUP_FAILURE = 1509; // 0x5e5
- field public static final int CODE_RADIO_UPLINK_FAILURE = 1508; // 0x5e4
- field public static final int CODE_REGISTRATION_ERROR = 1000; // 0x3e8
- field public static final int CODE_REJECTED_ELSEWHERE = 1017; // 0x3f9
- field public static final int CODE_REJECT_1X_COLLISION = 1603; // 0x643
- field public static final int CODE_REJECT_CALL_ON_OTHER_SUB = 1602; // 0x642
- field public static final int CODE_REJECT_CALL_TYPE_NOT_ALLOWED = 1605; // 0x645
- field public static final int CODE_REJECT_CONFERENCE_TTY_NOT_ALLOWED = 1617; // 0x651
- field public static final int CODE_REJECT_INTERNAL_ERROR = 1612; // 0x64c
- field public static final int CODE_REJECT_MAX_CALL_LIMIT_REACHED = 1608; // 0x648
- field public static final int CODE_REJECT_ONGOING_CALL_SETUP = 1607; // 0x647
- field public static final int CODE_REJECT_ONGOING_CALL_TRANSFER = 1611; // 0x64b
- field public static final int CODE_REJECT_ONGOING_CALL_UPGRADE = 1616; // 0x650
- field public static final int CODE_REJECT_ONGOING_CALL_WAITING_DISABLED = 1601; // 0x641
- field public static final int CODE_REJECT_ONGOING_CONFERENCE_CALL = 1618; // 0x652
- field public static final int CODE_REJECT_ONGOING_CS_CALL = 1621; // 0x655
- field public static final int CODE_REJECT_ONGOING_E911_CALL = 1606; // 0x646
- field public static final int CODE_REJECT_ONGOING_ENCRYPTED_CALL = 1620; // 0x654
- field public static final int CODE_REJECT_ONGOING_HANDOVER = 1614; // 0x64e
- field public static final int CODE_REJECT_QOS_FAILURE = 1613; // 0x64d
- field public static final int CODE_REJECT_SERVICE_NOT_REGISTERED = 1604; // 0x644
- field public static final int CODE_REJECT_UNKNOWN = 1600; // 0x640
- field public static final int CODE_REJECT_UNSUPPORTED_SDP_HEADERS = 1610; // 0x64a
- field public static final int CODE_REJECT_UNSUPPORTED_SIP_HEADERS = 1609; // 0x649
- field public static final int CODE_REJECT_VT_AVPF_NOT_ALLOWED = 1619; // 0x653
- field public static final int CODE_REJECT_VT_TTY_NOT_ALLOWED = 1615; // 0x64f
- field public static final int CODE_REMOTE_CALL_DECLINE = 1404; // 0x57c
- field public static final int CODE_SESSION_MODIFICATION_FAILED = 1517; // 0x5ed
- field public static final int CODE_SIP_ALTERNATE_EMERGENCY_CALL = 1514; // 0x5ea
- field public static final int CODE_SIP_AMBIGUOUS = 376; // 0x178
- field public static final int CODE_SIP_BAD_ADDRESS = 337; // 0x151
- field public static final int CODE_SIP_BAD_REQUEST = 331; // 0x14b
- field public static final int CODE_SIP_BUSY = 338; // 0x152
- field public static final int CODE_SIP_CALL_OR_TRANS_DOES_NOT_EXIST = 372; // 0x174
- field public static final int CODE_SIP_CLIENT_ERROR = 342; // 0x156
- field public static final int CODE_SIP_EXTENSION_REQUIRED = 370; // 0x172
- field public static final int CODE_SIP_FORBIDDEN = 332; // 0x14c
- field public static final int CODE_SIP_GLOBAL_ERROR = 362; // 0x16a
- field public static final int CODE_SIP_INTERVAL_TOO_BRIEF = 371; // 0x173
- field public static final int CODE_SIP_LOOP_DETECTED = 373; // 0x175
- field public static final int CODE_SIP_METHOD_NOT_ALLOWED = 366; // 0x16e
- field public static final int CODE_SIP_NOT_ACCEPTABLE = 340; // 0x154
- field public static final int CODE_SIP_NOT_FOUND = 333; // 0x14d
- field public static final int CODE_SIP_NOT_REACHABLE = 341; // 0x155
- field public static final int CODE_SIP_NOT_SUPPORTED = 334; // 0x14e
- field public static final int CODE_SIP_PROXY_AUTHENTICATION_REQUIRED = 367; // 0x16f
- field public static final int CODE_SIP_REDIRECTED = 321; // 0x141
- field public static final int CODE_SIP_REQUEST_CANCELLED = 339; // 0x153
- field public static final int CODE_SIP_REQUEST_ENTITY_TOO_LARGE = 368; // 0x170
- field public static final int CODE_SIP_REQUEST_PENDING = 377; // 0x179
- field public static final int CODE_SIP_REQUEST_TIMEOUT = 335; // 0x14f
- field public static final int CODE_SIP_REQUEST_URI_TOO_LARGE = 369; // 0x171
- field public static final int CODE_SIP_SERVER_ERROR = 354; // 0x162
- field public static final int CODE_SIP_SERVER_INTERNAL_ERROR = 351; // 0x15f
- field public static final int CODE_SIP_SERVER_TIMEOUT = 353; // 0x161
- field public static final int CODE_SIP_SERVICE_UNAVAILABLE = 352; // 0x160
- field public static final int CODE_SIP_TEMPRARILY_UNAVAILABLE = 336; // 0x150
- field public static final int CODE_SIP_TOO_MANY_HOPS = 374; // 0x176
- field public static final int CODE_SIP_TRANSACTION_DOES_NOT_EXIST = 343; // 0x157
- field public static final int CODE_SIP_UNDECIPHERABLE = 378; // 0x17a
- field public static final int CODE_SIP_USER_MARKED_UNWANTED = 365; // 0x16d
- field public static final int CODE_SIP_USER_REJECTED = 361; // 0x169
- field public static final int CODE_SUPP_SVC_CANCELLED = 1202; // 0x4b2
- field public static final int CODE_SUPP_SVC_FAILED = 1201; // 0x4b1
- field public static final int CODE_SUPP_SVC_REINVITE_COLLISION = 1203; // 0x4b3
- field public static final int CODE_TIMEOUT_1XX_WAITING = 201; // 0xc9
- field public static final int CODE_TIMEOUT_NO_ANSWER = 202; // 0xca
- field public static final int CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE = 203; // 0xcb
- field public static final int CODE_UNSPECIFIED = 0; // 0x0
- field public static final int CODE_USER_CANCELLED_SESSION_MODIFICATION = 512; // 0x200
- field public static final int CODE_USER_DECLINE = 504; // 0x1f8
- field public static final int CODE_USER_IGNORE = 503; // 0x1f7
- field public static final int CODE_USER_NOANSWER = 502; // 0x1f6
- field public static final int CODE_USER_REJECTED_SESSION_MODIFICATION = 511; // 0x1ff
- field public static final int CODE_USER_TERMINATED = 501; // 0x1f5
- field public static final int CODE_USER_TERMINATED_BY_REMOTE = 510; // 0x1fe
- field public static final int CODE_UT_CB_PASSWORD_MISMATCH = 821; // 0x335
- field public static final int CODE_UT_NETWORK_ERROR = 804; // 0x324
- field public static final int CODE_UT_NOT_SUPPORTED = 801; // 0x321
- field public static final int CODE_UT_OPERATION_NOT_ALLOWED = 803; // 0x323
- field public static final int CODE_UT_SERVICE_UNAVAILABLE = 802; // 0x322
- field public static final int CODE_UT_SS_MODIFIED_TO_DIAL = 822; // 0x336
- field public static final int CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO = 825; // 0x339
- field public static final int CODE_UT_SS_MODIFIED_TO_SS = 824; // 0x338
- field public static final int CODE_UT_SS_MODIFIED_TO_USSD = 823; // 0x337
- field public static final int CODE_WIFI_LOST = 1407; // 0x57f
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsReasonInfo> CREATOR;
- field public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3; // 0x3
- field public static final int EXTRA_CODE_CALL_RETRY_NORMAL = 1; // 0x1
- field public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2; // 0x2
field public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED = "Forbidden. Not Authorized for Service";
}
diff --git a/api/test-current.txt b/api/test-current.txt
index cf93410..2d35736 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -2944,7 +2944,7 @@
}
public static class CallScreeningService.CallResponse.Builder {
- method public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallFurther(boolean);
+ method @NonNull public android.telecom.CallScreeningService.CallResponse.Builder setShouldScreenCallViaAudioProcessing(boolean);
}
public abstract class Conference extends android.telecom.Conferenceable {
@@ -3454,190 +3454,6 @@
ctor @Deprecated public ImsMmTelManager.RegistrationCallback();
}
- public final class ImsReasonInfo implements android.os.Parcelable {
- ctor public ImsReasonInfo(int, int, String);
- method public int describeContents();
- method public int getCode();
- method public int getExtraCode();
- method public String getExtraMessage();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CODE_ACCESS_CLASS_BLOCKED = 1512; // 0x5e8
- field public static final int CODE_ANSWERED_ELSEWHERE = 1014; // 0x3f6
- field public static final int CODE_BLACKLISTED_CALL_ID = 506; // 0x1fa
- field public static final int CODE_CALL_BARRED = 240; // 0xf0
- field public static final int CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE = 1100; // 0x44c
- field public static final int CODE_CALL_END_CAUSE_CALL_PULL = 1016; // 0x3f8
- field public static final int CODE_CALL_PULL_OUT_OF_SYNC = 1015; // 0x3f7
- field public static final int CODE_DATA_DISABLED = 1406; // 0x57e
- field public static final int CODE_DATA_LIMIT_REACHED = 1405; // 0x57d
- field public static final int CODE_DIAL_MODIFIED_TO_DIAL = 246; // 0xf6
- field public static final int CODE_DIAL_MODIFIED_TO_DIAL_VIDEO = 247; // 0xf7
- field public static final int CODE_DIAL_MODIFIED_TO_SS = 245; // 0xf5
- field public static final int CODE_DIAL_MODIFIED_TO_USSD = 244; // 0xf4
- field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL = 248; // 0xf8
- field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 249; // 0xf9
- field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_SS = 250; // 0xfa
- field public static final int CODE_DIAL_VIDEO_MODIFIED_TO_USSD = 251; // 0xfb
- field public static final int CODE_ECBM_NOT_SUPPORTED = 901; // 0x385
- field public static final int CODE_EMERGENCY_PERM_FAILURE = 364; // 0x16c
- field public static final int CODE_EMERGENCY_TEMP_FAILURE = 363; // 0x16b
- field public static final int CODE_EPDG_TUNNEL_ESTABLISH_FAILURE = 1400; // 0x578
- field public static final int CODE_EPDG_TUNNEL_LOST_CONNECTION = 1402; // 0x57a
- field public static final int CODE_EPDG_TUNNEL_REKEY_FAILURE = 1401; // 0x579
- field public static final int CODE_FDN_BLOCKED = 241; // 0xf1
- field public static final int CODE_IKEV2_AUTH_FAILURE = 1408; // 0x580
- field public static final int CODE_IMEI_NOT_ACCEPTED = 243; // 0xf3
- field public static final int CODE_IWLAN_DPD_FAILURE = 1300; // 0x514
- field public static final int CODE_LOCAL_CALL_BUSY = 142; // 0x8e
- field public static final int CODE_LOCAL_CALL_CS_RETRY_REQUIRED = 146; // 0x92
- field public static final int CODE_LOCAL_CALL_DECLINE = 143; // 0x8f
- field public static final int CODE_LOCAL_CALL_EXCEEDED = 141; // 0x8d
- field public static final int CODE_LOCAL_CALL_RESOURCE_RESERVATION_FAILED = 145; // 0x91
- field public static final int CODE_LOCAL_CALL_TERMINATED = 148; // 0x94
- field public static final int CODE_LOCAL_CALL_VCC_ON_PROGRESSING = 144; // 0x90
- field public static final int CODE_LOCAL_CALL_VOLTE_RETRY_REQUIRED = 147; // 0x93
- field public static final int CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE = 108; // 0x6c
- field public static final int CODE_LOCAL_HO_NOT_FEASIBLE = 149; // 0x95
- field public static final int CODE_LOCAL_ILLEGAL_ARGUMENT = 101; // 0x65
- field public static final int CODE_LOCAL_ILLEGAL_STATE = 102; // 0x66
- field public static final int CODE_LOCAL_IMS_SERVICE_DOWN = 106; // 0x6a
- field public static final int CODE_LOCAL_INTERNAL_ERROR = 103; // 0x67
- field public static final int CODE_LOCAL_LOW_BATTERY = 112; // 0x70
- field public static final int CODE_LOCAL_NETWORK_IP_CHANGED = 124; // 0x7c
- field public static final int CODE_LOCAL_NETWORK_NO_LTE_COVERAGE = 122; // 0x7a
- field public static final int CODE_LOCAL_NETWORK_NO_SERVICE = 121; // 0x79
- field public static final int CODE_LOCAL_NETWORK_ROAMING = 123; // 0x7b
- field public static final int CODE_LOCAL_NOT_REGISTERED = 132; // 0x84
- field public static final int CODE_LOCAL_NO_PENDING_CALL = 107; // 0x6b
- field public static final int CODE_LOCAL_POWER_OFF = 111; // 0x6f
- field public static final int CODE_LOCAL_SERVICE_UNAVAILABLE = 131; // 0x83
- field public static final int CODE_LOW_BATTERY = 505; // 0x1f9
- field public static final int CODE_MAXIMUM_NUMBER_OF_CALLS_REACHED = 1403; // 0x57b
- field public static final int CODE_MEDIA_INIT_FAILED = 401; // 0x191
- field public static final int CODE_MEDIA_NOT_ACCEPTABLE = 403; // 0x193
- field public static final int CODE_MEDIA_NO_DATA = 402; // 0x192
- field public static final int CODE_MEDIA_UNSPECIFIED = 404; // 0x194
- field public static final int CODE_MULTIENDPOINT_NOT_SUPPORTED = 902; // 0x386
- field public static final int CODE_NETWORK_DETACH = 1513; // 0x5e9
- field public static final int CODE_NETWORK_REJECT = 1504; // 0x5e0
- field public static final int CODE_NETWORK_RESP_TIMEOUT = 1503; // 0x5df
- field public static final int CODE_NO_CSFB_IN_CS_ROAM = 1516; // 0x5ec
- field public static final int CODE_NO_VALID_SIM = 1501; // 0x5dd
- field public static final int CODE_OEM_CAUSE_1 = 61441; // 0xf001
- field public static final int CODE_OEM_CAUSE_10 = 61450; // 0xf00a
- field public static final int CODE_OEM_CAUSE_11 = 61451; // 0xf00b
- field public static final int CODE_OEM_CAUSE_12 = 61452; // 0xf00c
- field public static final int CODE_OEM_CAUSE_13 = 61453; // 0xf00d
- field public static final int CODE_OEM_CAUSE_14 = 61454; // 0xf00e
- field public static final int CODE_OEM_CAUSE_15 = 61455; // 0xf00f
- field public static final int CODE_OEM_CAUSE_2 = 61442; // 0xf002
- field public static final int CODE_OEM_CAUSE_3 = 61443; // 0xf003
- field public static final int CODE_OEM_CAUSE_4 = 61444; // 0xf004
- field public static final int CODE_OEM_CAUSE_5 = 61445; // 0xf005
- field public static final int CODE_OEM_CAUSE_6 = 61446; // 0xf006
- field public static final int CODE_OEM_CAUSE_7 = 61447; // 0xf007
- field public static final int CODE_OEM_CAUSE_8 = 61448; // 0xf008
- field public static final int CODE_OEM_CAUSE_9 = 61449; // 0xf009
- field public static final int CODE_RADIO_ACCESS_FAILURE = 1505; // 0x5e1
- field public static final int CODE_RADIO_INTERNAL_ERROR = 1502; // 0x5de
- field public static final int CODE_RADIO_LINK_FAILURE = 1506; // 0x5e2
- field public static final int CODE_RADIO_LINK_LOST = 1507; // 0x5e3
- field public static final int CODE_RADIO_OFF = 1500; // 0x5dc
- field public static final int CODE_RADIO_RELEASE_ABNORMAL = 1511; // 0x5e7
- field public static final int CODE_RADIO_RELEASE_NORMAL = 1510; // 0x5e6
- field public static final int CODE_RADIO_SETUP_FAILURE = 1509; // 0x5e5
- field public static final int CODE_RADIO_UPLINK_FAILURE = 1508; // 0x5e4
- field public static final int CODE_REGISTRATION_ERROR = 1000; // 0x3e8
- field public static final int CODE_REJECTED_ELSEWHERE = 1017; // 0x3f9
- field public static final int CODE_REJECT_1X_COLLISION = 1603; // 0x643
- field public static final int CODE_REJECT_CALL_ON_OTHER_SUB = 1602; // 0x642
- field public static final int CODE_REJECT_CALL_TYPE_NOT_ALLOWED = 1605; // 0x645
- field public static final int CODE_REJECT_CONFERENCE_TTY_NOT_ALLOWED = 1617; // 0x651
- field public static final int CODE_REJECT_INTERNAL_ERROR = 1612; // 0x64c
- field public static final int CODE_REJECT_MAX_CALL_LIMIT_REACHED = 1608; // 0x648
- field public static final int CODE_REJECT_ONGOING_CALL_SETUP = 1607; // 0x647
- field public static final int CODE_REJECT_ONGOING_CALL_TRANSFER = 1611; // 0x64b
- field public static final int CODE_REJECT_ONGOING_CALL_UPGRADE = 1616; // 0x650
- field public static final int CODE_REJECT_ONGOING_CALL_WAITING_DISABLED = 1601; // 0x641
- field public static final int CODE_REJECT_ONGOING_CONFERENCE_CALL = 1618; // 0x652
- field public static final int CODE_REJECT_ONGOING_CS_CALL = 1621; // 0x655
- field public static final int CODE_REJECT_ONGOING_E911_CALL = 1606; // 0x646
- field public static final int CODE_REJECT_ONGOING_ENCRYPTED_CALL = 1620; // 0x654
- field public static final int CODE_REJECT_ONGOING_HANDOVER = 1614; // 0x64e
- field public static final int CODE_REJECT_QOS_FAILURE = 1613; // 0x64d
- field public static final int CODE_REJECT_SERVICE_NOT_REGISTERED = 1604; // 0x644
- field public static final int CODE_REJECT_UNKNOWN = 1600; // 0x640
- field public static final int CODE_REJECT_UNSUPPORTED_SDP_HEADERS = 1610; // 0x64a
- field public static final int CODE_REJECT_UNSUPPORTED_SIP_HEADERS = 1609; // 0x649
- field public static final int CODE_REJECT_VT_AVPF_NOT_ALLOWED = 1619; // 0x653
- field public static final int CODE_REJECT_VT_TTY_NOT_ALLOWED = 1615; // 0x64f
- field public static final int CODE_REMOTE_CALL_DECLINE = 1404; // 0x57c
- field public static final int CODE_SESSION_MODIFICATION_FAILED = 1517; // 0x5ed
- field public static final int CODE_SIP_ALTERNATE_EMERGENCY_CALL = 1514; // 0x5ea
- field public static final int CODE_SIP_AMBIGUOUS = 376; // 0x178
- field public static final int CODE_SIP_BAD_ADDRESS = 337; // 0x151
- field public static final int CODE_SIP_BAD_REQUEST = 331; // 0x14b
- field public static final int CODE_SIP_BUSY = 338; // 0x152
- field public static final int CODE_SIP_CALL_OR_TRANS_DOES_NOT_EXIST = 372; // 0x174
- field public static final int CODE_SIP_CLIENT_ERROR = 342; // 0x156
- field public static final int CODE_SIP_EXTENSION_REQUIRED = 370; // 0x172
- field public static final int CODE_SIP_FORBIDDEN = 332; // 0x14c
- field public static final int CODE_SIP_GLOBAL_ERROR = 362; // 0x16a
- field public static final int CODE_SIP_INTERVAL_TOO_BRIEF = 371; // 0x173
- field public static final int CODE_SIP_LOOP_DETECTED = 373; // 0x175
- field public static final int CODE_SIP_METHOD_NOT_ALLOWED = 366; // 0x16e
- field public static final int CODE_SIP_NOT_ACCEPTABLE = 340; // 0x154
- field public static final int CODE_SIP_NOT_FOUND = 333; // 0x14d
- field public static final int CODE_SIP_NOT_REACHABLE = 341; // 0x155
- field public static final int CODE_SIP_NOT_SUPPORTED = 334; // 0x14e
- field public static final int CODE_SIP_PROXY_AUTHENTICATION_REQUIRED = 367; // 0x16f
- field public static final int CODE_SIP_REDIRECTED = 321; // 0x141
- field public static final int CODE_SIP_REQUEST_CANCELLED = 339; // 0x153
- field public static final int CODE_SIP_REQUEST_ENTITY_TOO_LARGE = 368; // 0x170
- field public static final int CODE_SIP_REQUEST_PENDING = 377; // 0x179
- field public static final int CODE_SIP_REQUEST_TIMEOUT = 335; // 0x14f
- field public static final int CODE_SIP_REQUEST_URI_TOO_LARGE = 369; // 0x171
- field public static final int CODE_SIP_SERVER_ERROR = 354; // 0x162
- field public static final int CODE_SIP_SERVER_INTERNAL_ERROR = 351; // 0x15f
- field public static final int CODE_SIP_SERVER_TIMEOUT = 353; // 0x161
- field public static final int CODE_SIP_SERVICE_UNAVAILABLE = 352; // 0x160
- field public static final int CODE_SIP_TEMPRARILY_UNAVAILABLE = 336; // 0x150
- field public static final int CODE_SIP_TOO_MANY_HOPS = 374; // 0x176
- field public static final int CODE_SIP_TRANSACTION_DOES_NOT_EXIST = 343; // 0x157
- field public static final int CODE_SIP_UNDECIPHERABLE = 378; // 0x17a
- field public static final int CODE_SIP_USER_MARKED_UNWANTED = 365; // 0x16d
- field public static final int CODE_SIP_USER_REJECTED = 361; // 0x169
- field public static final int CODE_SUPP_SVC_CANCELLED = 1202; // 0x4b2
- field public static final int CODE_SUPP_SVC_FAILED = 1201; // 0x4b1
- field public static final int CODE_SUPP_SVC_REINVITE_COLLISION = 1203; // 0x4b3
- field public static final int CODE_TIMEOUT_1XX_WAITING = 201; // 0xc9
- field public static final int CODE_TIMEOUT_NO_ANSWER = 202; // 0xca
- field public static final int CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE = 203; // 0xcb
- field public static final int CODE_UNSPECIFIED = 0; // 0x0
- field public static final int CODE_USER_CANCELLED_SESSION_MODIFICATION = 512; // 0x200
- field public static final int CODE_USER_DECLINE = 504; // 0x1f8
- field public static final int CODE_USER_IGNORE = 503; // 0x1f7
- field public static final int CODE_USER_NOANSWER = 502; // 0x1f6
- field public static final int CODE_USER_REJECTED_SESSION_MODIFICATION = 511; // 0x1ff
- field public static final int CODE_USER_TERMINATED = 501; // 0x1f5
- field public static final int CODE_USER_TERMINATED_BY_REMOTE = 510; // 0x1fe
- field public static final int CODE_UT_CB_PASSWORD_MISMATCH = 821; // 0x335
- field public static final int CODE_UT_NETWORK_ERROR = 804; // 0x324
- field public static final int CODE_UT_NOT_SUPPORTED = 801; // 0x321
- field public static final int CODE_UT_OPERATION_NOT_ALLOWED = 803; // 0x323
- field public static final int CODE_UT_SERVICE_UNAVAILABLE = 802; // 0x322
- field public static final int CODE_UT_SS_MODIFIED_TO_DIAL = 822; // 0x336
- field public static final int CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO = 825; // 0x339
- field public static final int CODE_UT_SS_MODIFIED_TO_SS = 824; // 0x338
- field public static final int CODE_UT_SS_MODIFIED_TO_USSD = 823; // 0x337
- field public static final int CODE_WIFI_LOST = 1407; // 0x57f
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsReasonInfo> CREATOR;
- field public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3; // 0x3
- field public static final int EXTRA_CODE_CALL_RETRY_NORMAL = 1; // 0x1
- field public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2; // 0x2
- field public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED = "Forbidden. Not Authorized for Service";
- }
-
public class ImsService extends android.app.Service {
ctor public ImsService();
method public android.telephony.ims.feature.MmTelFeature createMmTelFeature(int);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 47fd87d..39dc51e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -5001,14 +5001,15 @@
* <p>Device owner, profile owner and their delegated certificate installer can use
* {@link #ID_TYPE_BASE_INFO} to request inclusion of the general device information
* including manufacturer, model, brand, device and product in the attestation record.
- * Only device owner and their delegated certificate installer can use
- * {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI} and {@link #ID_TYPE_MEID} to request
- * unique device identifiers to be attested (the serial number, IMEI and MEID correspondingly),
- * if supported by the device (see {@link #isDeviceIdAttestationSupported()}).
- * Additionally, device owner and their delegated certificate installer can also request the
- * attestation record to be signed using an individual attestation certificate by specifying
- * the {@link #ID_TYPE_INDIVIDUAL_ATTESTATION} flag (if supported by the device, see
- * {@link #isUniqueDeviceAttestationSupported()}).
+ * Only device owner, profile owner on an organization-owned device and their delegated
+ * certificate installers can use {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI} and
+ * {@link #ID_TYPE_MEID} to request unique device identifiers to be attested (the serial number,
+ * IMEI and MEID correspondingly), if supported by the device
+ * (see {@link #isDeviceIdAttestationSupported()}).
+ * Additionally, device owner, profile owner on an organization-owned device and their delegated
+ * certificate installers can also request the attestation record to be signed using an
+ * individual attestation certificate by specifying the {@link #ID_TYPE_INDIVIDUAL_ATTESTATION}
+ * flag (if supported by the device, see {@link #isUniqueDeviceAttestationSupported()}).
* <p>
* If any of {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI} and {@link #ID_TYPE_MEID}
* is set, it is implicitly assumed that {@link #ID_TYPE_BASE_INFO} is also set.
@@ -5696,11 +5697,21 @@
* <p>
* The calling device admin must be a device owner, or alternatively a profile owner from
* Android 8.0 (API level 26) or higher. If it is not, a security exception will be thrown.
+ * <p>
+ * Staring from Android 11, this API switches to use
+ * {@link UserManager#DISALLOW_CONFIG_DATE_TIME} to enforce the auto time settings. Calling
+ * this API to enforce auto time will result in
+ * {@link UserManager#DISALLOW_CONFIG_DATE_TIME} being set, while calling this API to lift
+ * the requirement will result in {@link UserManager#DISALLOW_CONFIG_DATE_TIME} being cleared.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param required Whether auto time is set required or not.
* @throws SecurityException if {@code admin} is not a device owner.
+ * @deprecated From {@link android.os.Build.VERSION_CODES#R}. Use {@link #setAutoTime}
+ * to turn auto time on or off and use {@link UserManager#DISALLOW_CONFIG_DATE_TIME}
+ * to prevent the user from changing this setting.
*/
+ @Deprecated
public void setAutoTimeRequired(@NonNull ComponentName admin, boolean required) {
throwIfParentInstance("setAutoTimeRequired");
if (mService != null) {
@@ -5714,7 +5725,9 @@
/**
* @return true if auto time is required.
+ * @deprecated From {@link android.os.Build.VERSION_CODES#R}. Use {@link #getAutoTime}
*/
+ @Deprecated
public boolean getAutoTimeRequired() {
throwIfParentInstance("getAutoTimeRequired");
if (mService != null) {
@@ -5728,6 +5741,47 @@
}
/**
+ * Called by a device owner, a profile owner for the primary user or a profile
+ * owner of an organization-owned managed profile to turn auto time on and off.
+ * Callers are recommended to use {@link UserManager#DISALLOW_CONFIG_DATE_TIME}
+ * to prevent the user from changing this setting.
+ * <p>
+ * If user restriction {@link UserManager#DISALLOW_CONFIG_DATE_TIME} is used,
+ * no user will be able set the date and time. Instead, the network date
+ * and time will be used.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param enabled Whether time should be obtained automatically from the network or not.
+ * @throws SecurityException if caller is not a device owner, a profile owner for the
+ * primary user, or a profile owner of an organization-owned managed profile.
+ */
+ public void setAutoTime(@NonNull ComponentName admin, boolean enabled) {
+ if (mService != null) {
+ try {
+ mService.setAutoTime(admin, enabled);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * @return true if auto time is enabled on the device.
+ * @throws SecurityException if caller is not a device owner, a profile owner for the
+ * primary user, or a profile owner of an organization-owned managed profile.
+ */
+ public boolean getAutoTime(@NonNull ComponentName admin) {
+ if (mService != null) {
+ try {
+ return mService.getAutoTime(admin);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ return false;
+ }
+
+ /**
* Called by a device owner to set whether all users created on the device should be ephemeral.
* <p>
* The system user is exempt from this policy - it is never ephemeral.
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index df4b554..f55026c 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -295,6 +295,9 @@
void setAutoTimeRequired(in ComponentName who, boolean required);
boolean getAutoTimeRequired();
+ void setAutoTime(in ComponentName who, boolean enabled);
+ boolean getAutoTime(in ComponentName who);
+
void setForceEphemeralUsers(in ComponentName who, boolean forceEpehemeralUsers);
boolean getForceEphemeralUsers(in ComponentName who);
diff --git a/core/java/android/app/timezonedetector/ITimeZoneDetectorService.aidl b/core/java/android/app/timezonedetector/ITimeZoneDetectorService.aidl
index 260c7df..df643831 100644
--- a/core/java/android/app/timezonedetector/ITimeZoneDetectorService.aidl
+++ b/core/java/android/app/timezonedetector/ITimeZoneDetectorService.aidl
@@ -16,6 +16,7 @@
package android.app.timezonedetector;
+import android.app.timezonedetector.ManualTimeZoneSuggestion;
import android.app.timezonedetector.PhoneTimeZoneSuggestion;
/**
@@ -32,5 +33,6 @@
* {@hide}
*/
interface ITimeZoneDetectorService {
+ void suggestManualTimeZone(in ManualTimeZoneSuggestion timeZoneSuggestion);
void suggestPhoneTimeZone(in PhoneTimeZoneSuggestion timeZoneSuggestion);
}
diff --git a/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.aidl b/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.aidl
new file mode 100644
index 0000000..d1be86a
--- /dev/null
+++ b/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.timezonedetector;
+
+parcelable ManualTimeZoneSuggestion;
diff --git a/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java b/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java
new file mode 100644
index 0000000..a6b953b
--- /dev/null
+++ b/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.timezonedetector;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A time signal from a manual (user provided) source. The value consists of the number of
+ * milliseconds elapsed since 1/1/1970 00:00:00 UTC and the time according to the elapsed realtime
+ * clock when that number was established. The elapsed realtime clock is considered accurate but
+ * volatile, so time signals must not be persisted across device resets.
+ *
+ * @hide
+ */
+public final class ManualTimeZoneSuggestion implements Parcelable {
+
+ public static final @NonNull Creator<ManualTimeZoneSuggestion> CREATOR =
+ new Creator<ManualTimeZoneSuggestion>() {
+ public ManualTimeZoneSuggestion createFromParcel(Parcel in) {
+ return ManualTimeZoneSuggestion.createFromParcel(in);
+ }
+
+ public ManualTimeZoneSuggestion[] newArray(int size) {
+ return new ManualTimeZoneSuggestion[size];
+ }
+ };
+
+ @NonNull
+ private final String mZoneId;
+ @Nullable
+ private ArrayList<String> mDebugInfo;
+
+ public ManualTimeZoneSuggestion(@NonNull String zoneId) {
+ mZoneId = Objects.requireNonNull(zoneId);
+ }
+
+ private static ManualTimeZoneSuggestion createFromParcel(Parcel in) {
+ String zoneId = in.readString();
+ ManualTimeZoneSuggestion suggestion = new ManualTimeZoneSuggestion(zoneId);
+ @SuppressWarnings("unchecked")
+ ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */);
+ suggestion.mDebugInfo = debugInfo;
+ return suggestion;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mZoneId);
+ dest.writeList(mDebugInfo);
+ }
+
+ @NonNull
+ public String getZoneId() {
+ return mZoneId;
+ }
+
+ @NonNull
+ public List<String> getDebugInfo() {
+ return mDebugInfo == null
+ ? Collections.emptyList() : Collections.unmodifiableList(mDebugInfo);
+ }
+
+ /**
+ * Associates information with the instance that can be useful for debugging / logging. The
+ * information is present in {@link #toString()} but is not considered for
+ * {@link #equals(Object)} and {@link #hashCode()}.
+ */
+ public void addDebugInfo(String... debugInfos) {
+ if (mDebugInfo == null) {
+ mDebugInfo = new ArrayList<>();
+ }
+ mDebugInfo.addAll(Arrays.asList(debugInfos));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ManualTimeZoneSuggestion
+ that = (ManualTimeZoneSuggestion) o;
+ return Objects.equals(mZoneId, that.mZoneId);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mZoneId);
+ }
+
+ @Override
+ public String toString() {
+ return "ManualTimeSuggestion{"
+ + "mZoneId=" + mZoneId
+ + ", mDebugInfo=" + mDebugInfo
+ + '}';
+ }
+}
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 1fe1b10..accdd8d 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -17,10 +17,12 @@
package android.bluetooth;
import android.Manifest;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Binder;
@@ -439,28 +441,45 @@
* Set priority of the profile
*
* <p> The device should already be paired.
- * Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager
- * {@link #PRIORITY_OFF},
- *
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
- * permission.
+ * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
*
* @param device Paired bluetooth device
* @param priority
* @return true if priority is set, false on error
* @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
+ return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
+ }
+
+ /**
+ * Set connection policy of the profile
+ *
+ * <p> The device should already be paired.
+ * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
+ * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Paired bluetooth device
+ * @param connectionPolicy is the connection policy to set to for this profile
+ * @return true if connectionPolicy is set, false on error
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
+ @ConnectionPolicy int connectionPolicy) {
+ if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
try {
final IBluetoothA2dp service = getService();
if (service != null && isEnabled()
&& isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF
- && priority != BluetoothProfile.PRIORITY_ON) {
+ if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
+ && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
return false;
}
- return service.setPriority(device, priority);
+ return service.setConnectionPolicy(device, connectionPolicy);
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
@@ -474,8 +493,7 @@
* Get the priority of the profile.
*
* <p> The priority can be any of:
- * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
- * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
+ * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
*
* @param device Bluetooth device
* @return priority of the device
@@ -485,17 +503,35 @@
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
+ return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
+ }
+
+ /**
+ * Get the connection policy of the profile.
+ *
+ * <p> The connection policy can be any of:
+ * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
+ * {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Bluetooth device
+ * @return connection policy of the device
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
+ if (VDBG) log("getConnectionPolicy(" + device + ")");
try {
final IBluetoothA2dp service = getService();
if (service != null && isEnabled()
&& isValidDevice(device)) {
- return service.getPriority(device);
+ return service.getConnectionPolicy(device);
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
- return BluetoothProfile.PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
- return BluetoothProfile.PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
}
diff --git a/core/java/android/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java
index 5a8055a..c17834a 100755
--- a/core/java/android/bluetooth/BluetoothA2dpSink.java
+++ b/core/java/android/bluetooth/BluetoothA2dpSink.java
@@ -16,6 +16,9 @@
package android.bluetooth;
+import android.Manifest;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Binder;
@@ -317,27 +320,43 @@
* Set priority of the profile
*
* <p> The device should already be paired.
- * Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager
- * {@link #PRIORITY_OFF},
- *
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
- * permission.
+ * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
*
* @param device Paired bluetooth device
* @param priority
* @return true if priority is set, false on error
* @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
+ return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
+ }
+
+ /**
+ * Set connection policy of the profile
+ *
+ * <p> The device should already be paired.
+ * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
+ * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Paired bluetooth device
+ * @param connectionPolicy is the connection policy to set to for this profile
+ * @return true if connectionPolicy is set, false on error
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) {
+ if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
final IBluetoothA2dpSink service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF
- && priority != BluetoothProfile.PRIORITY_ON) {
+ if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
+ && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
return false;
}
try {
- return service.setPriority(device, priority);
+ return service.setConnectionPolicy(device, connectionPolicy);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
@@ -351,28 +370,44 @@
* Get the priority of the profile.
*
* <p> The priority can be any of:
- * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
- * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
- *
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+ * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
*
* @param device Bluetooth device
* @return priority of the device
* @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
+ return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
+ }
+
+ /**
+ * Get the connection policy of the profile.
+ *
+ * <p> The connection policy can be any of:
+ * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
+ * {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Bluetooth device
+ * @return connection policy of the device
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public int getConnectionPolicy(BluetoothDevice device) {
+ if (VDBG) log("getConnectionPolicy(" + device + ")");
final IBluetoothA2dpSink service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return service.getPriority(device);
+ return service.getConnectionPolicy(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
- return BluetoothProfile.PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
- return BluetoothProfile.PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
/**
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 9d152a7..9b5280d 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -27,6 +27,7 @@
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.app.ActivityThread;
+import android.bluetooth.BluetoothProfile.ConnectionPolicy;
import android.bluetooth.le.BluetoothLeAdvertiser;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.PeriodicAdvertisingManager;
@@ -456,6 +457,37 @@
@Retention(RetentionPolicy.SOURCE)
public @interface IoCapability {}
+ /** @hide */
+ @IntDef(prefix = "ACTIVE_DEVICE_", value = {ACTIVE_DEVICE_AUDIO,
+ ACTIVE_DEVICE_PHONE_CALL, ACTIVE_DEVICE_ALL})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ActiveDeviceUse {}
+
+ /**
+ * Use the specified device for audio (a2dp and hearing aid profile)
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int ACTIVE_DEVICE_AUDIO = 0;
+
+ /**
+ * Use the specified device for phone calls (headset profile and hearing
+ * aid profile)
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int ACTIVE_DEVICE_PHONE_CALL = 1;
+
+ /**
+ * Use the specified device for a2dp, hearing aid profile, and headset profile
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int ACTIVE_DEVICE_ALL = 2;
+
/**
* Broadcast Action: The local Bluetooth adapter has started the remote
* device discovery process.
@@ -1734,6 +1766,41 @@
}
/**
+ *
+ * @param device is the remote bluetooth device
+ * @param profiles represents the purpose for which we are setting this as the active device.
+ * Possible values are:
+ * {@link BluetoothAdapter#ACTIVE_DEVICE_AUDIO},
+ * {@link BluetoothAdapter#ACTIVE_DEVICE_PHONE_CALL},
+ * {@link BluetoothAdapter#ACTIVE_DEVICE_ALL}
+ * @return false on immediate error, true otherwise
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ public boolean setActiveDevice(@Nullable BluetoothDevice device,
+ @ActiveDeviceUse int profiles) {
+ if (profiles != ACTIVE_DEVICE_AUDIO && profiles != ACTIVE_DEVICE_PHONE_CALL
+ && profiles != ACTIVE_DEVICE_ALL) {
+ Log.e(TAG, "Invalid profiles param value in setActiveDevice");
+ return false;
+ }
+
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null) {
+ return mService.setActiveDevice(device, profiles);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+
+ return false;
+ }
+
+ /**
* Connects all enabled and supported bluetooth profiles between the local and remote device
*
* @param device is the remote device with which to connect these profiles
@@ -3381,4 +3448,48 @@
void onMetadataChanged(@NonNull BluetoothDevice device, int key,
@Nullable byte[] value);
}
+
+ /**
+ * Converts old constant of priority to the new for connection policy
+ *
+ * @param priority is the priority to convert to connection policy
+ * @return the equivalent connection policy constant to the priority
+ *
+ * @hide
+ */
+ public static @ConnectionPolicy int priorityToConnectionPolicy(int priority) {
+ switch(priority) {
+ case BluetoothProfile.PRIORITY_AUTO_CONNECT:
+ return BluetoothProfile.CONNECTION_POLICY_ALLOWED;
+ case BluetoothProfile.PRIORITY_ON:
+ return BluetoothProfile.CONNECTION_POLICY_ALLOWED;
+ case BluetoothProfile.PRIORITY_OFF:
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
+ case BluetoothProfile.PRIORITY_UNDEFINED:
+ return BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+ default:
+ Log.e(TAG, "setPriority: Invalid priority: " + priority);
+ return BluetoothProfile.CONNECTION_POLICY_UNKNOWN;
+ }
+ }
+
+ /**
+ * Converts new constant of connection policy to the old for priority
+ *
+ * @param connectionPolicy is the connection policy to convert to priority
+ * @return the equivalent priority constant to the connectionPolicy
+ *
+ * @hide
+ */
+ public static int connectionPolicyToPriority(@ConnectionPolicy int connectionPolicy) {
+ switch(connectionPolicy) {
+ case BluetoothProfile.CONNECTION_POLICY_ALLOWED:
+ return BluetoothProfile.PRIORITY_ON;
+ case BluetoothProfile.CONNECTION_POLICY_FORBIDDEN:
+ return BluetoothProfile.PRIORITY_OFF;
+ case BluetoothProfile.CONNECTION_POLICY_UNKNOWN:
+ return BluetoothProfile.PRIORITY_UNDEFINED;
+ }
+ return BluetoothProfile.PRIORITY_UNDEFINED;
+ }
}
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 672174f..ea3831a 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -17,6 +17,7 @@
package android.bluetooth;
import android.Manifest;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
@@ -560,26 +561,45 @@
* Priority can be one of {@link BluetoothProfile#PRIORITY_ON} or
* {@link BluetoothProfile#PRIORITY_OFF},
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
- * permission.
- *
* @param device Paired bluetooth device
* @param priority
* @return true if priority is set, false on error
* @hide
+ * @deprecated Replaced with {@link #setConnectionPolicy(BluetoothDevice, int)}
*/
+ @Deprecated
@SystemApi
@RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN)
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
+ return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
+ }
+
+ /**
+ * Set connection policy of the profile
+ *
+ * <p> The device should already be paired.
+ * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
+ * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Paired bluetooth device
+ * @param connectionPolicy is the connection policy to set to for this profile
+ * @return true if connectionPolicy is set, false on error
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
+ @ConnectionPolicy int connectionPolicy) {
+ if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
final IBluetoothHeadset service = mService;
if (service != null && isEnabled() && isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF
- && priority != BluetoothProfile.PRIORITY_ON) {
+ if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
+ && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
return false;
}
try {
- return service.setPriority(device, priority);
+ return service.setConnectionPolicy(device, connectionPolicy);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
@@ -596,26 +616,43 @@
* {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
* {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
*
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
- *
* @param device Bluetooth device
* @return priority of the device
* @hide
*/
@UnsupportedAppUsage
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
+ return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
+ }
+
+ /**
+ * Get the connection policy of the profile.
+ *
+ * <p> The connection policy can be any of:
+ * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
+ * {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Bluetooth device
+ * @return connection policy of the device
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
+ if (VDBG) log("getConnectionPolicy(" + device + ")");
final IBluetoothHeadset service = mService;
if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return service.getPriority(device);
+ return service.getConnectionPolicy(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
- return PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
- return PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
/**
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index 5d00f09..a8e1fd2 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -16,6 +16,9 @@
package android.bluetooth;
+import android.Manifest;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Binder;
@@ -553,19 +556,45 @@
/**
* Set priority of the profile
*
- * The device should already be paired.
+ * <p> The device should already be paired.
+ * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
+ *
+ * @param device Paired bluetooth device
+ * @param priority
+ * @return true if priority is set, false on error
+ * @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
+ return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
+ }
+
+ /**
+ * Set connection policy of the profile
+ *
+ * <p> The device should already be paired.
+ * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
+ * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Paired bluetooth device
+ * @param connectionPolicy is the connection policy to set to for this profile
+ * @return true if connectionPolicy is set, false on error
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) {
+ if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
final IBluetoothHeadsetClient service =
getService();
if (service != null && isEnabled() && isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF
- && priority != BluetoothProfile.PRIORITY_ON) {
+ if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
+ && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
return false;
}
try {
- return service.setPriority(device, priority);
+ return service.setConnectionPolicy(device, connectionPolicy);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
@@ -577,21 +606,47 @@
/**
* Get the priority of the profile.
+ *
+ * <p> The priority can be any of:
+ * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
+ *
+ * @param device Bluetooth device
+ * @return priority of the device
+ * @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
+ return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
+ }
+
+ /**
+ * Get the connection policy of the profile.
+ *
+ * <p> The connection policy can be any of:
+ * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
+ * {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Bluetooth device
+ * @return connection policy of the device
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public int getConnectionPolicy(BluetoothDevice device) {
+ if (VDBG) log("getConnectionPolicy(" + device + ")");
final IBluetoothHeadsetClient service =
getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return service.getPriority(device);
+ return service.getConnectionPolicy(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
- return PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
- return PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
/**
diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java
index a812c32..ead8429 100644
--- a/core/java/android/bluetooth/BluetoothHearingAid.java
+++ b/core/java/android/bluetooth/BluetoothHearingAid.java
@@ -22,6 +22,7 @@
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Binder;
@@ -355,28 +356,45 @@
* Set priority of the profile
*
* <p> The device should already be paired.
- * Priority can be one of {@link #PRIORITY_ON} orgetBluetoothManager
- * {@link #PRIORITY_OFF},
- *
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
- * permission.
+ * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
*
* @param device Paired bluetooth device
* @param priority
* @return true if priority is set, false on error
* @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
+ return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
+ }
+
+ /**
+ * Set connection policy of the profile
+ *
+ * <p> The device should already be paired.
+ * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
+ * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Paired bluetooth device
+ * @param connectionPolicy is the connection policy to set to for this profile
+ * @return true if connectionPolicy is set, false on error
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
+ @ConnectionPolicy int connectionPolicy) {
+ if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
final IBluetoothHearingAid service = getService();
try {
if (service != null && isEnabled()
&& isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF
- && priority != BluetoothProfile.PRIORITY_ON) {
+ if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
+ && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
return false;
}
- return service.setPriority(device, priority);
+ return service.setConnectionPolicy(device, connectionPolicy);
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
return false;
@@ -390,8 +408,7 @@
* Get the priority of the profile.
*
* <p> The priority can be any of:
- * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
- * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
+ * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
*
* @param device Bluetooth device
* @return priority of the device
@@ -400,17 +417,35 @@
@RequiresPermission(Manifest.permission.BLUETOOTH)
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
+ return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
+ }
+
+ /**
+ * Get the connection policy of the profile.
+ *
+ * <p> The connection policy can be any of:
+ * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
+ * {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Bluetooth device
+ * @return connection policy of the device
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public @ConnectionPolicy int getConnectionPolicy(@NonNull BluetoothDevice device) {
+ if (VDBG) log("getConnectionPolicy(" + device + ")");
final IBluetoothHearingAid service = getService();
try {
if (service != null && isEnabled()
&& isValidDevice(device)) {
- return service.getPriority(device);
+ return service.getConnectionPolicy(device);
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
- return BluetoothProfile.PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
- return BluetoothProfile.PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
}
diff --git a/core/java/android/bluetooth/BluetoothHidHost.java b/core/java/android/bluetooth/BluetoothHidHost.java
index 4afb382..8f5cdf0 100644
--- a/core/java/android/bluetooth/BluetoothHidHost.java
+++ b/core/java/android/bluetooth/BluetoothHidHost.java
@@ -16,8 +16,11 @@
package android.bluetooth;
+import android.Manifest;
+import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
@@ -379,27 +382,43 @@
* Set priority of the profile
*
* <p> The device should already be paired.
- * Priority can be one of {@link #PRIORITY_ON} or
- * {@link #PRIORITY_OFF},
- *
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
- * permission.
+ * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
*
* @param device Paired bluetooth device
* @param priority
* @return true if priority is set, false on error
* @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
+ return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
+ }
+
+ /**
+ * Set connection policy of the profile
+ *
+ * <p> The device should already be paired.
+ * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
+ * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Paired bluetooth device
+ * @param connectionPolicy is the connection policy to set to for this profile
+ * @return true if connectionPolicy is set, false on error
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) {
+ if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
final IBluetoothHidHost service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF
- && priority != BluetoothProfile.PRIORITY_ON) {
+ if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
+ && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
return false;
}
try {
- return service.setPriority(device, priority);
+ return service.setConnectionPolicy(device, connectionPolicy);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
return false;
@@ -413,28 +432,44 @@
* Get the priority of the profile.
*
* <p> The priority can be any of:
- * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
- * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
- *
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
+ * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
*
* @param device Bluetooth device
* @return priority of the device
* @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
+ return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
+ }
+
+ /**
+ * Get the connection policy of the profile.
+ *
+ * <p> The connection policy can be any of:
+ * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
+ * {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Bluetooth device
+ * @return connection policy of the device
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public int getConnectionPolicy(BluetoothDevice device) {
+ if (VDBG) log("getConnectionPolicy(" + device + ")");
final IBluetoothHidHost service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return service.getPriority(device);
+ return service.getConnectionPolicy(device);
} catch (RemoteException e) {
Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
- return BluetoothProfile.PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
- return BluetoothProfile.PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
private boolean isEnabled() {
diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java
index dd2f150..979dfd4 100644
--- a/core/java/android/bluetooth/BluetoothMap.java
+++ b/core/java/android/bluetooth/BluetoothMap.java
@@ -16,6 +16,9 @@
package android.bluetooth;
+import android.Manifest;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Binder;
@@ -271,23 +274,43 @@
* Set priority of the profile
*
* <p> The device should already be paired.
- * Priority can be one of {@link #PRIORITY_ON} or
- * {@link #PRIORITY_OFF},
+ * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
*
* @param device Paired bluetooth device
* @param priority
* @return true if priority is set, false on error
+ * @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
+ return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
+ }
+
+ /**
+ * Set connection policy of the profile
+ *
+ * <p> The device should already be paired.
+ * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
+ * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Paired bluetooth device
+ * @param connectionPolicy is the connection policy to set to for this profile
+ * @return true if connectionPolicy is set, false on error
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) {
+ if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
final IBluetoothMap service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF
- && priority != BluetoothProfile.PRIORITY_ON) {
+ if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
+ && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
return false;
}
try {
- return service.setPriority(device, priority);
+ return service.setConnectionPolicy(device, connectionPolicy);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
@@ -301,25 +324,44 @@
* Get the priority of the profile.
*
* <p> The priority can be any of:
- * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
- * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
+ * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
*
* @param device Bluetooth device
* @return priority of the device
+ * @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
+ return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
+ }
+
+ /**
+ * Get the connection policy of the profile.
+ *
+ * <p> The connection policy can be any of:
+ * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
+ * {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Bluetooth device
+ * @return connection policy of the device
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public int getConnectionPolicy(BluetoothDevice device) {
+ if (VDBG) log("getConnectionPolicy(" + device + ")");
final IBluetoothMap service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return service.getPriority(device);
+ return service.getConnectionPolicy(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
- return PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
- return PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
private static void log(String msg) {
diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java
index 69682c6..0ec473c 100644
--- a/core/java/android/bluetooth/BluetoothMapClient.java
+++ b/core/java/android/bluetooth/BluetoothMapClient.java
@@ -16,6 +16,9 @@
package android.bluetooth;
+import android.Manifest;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.app.PendingIntent;
import android.content.Context;
@@ -240,22 +243,44 @@
/**
* Set priority of the profile
*
- * <p> The device should already be paired. Priority can be one of {@link #PRIORITY_ON} or
- * {@link #PRIORITY_OFF},
+ * <p> The device should already be paired.
+ * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
*
* @param device Paired bluetooth device
+ * @param priority
* @return true if priority is set, false on error
+ * @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) Log.d(TAG, "setPriority(" + device + ", " + priority + ")");
+ return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
+ }
+
+ /**
+ * Set connection policy of the profile
+ *
+ * <p> The device should already be paired.
+ * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
+ * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Paired bluetooth device
+ * @param connectionPolicy is the connection policy to set to for this profile
+ * @return true if connectionPolicy is set, false on error
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) {
+ if (DBG) Log.d(TAG, "setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
final IBluetoothMapClient service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF
- && priority != BluetoothProfile.PRIORITY_ON) {
+ if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
+ && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
return false;
}
try {
- return service.setPriority(device, priority);
+ return service.setConnectionPolicy(device, connectionPolicy);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
@@ -269,25 +294,44 @@
* Get the priority of the profile.
*
* <p> The priority can be any of:
- * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
- * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
+ * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
*
* @param device Bluetooth device
* @return priority of the device
+ * @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public int getPriority(BluetoothDevice device) {
if (VDBG) Log.d(TAG, "getPriority(" + device + ")");
+ return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
+ }
+
+ /**
+ * Get the connection policy of the profile.
+ *
+ * <p> The connection policy can be any of:
+ * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
+ * {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Bluetooth device
+ * @return connection policy of the device
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public int getConnectionPolicy(BluetoothDevice device) {
+ if (VDBG) Log.d(TAG, "getConnectionPolicy(" + device + ")");
final IBluetoothMapClient service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return service.getPriority(device);
+ return service.getConnectionPolicy(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
- return PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
- return PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
/**
diff --git a/core/java/android/bluetooth/BluetoothPbapClient.java b/core/java/android/bluetooth/BluetoothPbapClient.java
index d70e1e7..9618ba0 100644
--- a/core/java/android/bluetooth/BluetoothPbapClient.java
+++ b/core/java/android/bluetooth/BluetoothPbapClient.java
@@ -16,6 +16,9 @@
package android.bluetooth;
+import android.Manifest;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
@@ -241,25 +244,45 @@
* Set priority of the profile
*
* <p> The device should already be paired.
- * Priority can be one of {@link #PRIORITY_ON} or
- * {@link #PRIORITY_OFF},
+ * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
*
* @param device Paired bluetooth device
- * @param priority Priority of this profile
+ * @param priority
* @return true if priority is set, false on error
+ * @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean setPriority(BluetoothDevice device, int priority) {
+ if (DBG) log("setPriority(" + device + ", " + priority + ")");
+ return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
+ }
+
+ /**
+ * Set connection policy of the profile
+ *
+ * <p> The device should already be paired.
+ * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
+ * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Paired bluetooth device
+ * @param connectionPolicy is the connection policy to set to for this profile
+ * @return true if connectionPolicy is set, false on error
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) {
if (DBG) {
- log("setPriority(" + device + ", " + priority + ")");
+ log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
}
final IBluetoothPbapClient service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF
- && priority != BluetoothProfile.PRIORITY_ON) {
+ if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
+ && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
return false;
}
try {
- return service.setPriority(device, priority);
+ return service.setConnectionPolicy(device, connectionPolicy);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
@@ -275,28 +298,47 @@
* Get the priority of the profile.
*
* <p> The priority can be any of:
- * {@link #PRIORITY_AUTO_CONNECT}, {@link #PRIORITY_OFF},
- * {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
+ * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
*
* @param device Bluetooth device
* @return priority of the device
+ * @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public int getPriority(BluetoothDevice device) {
+ if (VDBG) log("getPriority(" + device + ")");
+ return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
+ }
+
+ /**
+ * Get the connection policy of the profile.
+ *
+ * <p> The connection policy can be any of:
+ * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
+ * {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Bluetooth device
+ * @return connection policy of the device
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public int getConnectionPolicy(BluetoothDevice device) {
if (VDBG) {
- log("getPriority(" + device + ")");
+ log("getConnectionPolicy(" + device + ")");
}
final IBluetoothPbapClient service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return service.getPriority(device);
+ return service.getConnectionPolicy(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
- return PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
}
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
}
- return PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
}
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index f1ac765..097a367 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -225,7 +225,9 @@
* and outgoing connections for the profile
*
* @hide
+ * @deprecated Replaced with {@link #CONNECTION_POLICY_ALLOWED}
**/
+ @Deprecated
@SystemApi
int PRIORITY_ON = 100;
@@ -234,7 +236,9 @@
* connections and outgoing connections for the profile.
*
* @hide
+ * @deprecated Replaced with {@link #CONNECTION_POLICY_FORBIDDEN}
**/
+ @Deprecated
@SystemApi
int PRIORITY_OFF = 0;
@@ -246,6 +250,38 @@
@UnsupportedAppUsage
int PRIORITY_UNDEFINED = -1;
+ /** @hide */
+ @IntDef(prefix = "CONNECTION_POLICY_", value = {CONNECTION_POLICY_ALLOWED,
+ CONNECTION_POLICY_FORBIDDEN, CONNECTION_POLICY_UNKNOWN})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ConnectionPolicy{}
+
+ /**
+ * Default connection policy for devices that allow incoming and outgoing connections
+ * for the profile
+ *
+ * @hide
+ **/
+ @SystemApi
+ int CONNECTION_POLICY_ALLOWED = 100;
+
+ /**
+ * Default connection policy for devices that do not allow incoming or outgoing connections
+ * for the profile.
+ *
+ * @hide
+ **/
+ @SystemApi
+ int CONNECTION_POLICY_FORBIDDEN = 0;
+
+ /**
+ * Default connection policy when not set or when the device is unpaired
+ *
+ * @hide
+ */
+ @SystemApi
+ int CONNECTION_POLICY_UNKNOWN = -1;
+
/**
* Get connected devices for this specific profile.
*
diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java
index e0610c8..9b4dabc 100644
--- a/core/java/android/bluetooth/BluetoothSap.java
+++ b/core/java/android/bluetooth/BluetoothSap.java
@@ -16,6 +16,9 @@
package android.bluetooth;
+import android.Manifest;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Binder;
@@ -300,22 +303,43 @@
* Set priority of the profile
*
* <p> The device should already be paired.
+ * Priority can be one of {@link #PRIORITY_ON} or {@link #PRIORITY_OFF},
*
* @param device Paired bluetooth device
* @param priority
* @return true if priority is set, false on error
* @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean setPriority(BluetoothDevice device, int priority) {
if (DBG) log("setPriority(" + device + ", " + priority + ")");
+ return setConnectionPolicy(device, BluetoothAdapter.priorityToConnectionPolicy(priority));
+ }
+
+ /**
+ * Set connection policy of the profile
+ *
+ * <p> The device should already be paired.
+ * Connection policy can be one of {@link #CONNECTION_POLICY_ALLOWED},
+ * {@link #CONNECTION_POLICY_FORBIDDEN}, {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Paired bluetooth device
+ * @param connectionPolicy is the connection policy to set to for this profile
+ * @return true if connectionPolicy is set, false on error
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+ public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) {
+ if (DBG) log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
final IBluetoothSap service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
- if (priority != BluetoothProfile.PRIORITY_OFF
- && priority != BluetoothProfile.PRIORITY_ON) {
+ if (connectionPolicy != BluetoothProfile.CONNECTION_POLICY_FORBIDDEN
+ && connectionPolicy != BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
return false;
}
try {
- return service.setPriority(device, priority);
+ return service.setConnectionPolicy(device, connectionPolicy);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
return false;
@@ -328,23 +352,45 @@
/**
* Get the priority of the profile.
*
+ * <p> The priority can be any of:
+ * {@link #PRIORITY_OFF}, {@link #PRIORITY_ON}, {@link #PRIORITY_UNDEFINED}
+ *
* @param device Bluetooth device
* @return priority of the device
* @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
+ return BluetoothAdapter.connectionPolicyToPriority(getConnectionPolicy(device));
+ }
+
+ /**
+ * Get the connection policy of the profile.
+ *
+ * <p> The connection policy can be any of:
+ * {@link #CONNECTION_POLICY_ALLOWED}, {@link #CONNECTION_POLICY_FORBIDDEN},
+ * {@link #CONNECTION_POLICY_UNKNOWN}
+ *
+ * @param device Bluetooth device
+ * @return connection policy of the device
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ public int getConnectionPolicy(BluetoothDevice device) {
+ if (VDBG) log("getConnectionPolicy(" + device + ")");
final IBluetoothSap service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
try {
- return service.getPriority(device);
+ return service.getConnectionPolicy(device);
} catch (RemoteException e) {
Log.e(TAG, Log.getStackTraceString(new Throwable()));
- return PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
}
if (service == null) Log.w(TAG, "Proxy not attached to service");
- return PRIORITY_OFF;
+ return BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
}
private static void log(String msg) {
diff --git a/core/java/android/hardware/camera2/legacy/RequestQueue.java b/core/java/android/hardware/camera2/legacy/RequestQueue.java
index 407e5e6..fb44402 100644
--- a/core/java/android/hardware/camera2/legacy/RequestQueue.java
+++ b/core/java/android/hardware/camera2/legacy/RequestQueue.java
@@ -30,7 +30,7 @@
public class RequestQueue {
private static final String TAG = "RequestQueue";
- private static final long INVALID_FRAME = -1;
+ public static final long INVALID_FRAME = -1;
private BurstHolder mRepeatingRequest = null;
private final ArrayDeque<BurstHolder> mRequestQueue = new ArrayDeque<BurstHolder>();
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index 32411fb..f9a5029 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -948,8 +948,13 @@
Log.d(TAG, "Stopped repeating request. Last frame number is " +
lastFrameNumber);
}
- mDeviceState.setRepeatingRequestError(lastFrameNumber,
- burstHolder.getRequestId());
+ if (lastFrameNumber != RequestQueue.INVALID_FRAME) {
+ mDeviceState.setRepeatingRequestError(lastFrameNumber,
+ burstHolder.getRequestId());
+ } else {
+ Log.e(TAG, "Repeating request id: " + burstHolder.getRequestId() +
+ " already canceled!");
+ }
}
if (DEBUG) {
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index db6211d..fc80e00 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -1909,7 +1909,9 @@
*
* @param layer The root layer to capture.
* @param sourceCrop The portion of the root surface to capture; caller may pass in 'new
- * Rect()' or null if no cropping is desired.
+ * Rect()' or null if no cropping is desired. If the root layer does not
+ * have a buffer or a crop set, then a non-empty source crop must be
+ * specified.
* @param frameScale The desired scale of the returned buffer; the raw
* screen will be scaled up/down.
*
@@ -1926,7 +1928,9 @@
*
* @param layer The root layer to capture.
* @param sourceCrop The portion of the root surface to capture; caller may pass in 'new
- * Rect()' or null if no cropping is desired.
+ * Rect()' or null if no cropping is desired. If the root layer does not
+ * have a buffer or a crop set, then a non-empty source crop must be
+ * specified.
* @param frameScale The desired scale of the returned buffer; the raw
* screen will be scaled up/down.
* @param format The desired pixel format of the returned buffer.
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 58e80c7..9e23c28 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -136,13 +136,6 @@
*/
public static final String HASH_SALT_MAX_DAYS = "hash_salt_max_days";
- // Flag related to Privacy Indicators
-
- /**
- * Whether the Permissions Hub is showing.
- */
- public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled";
-
// Flags related to Assistant
/**
diff --git a/core/proto/android/stats/devicepolicy/device_policy_enums.proto b/core/proto/android/stats/devicepolicy/device_policy_enums.proto
index 15813a1..f8c304c 100644
--- a/core/proto/android/stats/devicepolicy/device_policy_enums.proto
+++ b/core/proto/android/stats/devicepolicy/device_policy_enums.proto
@@ -151,4 +151,5 @@
PROVISIONING_FLOW_TYPE = 124;
CROSS_PROFILE_APPS_GET_TARGET_USER_PROFILES = 125;
CROSS_PROFILE_APPS_START_ACTIVITY_AS_USER = 126;
+ SET_AUTO_TIME = 127;
}
diff --git a/core/tests/coretests/src/android/app/timezonedetector/ManualTimeZoneSuggestionTest.java b/core/tests/coretests/src/android/app/timezonedetector/ManualTimeZoneSuggestionTest.java
new file mode 100644
index 0000000..02ed0ed
--- /dev/null
+++ b/core/tests/coretests/src/android/app/timezonedetector/ManualTimeZoneSuggestionTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.timezonedetector;
+
+import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
+import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import org.junit.Test;
+
+public class ManualTimeZoneSuggestionTest {
+
+ private static final String ARBITRARY_ZONE_ID1 = "Europe/London";
+ private static final String ARBITRARY_ZONE_ID2 = "Europe/Paris";
+
+ @Test
+ public void testEquals() {
+ ManualTimeZoneSuggestion one = new ManualTimeZoneSuggestion(ARBITRARY_ZONE_ID1);
+ assertEquals(one, one);
+
+ ManualTimeZoneSuggestion two = new ManualTimeZoneSuggestion(ARBITRARY_ZONE_ID1);
+ assertEquals(one, two);
+ assertEquals(two, one);
+
+ ManualTimeZoneSuggestion three = new ManualTimeZoneSuggestion(ARBITRARY_ZONE_ID2);
+ assertNotEquals(one, three);
+ assertNotEquals(three, one);
+
+ // DebugInfo must not be considered in equals().
+ one.addDebugInfo("Debug info 1");
+ two.addDebugInfo("Debug info 2");
+ assertEquals(one, two);
+ }
+
+ @Test
+ public void testParcelable() {
+ ManualTimeZoneSuggestion suggestion = new ManualTimeZoneSuggestion(ARBITRARY_ZONE_ID1);
+ assertRoundTripParcelable(suggestion);
+
+ // DebugInfo should also be stored (but is not checked by equals()
+ suggestion.addDebugInfo("This is debug info");
+ ManualTimeZoneSuggestion rtSuggestion = roundTripParcelable(suggestion);
+ assertEquals(suggestion.getDebugInfo(), rtSuggestion.getDebugInfo());
+ }
+}
diff --git a/core/tests/coretests/src/android/app/timezonedetector/ParcelableTestSupport.java b/core/tests/coretests/src/android/app/timezonedetector/ParcelableTestSupport.java
new file mode 100644
index 0000000..0073d86
--- /dev/null
+++ b/core/tests/coretests/src/android/app/timezonedetector/ParcelableTestSupport.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.timezonedetector;
+
+import static org.junit.Assert.assertEquals;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.reflect.Field;
+
+/** Utility methods related to {@link Parcelable} objects used in several tests. */
+public final class ParcelableTestSupport {
+
+ private ParcelableTestSupport() {}
+
+ /** Returns the result of parceling and unparceling the argument. */
+ @SuppressWarnings("unchecked")
+ public static <T extends Parcelable> T roundTripParcelable(T parcelable) {
+ Parcel parcel = Parcel.obtain();
+ parcel.writeTypedObject(parcelable, 0);
+ parcel.setDataPosition(0);
+
+ Parcelable.Creator<T> creator;
+ try {
+ Field creatorField = parcelable.getClass().getField("CREATOR");
+ creator = (Parcelable.Creator<T>) creatorField.get(null);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new AssertionError(e);
+ }
+ T toReturn = parcel.readTypedObject(creator);
+ parcel.recycle();
+ return toReturn;
+ }
+
+ public static <T extends Parcelable> void assertRoundTripParcelable(T instance) {
+ assertEquals(instance, roundTripParcelable(instance));
+ }
+}
diff --git a/core/tests/coretests/src/android/app/timezonedetector/PhoneTimeZoneSuggestionTest.java b/core/tests/coretests/src/android/app/timezonedetector/PhoneTimeZoneSuggestionTest.java
index ae91edc..0108a0b 100644
--- a/core/tests/coretests/src/android/app/timezonedetector/PhoneTimeZoneSuggestionTest.java
+++ b/core/tests/coretests/src/android/app/timezonedetector/PhoneTimeZoneSuggestionTest.java
@@ -16,13 +16,13 @@
package android.app.timezonedetector;
+import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
+import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
-import android.os.Parcel;
-import android.os.Parcelable;
-
import org.junit.Test;
public class PhoneTimeZoneSuggestionTest {
@@ -152,19 +152,4 @@
assertEquals(suggestion1, suggestion1_2);
assertTrue(suggestion1_2.getDebugInfo().contains(debugString));
}
-
- private static void assertRoundTripParcelable(PhoneTimeZoneSuggestion instance) {
- assertEquals(instance, roundTripParcelable(instance));
- }
-
- @SuppressWarnings("unchecked")
- private static <T extends Parcelable> T roundTripParcelable(T one) {
- Parcel parcel = Parcel.obtain();
- parcel.writeTypedObject(one, 0);
- parcel.setDataPosition(0);
-
- T toReturn = (T) parcel.readTypedObject(PhoneTimeZoneSuggestion.CREATOR);
- parcel.recycle();
- return toReturn;
- }
}
diff --git a/packages/CarSystemUI/res/values/dimens.xml b/packages/CarSystemUI/res/values/dimens.xml
index ee79653..f68d034 100644
--- a/packages/CarSystemUI/res/values/dimens.xml
+++ b/packages/CarSystemUI/res/values/dimens.xml
@@ -60,21 +60,6 @@
<dimen name="car_keyline_2">96dp</dimen>
<dimen name="car_keyline_3">128dp</dimen>
- <!-- Height of icons in Ongoing App Ops dialog. Both App Op icon and application icon -->
- <dimen name="ongoing_appops_dialog_icon_height">48dp</dimen>
- <!-- Margin between text lines in Ongoing App Ops dialog -->
- <dimen name="ongoing_appops_dialog_text_margin">15dp</dimen>
- <!-- Padding around Ongoing App Ops dialog content -->
- <dimen name="ongoing_appops_dialog_content_padding">24dp</dimen>
- <!-- Margins around the Ongoing App Ops chip. In landscape, the side margins are 0 -->
- <dimen name="ongoing_appops_chip_margin">12dp</dimen>
- <!-- Start and End padding for Ongoing App Ops chip -->
- <dimen name="ongoing_appops_chip_side_padding">6dp</dimen>
- <!-- Padding between background of Ongoing App Ops chip and content -->
- <dimen name="ongoing_appops_chip_bg_padding">4dp</dimen>
- <!-- Radius of Ongoing App Ops chip corners -->
- <dimen name="ongoing_appops_chip_bg_corner_radius">12dp</dimen>
-
<!-- Car volume dimens. -->
<dimen name="car_volume_item_icon_size">@dimen/car_primary_icon_size</dimen>
<dimen name="car_volume_item_height">@*android:dimen/car_single_line_list_item_height</dimen>
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
index 9a7c373..c9ac765 100644
--- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
+++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
@@ -296,7 +296,7 @@
mShowing = true;
clearAllAndSetupDefaultCarVolumeLineItem(mCurrentlyDisplayingGroupId);
mDialog.show();
- Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
+ Events.writeEvent(Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
}
private void clearAllAndSetupDefaultCarVolumeLineItem(int groupId) {
@@ -359,7 +359,7 @@
}, DISMISS_DELAY_IN_MILLIS))
.start();
- Events.writeEvent(mContext, Events.EVENT_DISMISS_DIALOG, reason);
+ Events.writeEvent(Events.EVENT_DISMISS_DIALOG, reason);
}
private void loadAudioUsageItems() {
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
index 9672fea..9f16d03 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
@@ -408,23 +408,6 @@
}
/**
- * Checks if {@link android.app.admin.DevicePolicyManager#setAutoTimeRequired} is enforced
- * on the device.
- *
- * @return EnforcedAdmin Object containing the device owner component and
- * userId the device owner is running as, or {@code null} setAutoTimeRequired is not enforced.
- */
- public static EnforcedAdmin checkIfAutoTimeRequired(Context context) {
- DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
- Context.DEVICE_POLICY_SERVICE);
- if (dpm == null || !dpm.getAutoTimeRequired()) {
- return null;
- }
- ComponentName adminComponent = dpm.getDeviceOwnerComponentOnCallingUser();
- return new EnforcedAdmin(adminComponent, getUserHandleOf(UserHandle.myUserId()));
- }
-
- /**
* Checks if an admin has enforced minimum password quality requirements on the given user.
*
* @return EnforcedAdmin Object containing the enforced admin component and admin user details,
diff --git a/packages/SystemUI/res/drawable/privacy_chip_bg.xml b/packages/SystemUI/res/drawable/privacy_chip_bg.xml
deleted file mode 100644
index b7b21fa..0000000
--- a/packages/SystemUI/res/drawable/privacy_chip_bg.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2018 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.
--->
-
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="#242424" /> <!-- 14% of white -->
- <padding android:paddingTop="@dimen/ongoing_appops_chip_bg_padding"
- android:paddingBottom="@dimen/ongoing_appops_chip_bg_padding" />
- <corners android:radius="@dimen/ongoing_appops_chip_bg_corner_radius" />
-</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
deleted file mode 100644
index dce9ce1..0000000
--- a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2018 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.
--->
-
-
-<com.android.systemui.privacy.OngoingPrivacyChip
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/privacy_chip"
- android:layout_height="match_parent"
- android:layout_width="wrap_content"
- android:layout_gravity="center_vertical|end"
- android:gravity="center_vertical"
- android:orientation="horizontal"
- android:focusable="true" >
-
- <FrameLayout
- android:id="@+id/background"
- android:layout_height="@dimen/ongoing_appops_chip_height"
- android:minWidth="48dp"
- android:layout_width="wrap_content" >
- <LinearLayout
- android:id="@+id/icons_container"
- android:layout_height="match_parent"
- android:layout_width="wrap_content"
- android:gravity="center_vertical"
- />
- </FrameLayout>
-</com.android.systemui.privacy.OngoingPrivacyChip>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/ongoing_privacy_text_item.xml b/packages/SystemUI/res/layout/ongoing_privacy_text_item.xml
deleted file mode 100644
index 5595b13..0000000
--- a/packages/SystemUI/res/layout/ongoing_privacy_text_item.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2018 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.
--->
-
-<TextView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textDirection="locale"
- android:textAppearance="@style/TextAppearance.QS.DetailItemPrimary"
-/>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
index cd9f780..8676767 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
@@ -14,7 +14,7 @@
** See the License for the specific language governing permissions and
** limitations under the License.
-->
-<LinearLayout
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/quick_status_bar_system_icons"
@@ -28,13 +28,6 @@
android:paddingStart="@dimen/status_bar_padding_start"
android:paddingEnd="@dimen/status_bar_padding_end" >
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:orientation="horizontal"
- android:gravity="center_vertical|start" >
-
<com.android.systemui.statusbar.policy.Clock
android:id="@+id/clock"
android:layout_width="wrap_content"
@@ -46,23 +39,5 @@
android:singleLine="true"
android:textAppearance="@style/TextAppearance.StatusBar.Clock"
systemui:showDark="false" />
- </LinearLayout>
- <android.widget.Space
- android:id="@+id/space"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical|center_horizontal"
- android:visibility="gone" />
-
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:orientation="horizontal"
- android:gravity="center_vertical|end" >
-
- <include layout="@layout/ongoing_privacy_chip" />
-
- </LinearLayout>
-</LinearLayout>
+</FrameLayout>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 076cd22..e896c16 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -462,8 +462,6 @@
<item>com.android.systemui</item>
</string-array>
- <integer name="ongoing_appops_dialog_max_apps">5</integer>
-
<!-- Launcher package name for overlaying icons. -->
<string name="launcher_overlayable_package" translatable="false">com.android.launcher3</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1a05ec1..c948116 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1067,47 +1067,6 @@
<!-- How much into a DisplayCutout's bounds we can go, on each side -->
<dimen name="display_cutout_margin_consumption">0px</dimen>
-
- <!-- Padding below Ongoing App Ops dialog title -->
- <dimen name="ongoing_appops_dialog_sep">16dp</dimen>
- <!--Padding around text items in Ongoing App Ops dialog -->
- <dimen name="ongoing_appops_dialog_text_padding">16dp</dimen>
- <!-- Height and width of App Opp icons in Ongoing App Ops dialog -->
- <dimen name="ongoing_appops_dialog_icon_size">24dp</dimen>
- <!-- Left margin of App Opp icons in Ongoing App Ops dialog -->
- <dimen name="ongoing_appops_dialog_icon_margin">12dp</dimen>
- <!-- Height and width of Application icons in Ongoing App Ops dialog -->
- <dimen name="ongoing_appops_dialog_app_icon_size">32dp</dimen>
- <!-- Height and width of Plus sign in Ongoing App Ops dialog -->
- <dimen name="ongoing_appops_dialog_app_plus_size">24dp</dimen>
- <!-- Height of line in Ongoing App Ops dialog-->
- <dimen name="ongoing_appops_dialog_line_height">48dp</dimen>
- <!-- Side margin of title in Ongoing App Ops dialog -->
- <dimen name="ongoing_appops_dialog_title_margin_sides">24dp</dimen>
- <!-- Bottom margin of items in Ongoing App Ops dialog -->
- <dimen name="ongoing_appops_dialog_items_bottom_margin">24dp</dimen>
- <!-- Top and bottom margin of title in Ongoing App Ops dialog -->
- <dimen name="ongoing_appops_dialog_title_margin_top_bottom">18dp</dimen>
- <!-- Text size for Ongoing App Ops dialog title -->
- <dimen name="ongoing_appops_dialog_title_size">20sp</dimen>
- <!-- Text size for Ongoing App Ops dialog items -->
- <dimen name="ongoing_appops_dialog_item_size">16sp</dimen>
- <!-- Height of the Ongoing App Ops chip -->
- <dimen name="ongoing_appops_chip_height">32dp</dimen>
- <!-- Padding between background of Ongoing App Ops chip and content -->
- <dimen name="ongoing_appops_chip_bg_padding">8dp</dimen>
- <!-- Side padding between background of Ongoing App Ops chip and content -->
- <dimen name="ongoing_appops_chip_side_padding">8dp</dimen>
- <!-- Margin between icons of Ongoing App Ops chip when QQS-->
- <dimen name="ongoing_appops_chip_icon_margin_collapsed">0dp</dimen>
- <!-- Margin between icons of Ongoing App Ops chip when QS-->
- <dimen name="ongoing_appops_chip_icon_margin_expanded">2dp</dimen>
- <!-- Icon size of Ongoing App Ops chip -->
- <dimen name="ongoing_appops_chip_icon_size">@dimen/status_bar_icon_drawing_size</dimen>
- <!-- Radius of Ongoing App Ops chip corners -->
- <dimen name="ongoing_appops_chip_bg_corner_radius">16dp</dimen>
-
-
<!-- How much each bubble is elevated. -->
<dimen name="bubble_elevation">1dp</dimen>
<!-- How much the bubble flyout text container is elevated. -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 99da058..1dd5496 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2444,27 +2444,6 @@
app for debugging. Will not be seen by users. [CHAR LIMIT=20] -->
<string name="heap_dump_tile_name">Dump SysUI Heap</string>
- <!-- Content description for ongoing privacy chip. Use with a single app [CHAR LIMIT=NONE]-->
- <string name="ongoing_privacy_chip_content_single_app"><xliff:g id="app" example="Example App">%1$s</xliff:g> is using your <xliff:g id="types_list" example="camera, location">%2$s</xliff:g>.</string>
-
- <!-- Content description for ongoing privacy chip. Use with multiple apps [CHAR LIMIT=NONE]-->
- <string name="ongoing_privacy_chip_content_multiple_apps">Applications are using your <xliff:g id="types_list" example="camera, location">%s</xliff:g>.</string>
-
- <!-- Separator for types. Include spaces before and after if needed [CHAR LIMIT=10] -->
- <string name="ongoing_privacy_dialog_separator">,\u0020</string>
-
- <!-- Separator for types, before last type. Include spaces before and after if needed [CHAR LIMIT=10] -->
- <string name="ongoing_privacy_dialog_last_separator">\u0020and\u0020</string>
-
- <!-- Text for camera app op [CHAR LIMIT=20]-->
- <string name="privacy_type_camera">camera</string>
-
- <!-- Text for location app op [CHAR LIMIT=20]-->
- <string name="privacy_type_location">location</string>
-
- <!-- Text for microphone app op [CHAR LIMIT=20]-->
- <string name="privacy_type_microphone">microphone</string>
-
<!-- Text for the quick setting tile for sensor privacy [CHAR LIMIT=30] -->
<string name="sensor_privacy_mode">Sensors off</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 96fbcbb..926d016 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -227,18 +227,6 @@
<item name="android:textColor">@color/dark_mode_qs_icon_color_single_tone</item>
</style>
- <style name="TextAppearance.AppOpsDialog" />
-
- <style name="TextAppearance.AppOpsDialog.Title">
- <item name="android:textSize">@dimen/ongoing_appops_dialog_title_size</item>
- <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
- </style>
-
- <style name="TextAppearance.AppOpsDialog.Item">
- <item name="android:textSize">@dimen/ongoing_appops_dialog_item_size</item>
- <item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
- </style>
-
<style name="TextAppearance.DeviceManagementDialog">
<item name="android:textColor">?android:attr/textColorPrimary</item>
</style>
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index c55b0d9..6821265 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -56,7 +56,6 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.power.EnhancedEstimates;
import com.android.systemui.power.PowerUI;
-import com.android.systemui.privacy.PrivacyItemController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
import com.android.systemui.shared.plugins.PluginManager;
@@ -298,7 +297,6 @@
@Inject Lazy<SensorPrivacyManager> mSensorPrivacyManager;
@Inject Lazy<AutoHideController> mAutoHideController;
@Inject Lazy<ForegroundServiceNotificationListener> mForegroundServiceNotificationListener;
- @Inject Lazy<PrivacyItemController> mPrivacyItemController;
@Inject @BgLooper Lazy<Looper> mBgLooper;
@Inject @BgHandler Lazy<Handler> mBgHandler;
@Inject @MainLooper Lazy<Looper> mMainLooper;
@@ -497,7 +495,6 @@
mProviders.put(ForegroundServiceNotificationListener.class,
mForegroundServiceNotificationListener::get);
mProviders.put(ClockManager.class, mClockManager::get);
- mProviders.put(PrivacyItemController.class, mPrivacyItemController::get);
mProviders.put(ActivityManagerWrapper.class, mActivityManagerWrapper::get);
mProviders.put(DevicePolicyManagerWrapper.class, mDevicePolicyManagerWrapper::get);
mProviders.put(PackageManagerWrapper.class, mPackageManagerWrapper::get);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
index 044ea54..24ee9695 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
@@ -321,20 +321,6 @@
return (flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
}
- /**
- * Whether this bubble was explicitly created by the user via a SysUI affordance.
- */
- boolean isUserCreated() {
- return mIsUserCreated;
- }
-
- /**
- * Set whether this bubble was explicitly created by the user via a SysUI affordance.
- */
- void setUserCreated(boolean isUserCreated) {
- mIsUserCreated = isUserCreated;
- }
-
float getDesiredHeight(Context context) {
Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
boolean useRes = data.getDesiredHeightResId() != 0;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index db1185f..ed21e14 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -31,6 +31,7 @@
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_CONTROLLER;
+import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_EXPERIMENTS;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.systemui.statusbar.StatusBarState.SHADE;
@@ -92,6 +93,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import javax.inject.Inject;
@@ -145,6 +147,10 @@
// Saves notification keys of active bubbles when users are switched.
private final SparseSetArray<String> mSavedBubbleKeysPerUser;
+ // Saves notification keys of user created "fake" bubbles so that we can allow notifications
+ // like these to bubble by default. Doesn't persist across reboots, not a long-term solution.
+ private final HashSet<String> mUserCreatedBubbles;
+
// Bubbles get added to the status bar view
private final StatusBarWindowController mStatusBarWindowController;
private final ZenModeController mZenModeController;
@@ -312,6 +318,8 @@
restoreBubbles(newUserId);
mCurrentUserId = newUserId;
});
+
+ mUserCreatedBubbles = new HashSet<>();
}
/**
@@ -535,10 +543,13 @@
* @param entry the notification to show as a bubble.
*/
public void onUserCreatedBubbleFromNotification(NotificationEntry entry) {
+ if (DEBUG_EXPERIMENTS || DEBUG_BUBBLE_CONTROLLER) {
+ Log.d(TAG, "onUserCreatedBubble: " + entry.getKey());
+ }
mShadeController.get().collapsePanel(true);
entry.setFlagBubble(true);
updateBubble(entry, true /* suppressFlyout */, false /* showInShade */);
- mBubbleData.getBubbleWithKey(entry.getKey()).setUserCreated(true);
+ mUserCreatedBubbles.add(entry.getKey());
}
/**
@@ -548,8 +559,19 @@
* @param entry the notification to no longer show as a bubble.
*/
public void onUserDemotedBubbleFromNotification(NotificationEntry entry) {
+ if (DEBUG_EXPERIMENTS || DEBUG_BUBBLE_CONTROLLER) {
+ Log.d(TAG, "onUserDemotedBubble: " + entry.getKey());
+ }
entry.setFlagBubble(false);
removeBubble(entry.getKey(), DISMISS_BLOCKED);
+ mUserCreatedBubbles.remove(entry.getKey());
+ }
+
+ /**
+ * Whether this bubble was explicitly created by the user via a SysUI affordance.
+ */
+ boolean isUserCreatedBubble(String key) {
+ return mUserCreatedBubbles.contains(key);
}
/**
@@ -616,7 +638,8 @@
mNotificationEntryManager.updateNotifications(
"BubbleController.onNotificationRemoveRequested");
return true;
- } else if (!userRemovedNotif && entry != null && !bubble.isUserCreated()) {
+ } else if (!userRemovedNotif && entry != null
+ && !isUserCreatedBubble(bubble.getKey())) {
// This wasn't a user removal so we should remove the bubble as well
mBubbleData.notificationEntryRemoved(entry, DISMISS_NOTIF_CANCEL);
return false;
@@ -676,8 +699,8 @@
private final NotificationEntryListener mEntryListener = new NotificationEntryListener() {
@Override
public void onPendingEntryAdded(NotificationEntry entry) {
- Bubble b = mBubbleData.getBubbleWithKey(entry.getKey());
- BubbleExperimentConfig.adjustForExperiments(mContext, entry, b);
+ boolean previouslyUserCreated = mUserCreatedBubbles.contains(entry.getKey());
+ BubbleExperimentConfig.adjustForExperiments(mContext, entry, previouslyUserCreated);
if (mNotificationInterruptionStateProvider.shouldBubbleUp(entry)
&& canLaunchInActivityView(mContext, entry)) {
@@ -687,8 +710,8 @@
@Override
public void onPreEntryUpdated(NotificationEntry entry) {
- Bubble b = mBubbleData.getBubbleWithKey(entry.getKey());
- BubbleExperimentConfig.adjustForExperiments(mContext, entry, b);
+ boolean previouslyUserCreated = mUserCreatedBubbles.contains(entry.getKey());
+ BubbleExperimentConfig.adjustForExperiments(mContext, entry, previouslyUserCreated);
boolean shouldBubble = mNotificationInterruptionStateProvider.shouldBubbleUp(entry)
&& canLaunchInActivityView(mContext, entry);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java
index b702d06..a912ecc 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleDebugConfig.java
@@ -37,5 +37,6 @@
static final boolean DEBUG_BUBBLE_DATA = false;
static final boolean DEBUG_BUBBLE_STACK_VIEW = false;
static final boolean DEBUG_BUBBLE_EXPANDED_VIEW = false;
+ static final boolean DEBUG_EXPERIMENTS = true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index ea51f4a..512b38e 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -189,12 +189,10 @@
+ " mActivityViewStatus=" + mActivityViewStatus
+ " bubble=" + getBubbleKey());
}
- if (mBubble != null && !mBubble.isUserCreated()) {
- if (mBubble != null) {
- // Must post because this is called from a binder thread.
- post(() -> mBubbleController.removeBubble(mBubble.getKey(),
- BubbleController.DISMISS_TASK_FINISHED));
- }
+ if (mBubble != null && !mBubbleController.isUserCreatedBubble(mBubble.getKey())) {
+ // Must post because this is called from a binder thread.
+ post(() -> mBubbleController.removeBubble(mBubble.getKey(),
+ BubbleController.DISMISS_TASK_FINISHED));
}
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java
index 6eeb5c3..17d6737 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExperimentConfig.java
@@ -22,6 +22,9 @@
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED;
import static com.android.systemui.bubbles.BubbleController.canLaunchIntentInActivityView;
+import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_EXPERIMENTS;
+import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
+import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
import android.app.Notification;
import android.app.PendingIntent;
@@ -35,6 +38,7 @@
import android.os.Parcelable;
import android.os.UserHandle;
import android.provider.Settings;
+import android.util.Log;
import com.android.internal.util.ArrayUtils;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -47,6 +51,7 @@
* Common class for experiments controlled via secure settings.
*/
public class BubbleExperimentConfig {
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleController" : TAG_BUBBLES;
private static final String SHORTCUT_DUMMY_INTENT = "bubble_experiment_shortcut_intent";
private static PendingIntent sDummyShortcutIntent;
@@ -104,8 +109,7 @@
* the notification has necessary info for BubbleMetadata.
*/
static void adjustForExperiments(Context context, NotificationEntry entry,
- Bubble previousBubble) {
-
+ boolean previouslyUserCreated) {
Notification.BubbleMetadata metadata = null;
boolean addedMetadata = false;
@@ -118,6 +122,19 @@
boolean useShortcutInfo = useShortcutInfoToBubble(context);
String shortcutId = entry.getSbn().getNotification().getShortcutId();
+ boolean hasMetadata = entry.getBubbleMetadata() != null;
+ if ((!hasMetadata && (previouslyUserCreated || bubbleNotifForExperiment))
+ || useShortcutInfo) {
+ if (DEBUG_EXPERIMENTS) {
+ Log.d(TAG, "Adjusting " + entry.getKey() + " for bubble experiment."
+ + " allowMessages=" + allowMessageNotifsToBubble(context)
+ + " isMessage=" + isMessage
+ + " allowNotifs=" + allowAnyNotifToBubble(context)
+ + " useShortcutInfo=" + useShortcutInfo
+ + " previouslyUserCreated=" + previouslyUserCreated);
+ }
+ }
+
if (useShortcutInfo && shortcutId != null) {
// We don't actually get anything useful from ShortcutInfo so just check existence
ShortcutInfo info = getShortcutInfo(context, entry.getSbn().getPackageName(),
@@ -127,26 +144,37 @@
}
// Replace existing metadata with shortcut, or we're bubbling for experiment
- boolean shouldBubble = entry.getBubbleMetadata() != null || bubbleNotifForExperiment;
-
+ boolean shouldBubble = entry.getBubbleMetadata() != null
+ || bubbleNotifForExperiment
+ || previouslyUserCreated;
if (shouldBubble && metadata != null) {
+ if (DEBUG_EXPERIMENTS) {
+ Log.d(TAG, "Adding experimental shortcut bubble for: " + entry.getKey());
+ }
entry.setBubbleMetadata(metadata);
addedMetadata = true;
}
}
// Didn't get metadata from a shortcut & we're bubbling for experiment
- if (entry.getBubbleMetadata() == null && bubbleNotifForExperiment) {
+ if (entry.getBubbleMetadata() == null
+ && (bubbleNotifForExperiment || previouslyUserCreated)) {
metadata = createFromNotif(context, entry);
if (metadata != null) {
+ if (DEBUG_EXPERIMENTS) {
+ Log.d(TAG, "Adding experimental notification bubble for: " + entry.getKey());
+ }
entry.setBubbleMetadata(metadata);
addedMetadata = true;
}
}
- if (previousBubble != null && addedMetadata) {
- // Update to a previously bubble, set its flag now so the update goes
+ if (previouslyUserCreated && addedMetadata) {
+ // Update to a previous bubble, set its flag now so the update goes
// to the bubble.
+ if (DEBUG_EXPERIMENTS) {
+ Log.d(TAG, "Setting FLAG_BUBBLE for: " + entry.getKey());
+ }
entry.setFlagBubble(true);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 4982dd4..eb19571 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -476,7 +476,7 @@
});
d.setOnDismissListener(dialogInterface -> {
mUsbHighTempDialog = null;
- Events.writeEvent(mContext, Events.EVENT_DISMISS_USB_OVERHEAT_ALARM,
+ Events.writeEvent(Events.EVENT_DISMISS_USB_OVERHEAT_ALARM,
Events.DISMISS_REASON_USB_OVERHEAD_ALARM_CHANGED,
mKeyguard.isKeyguardLocked());
});
@@ -485,7 +485,7 @@
d.show();
mUsbHighTempDialog = d;
- Events.writeEvent(mContext, Events.EVENT_SHOW_USB_OVERHEAT_ALARM,
+ Events.writeEvent(Events.EVENT_SHOW_USB_OVERHEAT_ALARM,
Events.SHOW_REASON_USB_OVERHEAD_ALARM_CHANGED,
mKeyguard.isKeyguardLocked());
}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
deleted file mode 100644
index a5a915b..0000000
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2018 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.systemui.privacy
-
-import android.content.Context
-import android.util.AttributeSet
-import android.view.Gravity
-import android.view.ViewGroup
-import android.widget.FrameLayout
-import android.widget.ImageView
-import android.widget.LinearLayout
-import com.android.systemui.R
-
-class OngoingPrivacyChip @JvmOverloads constructor(
- context: Context,
- attrs: AttributeSet? = null,
- defStyleAttrs: Int = 0,
- defStyleRes: Int = 0
-) : LinearLayout(context, attrs, defStyleAttrs, defStyleRes) {
-
- private val iconMarginExpanded = context.resources.getDimensionPixelSize(
- R.dimen.ongoing_appops_chip_icon_margin_expanded)
- private val iconMarginCollapsed = context.resources.getDimensionPixelSize(
- R.dimen.ongoing_appops_chip_icon_margin_collapsed)
- private val iconSize =
- context.resources.getDimensionPixelSize(R.dimen.ongoing_appops_chip_icon_size)
- private val iconColor = context.resources.getColor(
- R.color.status_bar_clock_color, context.theme)
- private val sidePadding =
- context.resources.getDimensionPixelSize(R.dimen.ongoing_appops_chip_side_padding)
- private val backgroundDrawable = context.getDrawable(R.drawable.privacy_chip_bg)
- private lateinit var iconsContainer: LinearLayout
- private lateinit var back: FrameLayout
- var expanded = false
- set(value) {
- if (value != field) {
- field = value
- updateView()
- }
- }
-
- var builder = PrivacyDialogBuilder(context, emptyList<PrivacyItem>())
- var privacyList = emptyList<PrivacyItem>()
- set(value) {
- field = value
- builder = PrivacyDialogBuilder(context, value)
- updateView()
- }
-
- override fun onFinishInflate() {
- super.onFinishInflate()
-
- back = findViewById(R.id.background)
- iconsContainer = findViewById(R.id.icons_container)
- }
-
- // Should only be called if the builder icons or app changed
- private fun updateView() {
- back.background = if (expanded) backgroundDrawable else null
- val padding = if (expanded) sidePadding else 0
- back.setPaddingRelative(padding, 0, padding, 0)
- fun setIcons(dialogBuilder: PrivacyDialogBuilder, iconsContainer: ViewGroup) {
- iconsContainer.removeAllViews()
- dialogBuilder.generateIcons().forEachIndexed { i, it ->
- it.mutate()
- it.setTint(iconColor)
- val image = ImageView(context).apply {
- setImageDrawable(it)
- scaleType = ImageView.ScaleType.CENTER_INSIDE
- }
- iconsContainer.addView(image, iconSize, iconSize)
- if (i != 0) {
- val lp = image.layoutParams as MarginLayoutParams
- lp.marginStart = if (expanded) iconMarginExpanded else iconMarginCollapsed
- image.layoutParams = lp
- }
- }
- }
-
- if (!privacyList.isEmpty()) {
- generateContentDescription()
- setIcons(builder, iconsContainer)
- val lp = iconsContainer.layoutParams as FrameLayout.LayoutParams
- lp.gravity = Gravity.CENTER_VERTICAL or
- (if (expanded) Gravity.CENTER_HORIZONTAL else Gravity.END)
- iconsContainer.layoutParams = lp
- } else {
- iconsContainer.removeAllViews()
- }
- requestLayout()
- }
-
- private fun generateContentDescription() {
- val typesText = builder.joinTypes()
- contentDescription = context.getString(
- R.string.ongoing_privacy_chip_content_multiple_apps, typesText)
- }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt
deleted file mode 100644
index d08a373..0000000
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogBuilder.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2018 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.systemui.privacy
-
-import android.content.Context
-import android.graphics.drawable.Drawable
-import com.android.systemui.R
-
-class PrivacyDialogBuilder(private val context: Context, itemsList: List<PrivacyItem>) {
-
- val appsAndTypes: List<Pair<PrivacyApplication, List<PrivacyType>>>
- val types: List<PrivacyType>
- private val separator = context.getString(R.string.ongoing_privacy_dialog_separator)
- private val lastSeparator = context.getString(R.string.ongoing_privacy_dialog_last_separator)
-
- init {
- appsAndTypes = itemsList.groupBy({ it.application }, { it.privacyType })
- .toList()
- .sortedWith(compareBy({ -it.second.size }, // Sort by number of AppOps
- { it.second.min() })) // Sort by "smallest" AppOpp (Location is largest)
- types = itemsList.map { it.privacyType }.distinct().sorted()
- }
-
- fun generateIconsForApp(types: List<PrivacyType>): List<Drawable> {
- return types.sorted().map { it.getIcon(context) }
- }
-
- fun generateIcons() = types.map { it.getIcon(context) }
-
- private fun <T> List<T>.joinWithAnd(): StringBuilder {
- return subList(0, size - 1).joinTo(StringBuilder(), separator = separator).apply {
- append(lastSeparator)
- append(this@joinWithAnd.last())
- }
- }
-
- fun joinTypes(): String {
- return when (types.size) {
- 0 -> ""
- 1 -> types[0].getName(context)
- else -> types.map { it.getName(context) }.joinWithAnd().toString()
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
deleted file mode 100644
index 2909424..0000000
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2018 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.systemui.privacy
-
-import android.content.Context
-import android.content.pm.ApplicationInfo
-import android.content.pm.PackageManager
-import android.graphics.drawable.Drawable
-import android.os.UserHandle
-import android.util.IconDrawableFactory
-import com.android.systemui.R
-
-typealias Privacy = PrivacyType
-
-enum class PrivacyType(private val nameId: Int, val iconId: Int) {
- // This is uses the icons used by the corresponding permission groups in the AndroidManifest
- TYPE_CAMERA(R.string.privacy_type_camera,
- com.android.internal.R.drawable.perm_group_camera),
- TYPE_MICROPHONE(R.string.privacy_type_microphone,
- com.android.internal.R.drawable.perm_group_microphone),
- TYPE_LOCATION(R.string.privacy_type_location,
- com.android.internal.R.drawable.perm_group_location);
-
- fun getName(context: Context) = context.resources.getString(nameId)
-
- fun getIcon(context: Context) = context.resources.getDrawable(iconId, context.theme)
-}
-
-data class PrivacyItem(
- val privacyType: PrivacyType,
- val application: PrivacyApplication
-)
-
-data class PrivacyApplication(val packageName: String, val uid: Int, val context: Context)
- : Comparable<PrivacyApplication> {
-
- override fun compareTo(other: PrivacyApplication): Int {
- return applicationName.compareTo(other.applicationName)
- }
-
- private val applicationInfo: ApplicationInfo? by lazy {
- try {
- val userHandle = UserHandle.getUserHandleForUid(uid)
- context.createPackageContextAsUser(packageName, 0, userHandle).getPackageManager()
- .getApplicationInfo(packageName, 0)
- } catch (_: PackageManager.NameNotFoundException) {
- null
- }
- }
- val icon: Drawable by lazy {
- applicationInfo?.let {
- try {
- val iconFactory = IconDrawableFactory.newInstance(context, true)
- iconFactory.getBadgedIcon(it, UserHandle.getUserId(uid))
- } catch (_: Exception) {
- null
- }
- } ?: context.getDrawable(android.R.drawable.sym_def_app_icon)
- }
-
- val applicationName: String by lazy {
- applicationInfo?.let {
- context.packageManager.getApplicationLabel(it) as String
- } ?: packageName
- }
-
- override fun toString() = "PrivacyApplication(packageName=$packageName, uid=$uid)"
-}
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
deleted file mode 100644
index d592492..0000000
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2018 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.systemui.privacy
-
-import android.app.ActivityManager
-import android.app.AppOpsManager
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import android.content.IntentFilter
-import android.os.Handler
-import android.os.Looper
-import android.os.Message
-import android.os.UserHandle
-import android.os.UserManager
-import android.provider.DeviceConfig
-import com.android.internal.annotations.VisibleForTesting
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
-import com.android.systemui.Dumpable
-import com.android.systemui.R
-import com.android.systemui.appops.AppOpItem
-import com.android.systemui.appops.AppOpsController
-import com.android.systemui.broadcast.BroadcastDispatcher
-import com.android.systemui.dagger.qualifiers.BgHandler
-import com.android.systemui.dagger.qualifiers.MainHandler
-import java.io.FileDescriptor
-import java.io.PrintWriter
-import java.lang.ref.WeakReference
-import javax.inject.Inject
-import javax.inject.Singleton
-
-fun isPermissionsHubEnabled() = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
- SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, false)
-
-@Singleton
-class PrivacyItemController @Inject constructor(
- private val context: Context,
- private val appOpsController: AppOpsController,
- @MainHandler private val uiHandler: Handler,
- @BgHandler private val bgHandler: Handler,
- private val broadcastDispatcher: BroadcastDispatcher
-) : Dumpable {
-
- @VisibleForTesting
- internal companion object {
- val OPS = intArrayOf(AppOpsManager.OP_CAMERA,
- AppOpsManager.OP_RECORD_AUDIO,
- AppOpsManager.OP_COARSE_LOCATION,
- AppOpsManager.OP_FINE_LOCATION)
- val intents = listOf(Intent.ACTION_USER_FOREGROUND,
- Intent.ACTION_MANAGED_PROFILE_ADDED,
- Intent.ACTION_MANAGED_PROFILE_REMOVED)
- const val TAG = "PrivacyItemController"
- const val SYSTEM_UID = 1000
- const val MSG_ADD_CALLBACK = 0
- const val MSG_REMOVE_CALLBACK = 1
- const val MSG_UPDATE_LISTENING_STATE = 2
- }
-
- @VisibleForTesting
- internal var privacyList = emptyList<PrivacyItem>()
- @Synchronized get() = field.toList() // Returns a shallow copy of the list
- @Synchronized set
-
- private val userManager = context.getSystemService(UserManager::class.java)
- private var currentUserIds = emptyList<Int>()
- private var listening = false
- val systemApp =
- PrivacyApplication(context.getString(R.string.device_services), SYSTEM_UID, context)
- private val callbacks = mutableListOf<WeakReference<Callback>>()
- private val messageHandler = H(WeakReference(this), uiHandler.looper)
-
- private val notifyChanges = Runnable {
- val list = privacyList
- callbacks.forEach { it.get()?.privacyChanged(list) }
- }
-
- private val updateListAndNotifyChanges = Runnable {
- updatePrivacyList()
- uiHandler.post(notifyChanges)
- }
-
- private var indicatorsAvailable = isPermissionsHubEnabled()
- @VisibleForTesting
- internal val devicePropertiesChangedListener =
- object : DeviceConfig.OnPropertiesChangedListener {
- override fun onPropertiesChanged(properties: DeviceConfig.Properties) {
- if (DeviceConfig.NAMESPACE_PRIVACY.equals(properties.getNamespace()) &&
- properties.getKeyset().contains(
- SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED)) {
- indicatorsAvailable = properties.getBoolean(
- SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, false)
- messageHandler.removeMessages(MSG_UPDATE_LISTENING_STATE)
- messageHandler.sendEmptyMessage(MSG_UPDATE_LISTENING_STATE)
- }
- }
- }
-
- private val cb = object : AppOpsController.Callback {
- override fun onActiveStateChanged(
- code: Int,
- uid: Int,
- packageName: String,
- active: Boolean
- ) {
- val userId = UserHandle.getUserId(uid)
- if (userId in currentUserIds) {
- update(false)
- }
- }
- }
-
- @VisibleForTesting
- internal var userSwitcherReceiver = Receiver()
- set(value) {
- context.unregisterReceiver(field)
- field = value
- registerReceiver()
- }
-
- init {
- DeviceConfig.addOnPropertiesChangedListener(
- DeviceConfig.NAMESPACE_PRIVACY,
- context.mainExecutor,
- devicePropertiesChangedListener)
- }
-
- private fun unregisterReceiver() {
- broadcastDispatcher.unregisterReceiver(userSwitcherReceiver)
- }
-
- private fun registerReceiver() {
- broadcastDispatcher.registerReceiver(userSwitcherReceiver, IntentFilter().apply {
- intents.forEach {
- addAction(it)
- }
- }, null /* handler */, UserHandle.ALL)
- }
-
- private fun update(updateUsers: Boolean) {
- if (updateUsers) {
- val currentUser = ActivityManager.getCurrentUser()
- currentUserIds = userManager.getProfiles(currentUser).map { it.id }
- }
- bgHandler.post(updateListAndNotifyChanges)
- }
-
- /**
- * Updates listening status based on whether there are callbacks and the indicators are enabled
- *
- * This is only called from private (add/remove)Callback and from the config listener, all in
- * main thread.
- */
- private fun setListeningState() {
- val listen = !callbacks.isEmpty() and indicatorsAvailable
- if (listening == listen) return
- listening = listen
- if (listening) {
- appOpsController.addCallback(OPS, cb)
- registerReceiver()
- update(true)
- } else {
- appOpsController.removeCallback(OPS, cb)
- unregisterReceiver()
- // Make sure that we remove all indicators and notify listeners if we are not
- // listening anymore due to indicators being disabled
- update(false)
- }
- }
-
- private fun addCallback(callback: WeakReference<Callback>) {
- callbacks.add(callback)
- if (callbacks.isNotEmpty() && !listening) {
- messageHandler.removeMessages(MSG_UPDATE_LISTENING_STATE)
- messageHandler.sendEmptyMessage(MSG_UPDATE_LISTENING_STATE)
- }
- // Notify this callback if we didn't set to listening
- else if (listening) uiHandler.post(NotifyChangesToCallback(callback.get(), privacyList))
- }
-
- private fun removeCallback(callback: WeakReference<Callback>) {
- // Removes also if the callback is null
- callbacks.removeIf { it.get()?.equals(callback.get()) ?: true }
- if (callbacks.isEmpty()) {
- messageHandler.removeMessages(MSG_UPDATE_LISTENING_STATE)
- messageHandler.sendEmptyMessage(MSG_UPDATE_LISTENING_STATE)
- }
- }
-
- fun addCallback(callback: Callback) {
- messageHandler.obtainMessage(MSG_ADD_CALLBACK, callback).sendToTarget()
- }
-
- fun removeCallback(callback: Callback) {
- messageHandler.obtainMessage(MSG_REMOVE_CALLBACK, callback).sendToTarget()
- }
-
- private fun updatePrivacyList() {
- if (!listening) {
- privacyList = emptyList()
- return
- }
- val list = currentUserIds.flatMap { appOpsController.getActiveAppOpsForUser(it) }
- .mapNotNull { toPrivacyItem(it) }.distinct()
- privacyList = list
- }
-
- private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? {
- val type: PrivacyType = when (appOpItem.code) {
- AppOpsManager.OP_CAMERA -> PrivacyType.TYPE_CAMERA
- AppOpsManager.OP_COARSE_LOCATION -> PrivacyType.TYPE_LOCATION
- AppOpsManager.OP_FINE_LOCATION -> PrivacyType.TYPE_LOCATION
- AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE
- else -> return null
- }
- if (appOpItem.uid == SYSTEM_UID) return PrivacyItem(type, systemApp)
- val app = PrivacyApplication(appOpItem.packageName, appOpItem.uid, context)
- return PrivacyItem(type, app)
- }
-
- // Used by containing class to get notified of changes
- interface Callback {
- fun privacyChanged(privacyItems: List<PrivacyItem>)
- }
-
- internal inner class Receiver : BroadcastReceiver() {
- override fun onReceive(context: Context?, intent: Intent?) {
- if (intent?.action in intents) {
- update(true)
- }
- }
- }
-
- private class NotifyChangesToCallback(
- private val callback: Callback?,
- private val list: List<PrivacyItem>
- ) : Runnable {
- override fun run() {
- callback?.privacyChanged(list)
- }
- }
-
- override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
- pw.println("PrivacyItemController state:")
- pw.println(" Listening: $listening")
- pw.println(" Current user ids: $currentUserIds")
- pw.println(" Privacy Items:")
- privacyList.forEach {
- pw.print(" ")
- pw.println(it.toString())
- }
- pw.println(" Callbacks:")
- callbacks.forEach {
- it.get()?.let {
- pw.print(" ")
- pw.println(it.toString())
- }
- }
- }
-
- private class H(
- private val outerClass: WeakReference<PrivacyItemController>,
- looper: Looper
- ) : Handler(looper) {
- override fun handleMessage(msg: Message) {
- super.handleMessage(msg)
- when (msg.what) {
- MSG_UPDATE_LISTENING_STATE -> outerClass.get()?.setListeningState()
-
- MSG_ADD_CALLBACK -> {
- if (msg.obj !is PrivacyItemController.Callback) return
- outerClass.get()?.addCallback(
- WeakReference(msg.obj as PrivacyItemController.Callback))
- }
-
- MSG_REMOVE_CALLBACK -> {
- if (msg.obj !is PrivacyItemController.Callback) return
- outerClass.get()?.removeCallback(
- WeakReference(msg.obj as PrivacyItemController.Callback))
- }
- else -> {}
- }
- }
- }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 02e8f59..e5cec87 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -33,30 +33,24 @@
import android.graphics.Rect;
import android.media.AudioManager;
import android.os.Handler;
-import android.os.Looper;
import android.provider.AlarmClock;
-import android.provider.DeviceConfig;
import android.provider.Settings;
import android.service.notification.ZenModeConfig;
import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
-import android.util.StatsLog;
import android.view.ContextThemeWrapper;
import android.view.DisplayCutout;
import android.view.View;
import android.view.WindowInsets;
import android.widget.FrameLayout;
import android.widget.ImageView;
-import android.widget.LinearLayout;
import android.widget.RelativeLayout;
-import android.widget.Space;
import android.widget.TextView;
import androidx.annotation.VisibleForTesting;
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.settingslib.Utils;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.DualToneHandler;
@@ -65,11 +59,6 @@
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
-import com.android.systemui.privacy.OngoingPrivacyChip;
-import com.android.systemui.privacy.PrivacyDialogBuilder;
-import com.android.systemui.privacy.PrivacyItem;
-import com.android.systemui.privacy.PrivacyItemController;
-import com.android.systemui.privacy.PrivacyItemControllerKt;
import com.android.systemui.qs.QSDetail.Callback;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.PhoneStatusBarView;
@@ -145,12 +134,8 @@
private View mRingerContainer;
private Clock mClockView;
private DateView mDateView;
- private OngoingPrivacyChip mPrivacyChip;
- private Space mSpace;
private BatteryMeterView mBatteryRemainingIcon;
- private boolean mPermissionsHubEnabled;
- private PrivacyItemController mPrivacyItemController;
private BroadcastDispatcher mBroadcastDispatcher;
private final BroadcastReceiver mRingerReceiver = new BroadcastReceiver() {
@@ -161,43 +146,18 @@
}
};
private boolean mHasTopCutout = false;
- private boolean mPrivacyChipLogged = false;
-
- private final DeviceConfig.OnPropertiesChangedListener mPropertiesListener =
- new DeviceConfig.OnPropertiesChangedListener() {
- @Override
- public void onPropertiesChanged(DeviceConfig.Properties properties) {
- if (DeviceConfig.NAMESPACE_PRIVACY.equals(properties.getNamespace())
- && properties.getKeyset()
- .contains(SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED)) {
- mPermissionsHubEnabled = properties.getBoolean(
- SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, false);
- StatusIconContainer iconContainer = findViewById(R.id.statusIcons);
- iconContainer.setIgnoredSlots(getIgnoredIconSlots());
- }
- }
- };
-
- private PrivacyItemController.Callback mPICCallback = new PrivacyItemController.Callback() {
- @Override
- public void privacyChanged(List<PrivacyItem> privacyItems) {
- mPrivacyChip.setPrivacyList(privacyItems);
- setChipVisibility(!privacyItems.isEmpty());
- }
- };
@Inject
public QuickStatusBarHeader(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
NextAlarmController nextAlarmController, ZenModeController zenModeController,
StatusBarIconController statusBarIconController,
- ActivityStarter activityStarter, PrivacyItemController privacyItemController,
+ ActivityStarter activityStarter,
CommandQueue commandQueue, BroadcastDispatcher broadcastDispatcher) {
super(context, attrs);
mAlarmController = nextAlarmController;
mZenController = zenModeController;
mStatusBarIconController = statusBarIconController;
mActivityStarter = activityStarter;
- mPrivacyItemController = privacyItemController;
mDualToneHandler = new DualToneHandler(
new ContextThemeWrapper(context, R.style.QSHeaderTheme));
mBroadcastDispatcher = broadcastDispatcher;
@@ -228,11 +188,8 @@
mRingerModeTextView = findViewById(R.id.ringer_mode_text);
mRingerContainer = findViewById(R.id.ringer_container);
mRingerContainer.setOnClickListener(this::onClick);
- mPrivacyChip = findViewById(R.id.privacy_chip);
- mPrivacyChip.setOnClickListener(this::onClick);
mCarrierGroup = findViewById(R.id.carrier_group);
-
updateResources();
Rect tintArea = new Rect(0, 0, 0, 0);
@@ -252,7 +209,6 @@
mClockView = findViewById(R.id.clock);
mClockView.setOnClickListener(this);
mDateView = findViewById(R.id.date);
- mSpace = findViewById(R.id.space);
// Tint for the battery icons are handled in setupHost()
mBatteryRemainingIcon = findViewById(R.id.batteryRemainingIcon);
@@ -263,8 +219,6 @@
mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
mRingerModeTextView.setSelected(true);
mNextAlarmTextView.setSelected(true);
-
- mPermissionsHubEnabled = PrivacyItemControllerKt.isPermissionsHubEnabled();
}
private List<String> getIgnoredIconSlots() {
@@ -273,10 +227,6 @@
com.android.internal.R.string.status_bar_camera));
ignored.add(mContext.getResources().getString(
com.android.internal.R.string.status_bar_microphone));
- if (mPermissionsHubEnabled) {
- ignored.add(mContext.getResources().getString(
- com.android.internal.R.string.status_bar_location));
- }
return ignored;
}
@@ -292,21 +242,6 @@
}
}
- private void setChipVisibility(boolean chipVisible) {
- if (chipVisible && mPermissionsHubEnabled) {
- mPrivacyChip.setVisibility(View.VISIBLE);
- // Makes sure that the chip is logged as viewed at most once each time QS is opened
- // mListening makes sure that the callback didn't return after the user closed QS
- if (!mPrivacyChipLogged && mListening) {
- mPrivacyChipLogged = true;
- StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED,
- StatsLog.PRIVACY_INDICATORS_INTERACTED__TYPE__CHIP_VIEWED);
- }
- } else {
- mPrivacyChip.setVisibility(View.GONE);
- }
- }
-
private boolean updateRingerStatus() {
boolean isOriginalVisible = mRingerModeTextView.getVisibility() == View.VISIBLE;
CharSequence originalRingerText = mRingerModeTextView.getText();
@@ -418,7 +353,6 @@
updateStatusIconAlphaAnimator();
updateHeaderTextContainerAlphaAnimator();
- updatePrivacyChipAlphaAnimator();
}
private void updateStatusIconAlphaAnimator() {
@@ -433,12 +367,6 @@
.build();
}
- private void updatePrivacyChipAlphaAnimator() {
- mPrivacyChipAlphaAnimator = new TouchAnimator.Builder()
- .addFloat(mPrivacyChip, "alpha", 1, 0, 1)
- .build();
- }
-
public void setExpanded(boolean expanded) {
if (mExpanded == expanded) return;
mExpanded = expanded;
@@ -477,10 +405,6 @@
mHeaderTextContainerView.setVisibility(INVISIBLE);
}
}
- if (mPrivacyChipAlphaAnimator != null) {
- mPrivacyChip.setExpanded(expansionFraction > 0.5);
- mPrivacyChipAlphaAnimator.setPosition(keyguardExpansionFraction);
- }
}
public void disable(int state1, int state2, boolean animate) {
@@ -498,9 +422,6 @@
super.onAttachedToWindow();
mStatusBarIconController.addIconGroup(mIconManager);
requestApplyInsets();
- // Change the ignored slots when DeviceConfig flag changes
- DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_PRIVACY,
- mContext.getMainExecutor(), mPropertiesListener);
}
@Override
@@ -516,21 +437,6 @@
mSystemIconsView.setPadding(padding.first, 0, padding.second, 0);
}
- LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mSpace.getLayoutParams();
- if (cutout != null) {
- Rect topCutout = cutout.getBoundingRectTop();
- if (topCutout.isEmpty()) {
- mHasTopCutout = false;
- lp.width = 0;
- mSpace.setVisibility(View.GONE);
- } else {
- mHasTopCutout = true;
- lp.width = topCutout.width();
- mSpace.setVisibility(View.VISIBLE);
- }
- }
- mSpace.setLayoutParams(lp);
- setChipVisibility(mPrivacyChip.getVisibility() == View.VISIBLE);
return super.onApplyWindowInsets(insets);
}
@@ -539,7 +445,6 @@
public void onDetachedFromWindow() {
setListening(false);
mStatusBarIconController.removeIconGroup(mIconManager);
- DeviceConfig.removeOnPropertiesChangedListener(mPropertiesListener);
super.onDetachedFromWindow();
}
@@ -555,13 +460,10 @@
mAlarmController.addCallback(this);
mBroadcastDispatcher.registerReceiver(mRingerReceiver,
new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
- mPrivacyItemController.addCallback(mPICCallback);
} else {
mZenController.removeCallback(this);
mAlarmController.removeCallback(this);
- mPrivacyItemController.removeCallback(mPICCallback);
mBroadcastDispatcher.unregisterReceiver(mRingerReceiver);
- mPrivacyChipLogged = false;
}
}
@@ -579,18 +481,6 @@
mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
AlarmClock.ACTION_SHOW_ALARMS), 0);
}
- } else if (v == mPrivacyChip) {
- // Makes sure that the builder is grabbed as soon as the chip is pressed
- PrivacyDialogBuilder builder = mPrivacyChip.getBuilder();
- if (builder.getAppsAndTypes().size() == 0) return;
- Handler mUiHandler = new Handler(Looper.getMainLooper());
- StatsLog.write(StatsLog.PRIVACY_INDICATORS_INTERACTED,
- StatsLog.PRIVACY_INDICATORS_INTERACTED__TYPE__CHIP_CLICKED);
- mUiHandler.post(() -> {
- mActivityStarter.postStartActivityDismissingKeyguard(
- new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0);
- mHost.collapsePanels();
- });
} else if (v == mRingerContainer && mRingerContainer.isVisibleToUser()) {
mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
Settings.ACTION_SOUND_SETTINGS), 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index bfecaaa..8d43c66 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -43,10 +43,6 @@
import com.android.systemui.R;
import com.android.systemui.UiOffloadThread;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.privacy.PrivacyItem;
-import com.android.systemui.privacy.PrivacyItemController;
-import com.android.systemui.privacy.PrivacyItemControllerKt;
-import com.android.systemui.privacy.PrivacyType;
import com.android.systemui.qs.tiles.DndTile;
import com.android.systemui.qs.tiles.RotationLockTile;
import com.android.systemui.statusbar.CommandQueue;
@@ -67,9 +63,6 @@
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.ZenModeController;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.List;
import java.util.Locale;
/**
@@ -84,12 +77,12 @@
ZenModeController.Callback,
DeviceProvisionedListener,
KeyguardStateController.Callback,
- PrivacyItemController.Callback,
LocationController.LocationChangeCallback {
private static final String TAG = "PhoneStatusBarPolicy";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- public static final int LOCATION_STATUS_ICON_ID = PrivacyType.TYPE_LOCATION.getIconId();
+ public static final int LOCATION_STATUS_ICON_ID =
+ com.android.internal.R.drawable.perm_group_location;
private final String mSlotCast;
private final String mSlotHotspot;
@@ -122,7 +115,6 @@
private final DeviceProvisionedController mProvisionedController;
private final KeyguardStateController mKeyguardStateController;
private final LocationController mLocationController;
- private final PrivacyItemController mPrivacyItemController;
private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
private final SensorPrivacyController mSensorPrivacyController;
@@ -156,7 +148,6 @@
mProvisionedController = Dependency.get(DeviceProvisionedController.class);
mKeyguardStateController = Dependency.get(KeyguardStateController.class);
mLocationController = Dependency.get(LocationController.class);
- mPrivacyItemController = Dependency.get(PrivacyItemController.class);
mSensorPrivacyController = Dependency.get(SensorPrivacyController.class);
mSlotCast = context.getString(com.android.internal.R.string.status_bar_cast);
@@ -233,13 +224,6 @@
context.getString(R.string.accessibility_data_saver_on));
mIconController.setIconVisibility(mSlotDataSaver, false);
- // privacy items
- mIconController.setIcon(mSlotMicrophone, PrivacyType.TYPE_MICROPHONE.getIconId(),
- PrivacyType.TYPE_MICROPHONE.getName(mContext));
- mIconController.setIconVisibility(mSlotMicrophone, false);
- mIconController.setIcon(mSlotCamera, PrivacyType.TYPE_CAMERA.getIconId(),
- PrivacyType.TYPE_CAMERA.getName(mContext));
- mIconController.setIconVisibility(mSlotCamera, false);
mIconController.setIcon(mSlotLocation, LOCATION_STATUS_ICON_ID,
mContext.getString(R.string.accessibility_location_active));
mIconController.setIconVisibility(mSlotLocation, false);
@@ -259,7 +243,6 @@
mNextAlarmController.addCallback(mNextAlarmCallback);
mDataSaver.addCallback(this);
mKeyguardStateController.addCallback(this);
- mPrivacyItemController.addCallback(this);
mSensorPrivacyController.addCallback(mSensorPrivacyListener);
mLocationController.addCallback(this);
@@ -603,46 +586,9 @@
mIconController.setIconVisibility(mSlotDataSaver, isDataSaving);
}
- @Override // PrivacyItemController.Callback
- public void privacyChanged(List<PrivacyItem> privacyItems) {
- updatePrivacyItems(privacyItems);
- }
-
- private void updatePrivacyItems(List<PrivacyItem> items) {
- boolean showCamera = false;
- boolean showMicrophone = false;
- boolean showLocation = false;
- for (PrivacyItem item : items) {
- if (item == null /* b/124234367 */) {
- if (DEBUG) {
- Log.e(TAG, "updatePrivacyItems - null item found");
- StringWriter out = new StringWriter();
- mPrivacyItemController.dump(null, new PrintWriter(out), null);
- Log.e(TAG, out.toString());
- }
- continue;
- }
- switch (item.getPrivacyType()) {
- case TYPE_CAMERA:
- showCamera = true;
- break;
- case TYPE_LOCATION:
- showLocation = true;
- break;
- case TYPE_MICROPHONE:
- showMicrophone = true;
- break;
- }
- }
-
- mIconController.setIconVisibility(mSlotCamera, showCamera);
- mIconController.setIconVisibility(mSlotMicrophone, showMicrophone);
- mIconController.setIconVisibility(mSlotLocation, showLocation);
- }
-
@Override
public void onLocationActiveChanged(boolean active) {
- if (!PrivacyItemControllerKt.isPermissionsHubEnabled()) updateLocation();
+ updateLocation();
}
// Updates the status view based on the current state of location requests.
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ConfigurableTexts.java b/packages/SystemUI/src/com/android/systemui/volume/ConfigurableTexts.java
index 20de5bb..f1b9590 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ConfigurableTexts.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ConfigurableTexts.java
@@ -43,6 +43,9 @@
public int add(final TextView text, final int labelResId) {
if (text == null) return 0;
+ if (mTexts.containsKey(text)) {
+ return mTexts.get(text);
+ }
final Resources res = mContext.getResources();
final float fontScale = res.getConfiguration().fontScale;
final float density = res.getDisplayMetrics().density;
@@ -63,6 +66,11 @@
return sp;
}
+ public void remove(final TextView text) {
+ mTexts.remove(text);
+ mTextLabels.remove(text);
+ }
+
public void update() {
if (mTexts.isEmpty()) return;
mTexts.keyAt(0).post(mUpdateAll);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/Events.java b/packages/SystemUI/src/com/android/systemui/volume/Events.java
index 9bbfd22..5ed8b8f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/Events.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/Events.java
@@ -16,7 +16,6 @@
package com.android.systemui.volume;
-import android.content.Context;
import android.media.AudioManager;
import android.media.AudioSystem;
import android.provider.Settings.Global;
@@ -125,7 +124,12 @@
public static Callback sCallback;
- public static void writeEvent(Context context, int tag, Object... list) {
+ /**
+ * Logs an event to the system log and the event log.
+ * @param tag One of the EVENT_* codes above.
+ * @param list Any additional event-specific arguments, documented above.
+ */
+ public static void writeEvent(int tag, Object... list) {
MetricsLogger logger = new MetricsLogger();
final long time = System.currentTimeMillis();
final StringBuilder sb = new StringBuilder("writeEvent ").append(EVENT_TAGS[tag]);
@@ -133,33 +137,33 @@
sb.append(" ");
switch (tag) {
case EVENT_SHOW_DIALOG:
- MetricsLogger.visible(context, MetricsEvent.VOLUME_DIALOG);
- MetricsLogger.histogram(context, "volume_from_keyguard",
+ logger.visible(MetricsEvent.VOLUME_DIALOG);
+ logger.histogram("volume_from_keyguard",
(Boolean) list[1] ? 1 : 0);
sb.append(SHOW_REASONS[(Integer) list[0]]).append(" keyguard=").append(list[1]);
break;
case EVENT_EXPAND:
- MetricsLogger.visibility(context, MetricsEvent.VOLUME_DIALOG_DETAILS,
+ logger.visibility(MetricsEvent.VOLUME_DIALOG_DETAILS,
(Boolean) list[0]);
sb.append(list[0]);
break;
case EVENT_DISMISS_DIALOG:
- MetricsLogger.hidden(context, MetricsEvent.VOLUME_DIALOG);
+ logger.hidden(MetricsEvent.VOLUME_DIALOG);
sb.append(DISMISS_REASONS[(Integer) list[0]]);
break;
case EVENT_ACTIVE_STREAM_CHANGED:
- MetricsLogger.action(context, MetricsEvent.ACTION_VOLUME_STREAM,
+ logger.action(MetricsEvent.ACTION_VOLUME_STREAM,
(Integer) list[0]);
sb.append(AudioSystem.streamToString((Integer) list[0]));
break;
case EVENT_ICON_CLICK:
- MetricsLogger.action(context, MetricsEvent.ACTION_VOLUME_ICON,
+ logger.action(MetricsEvent.ACTION_VOLUME_ICON,
(Integer) list[0]);
sb.append(AudioSystem.streamToString((Integer) list[0])).append(' ')
.append(iconStateToString((Integer) list[1]));
break;
case EVENT_TOUCH_LEVEL_DONE:
- MetricsLogger.action(context, MetricsEvent.ACTION_VOLUME_SLIDER,
+ logger.action(MetricsEvent.ACTION_VOLUME_SLIDER,
(Integer) list[1]);
// fall through
case EVENT_TOUCH_LEVEL_CHANGED:
@@ -169,7 +173,7 @@
.append(list[1]);
break;
case EVENT_KEY:
- MetricsLogger.action(context, MetricsEvent.ACTION_VOLUME_KEY,
+ logger.action(MetricsEvent.ACTION_VOLUME_KEY,
(Integer) list[0]);
sb.append(AudioSystem.streamToString((Integer) list[0])).append(' ')
.append(list[1]);
@@ -181,7 +185,7 @@
logger.action(MetricsEvent.ACTION_VOLUME_SETTINGS);
break;
case EVENT_EXTERNAL_RINGER_MODE_CHANGED:
- MetricsLogger.action(context, MetricsEvent.ACTION_RINGER_MODE,
+ logger.action(MetricsEvent.ACTION_RINGER_MODE,
(Integer) list[0]);
// fall through
case EVENT_INTERNAL_RINGER_MODE_CHANGED:
@@ -194,14 +198,14 @@
sb.append(list[0]).append(' ').append(list[1]);
break;
case EVENT_SHOW_USB_OVERHEAT_ALARM:
- MetricsLogger.visible(context, MetricsEvent.POWER_OVERHEAT_ALARM);
- MetricsLogger.histogram(context, "show_usb_overheat_alarm",
+ logger.visible(MetricsEvent.POWER_OVERHEAT_ALARM);
+ logger.histogram("show_usb_overheat_alarm",
(Boolean) list[1] ? 1 : 0);
sb.append(SHOW_REASONS[(Integer) list[0]]).append(" keyguard=").append(list[1]);
break;
case EVENT_DISMISS_USB_OVERHEAT_ALARM:
- MetricsLogger.hidden(context, MetricsEvent.POWER_OVERHEAT_ALARM);
- MetricsLogger.histogram(context, "dismiss_usb_overheat_alarm",
+ logger.hidden(MetricsEvent.POWER_OVERHEAT_ALARM);
+ logger.histogram("dismiss_usb_overheat_alarm",
(Boolean) list[1] ? 1 : 0);
sb.append(DISMISS_REASONS[(Integer) list[0]])
.append(" keyguard=").append(list[1]);
@@ -255,4 +259,5 @@
void writeEvent(long time, int tag, Object[] list);
void writeState(long time, State state);
}
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 02c699f..a4ed31d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -150,7 +150,7 @@
mStatusBarOptionalLazy = statusBarOptionalLazy;
mNotificationManager = (NotificationManager) mContext.getSystemService(
Context.NOTIFICATION_SERVICE);
- Events.writeEvent(mContext, Events.EVENT_COLLECTION_STARTED);
+ Events.writeEvent(Events.EVENT_COLLECTION_STARTED);
mWorkerThread = new HandlerThread(VolumeDialogControllerImpl.class.getSimpleName());
mWorkerThread.start();
mWorker = new W(mWorkerThread.getLooper());
@@ -237,7 +237,7 @@
if (D.BUG) Log.d(TAG, "destroy");
if (mDestroyed) return;
mDestroyed = true;
- Events.writeEvent(mContext, Events.EVENT_COLLECTION_STOPPED);
+ Events.writeEvent(Events.EVENT_COLLECTION_STOPPED);
mMediaSessions.destroy();
mObserver.destroy();
mReceiver.destroy();
@@ -487,7 +487,7 @@
mCallbacks.onShowSilentHint();
}
if (changed && fromKey) {
- Events.writeEvent(mContext, Events.EVENT_KEY, stream, lastAudibleStreamVolume);
+ Events.writeEvent(Events.EVENT_KEY, stream, lastAudibleStreamVolume);
}
return changed;
}
@@ -495,7 +495,7 @@
private boolean updateActiveStreamW(int activeStream) {
if (activeStream == mState.activeStream) return false;
mState.activeStream = activeStream;
- Events.writeEvent(mContext, Events.EVENT_ACTIVE_STREAM_CHANGED, activeStream);
+ Events.writeEvent(Events.EVENT_ACTIVE_STREAM_CHANGED, activeStream);
if (D.BUG) Log.d(TAG, "updateActiveStreamW " + activeStream);
final int s = activeStream < DYNAMIC_STREAM_START_INDEX ? activeStream : -1;
if (D.BUG) Log.d(TAG, "forceVolumeControlStream " + s);
@@ -544,7 +544,7 @@
if (ss.level == level) return false;
ss.level = level;
if (isLogWorthy(stream)) {
- Events.writeEvent(mContext, Events.EVENT_LEVEL_CHANGED, stream, level);
+ Events.writeEvent(Events.EVENT_LEVEL_CHANGED, stream, level);
}
return true;
}
@@ -567,7 +567,7 @@
if (ss.muted == muted) return false;
ss.muted = muted;
if (isLogWorthy(stream)) {
- Events.writeEvent(mContext, Events.EVENT_MUTE_CHANGED, stream, muted);
+ Events.writeEvent(Events.EVENT_MUTE_CHANGED, stream, muted);
}
if (muted && isRinger(stream)) {
updateRingerModeInternalW(mAudio.getRingerModeInternal());
@@ -583,7 +583,7 @@
if (Objects.equals(mState.effectsSuppressor, effectsSuppressor)) return false;
mState.effectsSuppressor = effectsSuppressor;
mState.effectsSuppressorName = getApplicationName(mContext, mState.effectsSuppressor);
- Events.writeEvent(mContext, Events.EVENT_SUPPRESSOR_CHANGED, mState.effectsSuppressor,
+ Events.writeEvent(Events.EVENT_SUPPRESSOR_CHANGED, mState.effectsSuppressor,
mState.effectsSuppressorName);
return true;
}
@@ -607,7 +607,7 @@
Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
if (mState.zenMode == zen) return false;
mState.zenMode = zen;
- Events.writeEvent(mContext, Events.EVENT_ZEN_MODE_CHANGED, zen);
+ Events.writeEvent(Events.EVENT_ZEN_MODE_CHANGED, zen);
return true;
}
@@ -633,23 +633,23 @@
mState.disallowMedia = disallowMedia;
mState.disallowSystem = disallowSystem;
mState.disallowRinger = disallowRinger;
- Events.writeEvent(mContext, Events.EVENT_ZEN_CONFIG_CHANGED, "disallowAlarms=" +
- disallowAlarms + " disallowMedia=" + disallowMedia + " disallowSystem=" +
- disallowSystem + " disallowRinger=" + disallowRinger);
+ Events.writeEvent(Events.EVENT_ZEN_CONFIG_CHANGED, "disallowAlarms="
+ + disallowAlarms + " disallowMedia=" + disallowMedia + " disallowSystem="
+ + disallowSystem + " disallowRinger=" + disallowRinger);
return true;
}
private boolean updateRingerModeExternalW(int rm) {
if (rm == mState.ringerModeExternal) return false;
mState.ringerModeExternal = rm;
- Events.writeEvent(mContext, Events.EVENT_EXTERNAL_RINGER_MODE_CHANGED, rm);
+ Events.writeEvent(Events.EVENT_EXTERNAL_RINGER_MODE_CHANGED, rm);
return true;
}
private boolean updateRingerModeInternalW(int rm) {
if (rm == mState.ringerModeInternal) return false;
mState.ringerModeInternal = rm;
- Events.writeEvent(mContext, Events.EVENT_INTERNAL_RINGER_MODE_CHANGED, rm);
+ Events.writeEvent(Events.EVENT_INTERNAL_RINGER_MODE_CHANGED, rm);
if (mState.ringerModeInternal == RINGER_MODE_NORMAL) {
playTouchFeedback();
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 24d6c4c..f5c1587 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -429,7 +429,7 @@
row.icon.setImageResource(iconRes);
if (row.stream != AudioSystem.STREAM_ACCESSIBILITY) {
row.icon.setOnClickListener(v -> {
- Events.writeEvent(mContext, Events.EVENT_ICON_CLICK, row.stream, row.iconState);
+ Events.writeEvent(Events.EVENT_ICON_CLICK, row.stream, row.iconState);
mController.setActiveStream(row.stream);
if (row.stream == AudioManager.STREAM_RING) {
final boolean hasVibrator = mController.hasVibrator();
@@ -468,7 +468,7 @@
}
if (mSettingsIcon != null) {
mSettingsIcon.setOnClickListener(v -> {
- Events.writeEvent(mContext, Events.EVENT_SETTINGS_CLICK);
+ Events.writeEvent(Events.EVENT_SETTINGS_CLICK);
Intent intent = new Intent(Settings.Panel.ACTION_VOLUME);
dismissH(DISMISS_REASON_SETTINGS_CLICKED);
Dependency.get(ActivityStarter.class).startActivity(intent,
@@ -504,7 +504,7 @@
mController.setStreamVolume(AudioManager.STREAM_RING, 1);
}
}
- Events.writeEvent(mContext, Events.EVENT_RINGER_TOGGLE, newRingerMode);
+ Events.writeEvent(Events.EVENT_RINGER_TOGGLE, newRingerMode);
incrementManualToggleCount();
updateRingerH();
provideTouchFeedbackH(newRingerMode);
@@ -519,7 +519,7 @@
if (mODICaptionsIcon != null) {
mODICaptionsIcon.setOnConfirmedTapListener(() -> {
onCaptionIconClicked();
- Events.writeEvent(mContext, Events.EVENT_ODI_CAPTIONS_CLICK);
+ Events.writeEvent(Events.EVENT_ODI_CAPTIONS_CLICK);
}, mHandler);
}
@@ -541,7 +541,7 @@
mODICaptionsTooltipView = mODICaptionsTooltipViewStub.inflate();
mODICaptionsTooltipView.findViewById(R.id.dismiss).setOnClickListener(v -> {
hideCaptionsTooltip();
- Events.writeEvent(mContext, Events.EVENT_ODI_CAPTIONS_TOOLTIP_CLICK);
+ Events.writeEvent(Events.EVENT_ODI_CAPTIONS_TOOLTIP_CLICK);
});
mODICaptionsTooltipViewStub = null;
rescheduleTimeoutH();
@@ -694,7 +694,7 @@
initSettingsH();
mShowing = true;
mDialog.show();
- Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
+ Events.writeEvent(Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
mController.notifyVisible(true);
mController.getCaptionsComponentState(false);
checkODICaptionsTooltip(false);
@@ -741,7 +741,7 @@
if (mShowing) {
mShowing = false;
// Only logs when the volume dialog visibility is changed.
- Events.writeEvent(mContext, Events.EVENT_DISMISS_DIALOG, reason);
+ Events.writeEvent(Events.EVENT_DISMISS_DIALOG, reason);
}
mDialogView.setTranslationX(0);
mDialogView.setAlpha(1);
@@ -922,6 +922,7 @@
if (!mDynamic.get(row.stream)) {
mRows.remove(i);
mDialogRowsView.removeView(row.view);
+ mConfigurableTexts.remove(row.header);
}
}
}
@@ -1400,7 +1401,7 @@
mController.setActiveStream(mRow.stream);
mController.setStreamVolume(mRow.stream, userLevel);
mRow.requestedLevel = userLevel;
- Events.writeEvent(mContext, Events.EVENT_TOUCH_LEVEL_CHANGED, mRow.stream,
+ Events.writeEvent(Events.EVENT_TOUCH_LEVEL_CHANGED, mRow.stream,
userLevel);
}
}
@@ -1419,7 +1420,7 @@
mRow.tracking = false;
mRow.userAttempt = SystemClock.uptimeMillis();
final int userLevel = getImpliedLevel(seekBar, seekBar.getProgress());
- Events.writeEvent(mContext, Events.EVENT_TOUCH_LEVEL_DONE, mRow.stream, userLevel);
+ Events.writeEvent(Events.EVENT_TOUCH_LEVEL_DONE, mRow.stream, userLevel);
if (mRow.ss.level != userLevel) {
mHandler.sendMessageDelayed(mHandler.obtainMessage(H.RECHECK, mRow),
USER_ATTEMPT_GRACE_PERIOD);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt
deleted file mode 100644
index 6302f9d..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogBuilderTest.kt
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2018 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.systemui.privacy
-
-import androidx.test.filters.SmallTest
-import androidx.test.runner.AndroidJUnit4
-import com.android.systemui.SysuiTestCase
-import org.junit.Assert.assertEquals
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@RunWith(AndroidJUnit4::class)
-@SmallTest
-class PrivacyDialogBuilderTest : SysuiTestCase() {
-
- companion object {
- val TEST_UID = 1
- }
-
- @Test
- fun testGenerateAppsList() {
- val bar2 = PrivacyItem(Privacy.TYPE_CAMERA, PrivacyApplication(
- "Bar", TEST_UID, context))
- val bar3 = PrivacyItem(Privacy.TYPE_LOCATION, PrivacyApplication(
- "Bar", TEST_UID, context))
- val foo0 = PrivacyItem(Privacy.TYPE_MICROPHONE, PrivacyApplication(
- "Foo", TEST_UID, context))
- val baz1 = PrivacyItem(Privacy.TYPE_CAMERA, PrivacyApplication(
- "Baz", TEST_UID, context))
-
- val items = listOf(bar2, foo0, baz1, bar3)
-
- val textBuilder = PrivacyDialogBuilder(context, items)
-
- val list = textBuilder.appsAndTypes
- assertEquals(3, list.size)
- val appsList = list.map { it.first }
- val typesList = list.map { it.second }
- // List is sorted by number of types and then by types
- assertEquals(listOf("Bar", "Baz", "Foo"), appsList.map { it.packageName })
- assertEquals(listOf(Privacy.TYPE_CAMERA, Privacy.TYPE_LOCATION), typesList[0])
- assertEquals(listOf(Privacy.TYPE_CAMERA), typesList[1])
- assertEquals(listOf(Privacy.TYPE_MICROPHONE), typesList[2])
- }
-
- @Test
- fun testOrder() {
- // We want location to always go last, so it will go in the "+ other apps"
- val appCamera = PrivacyItem(PrivacyType.TYPE_CAMERA,
- PrivacyApplication("Camera", TEST_UID, context))
- val appMicrophone =
- PrivacyItem(PrivacyType.TYPE_MICROPHONE,
- PrivacyApplication("Microphone", TEST_UID, context))
- val appLocation =
- PrivacyItem(PrivacyType.TYPE_LOCATION,
- PrivacyApplication("Location", TEST_UID, context))
-
- val items = listOf(appLocation, appMicrophone, appCamera)
- val textBuilder = PrivacyDialogBuilder(context, items)
- val appList = textBuilder.appsAndTypes.map { it.first }.map { it.packageName }
- assertEquals(listOf("Camera", "Microphone", "Location"), appList)
- }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
deleted file mode 100644
index 20148e1..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (C) 2018 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.systemui.privacy
-
-import android.app.ActivityManager
-import android.app.AppOpsManager
-import android.content.Context
-import android.content.Intent
-import android.content.pm.UserInfo
-import android.os.Handler
-import android.os.UserHandle
-import android.os.UserManager
-import android.provider.DeviceConfig
-import android.provider.Settings.RESET_MODE_PACKAGE_DEFAULTS
-import android.testing.AndroidTestingRunner
-import android.testing.TestableLooper
-import android.testing.TestableLooper.RunWithLooper
-import androidx.test.filters.SmallTest
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
-import com.android.systemui.Dependency
-import com.android.systemui.R
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.appops.AppOpItem
-import com.android.systemui.appops.AppOpsController
-import com.android.systemui.broadcast.BroadcastDispatcher
-import org.hamcrest.Matchers.hasItem
-import org.hamcrest.Matchers.not
-import org.hamcrest.Matchers.nullValue
-import org.junit.After
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertThat
-import org.junit.Assert.assertTrue
-import org.junit.Before
-import org.junit.Ignore
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentCaptor
-import org.mockito.ArgumentMatchers.any
-import org.mockito.ArgumentMatchers.anyBoolean
-import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.ArgumentMatchers.anyList
-import org.mockito.ArgumentMatchers.anyString
-import org.mockito.ArgumentMatchers.eq
-import org.mockito.Captor
-import org.mockito.Mock
-import org.mockito.Mockito.atLeastOnce
-import org.mockito.Mockito.doAnswer
-import org.mockito.Mockito.doReturn
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.never
-import org.mockito.Mockito.reset
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyNoMoreInteractions
-import org.mockito.MockitoAnnotations
-
-@RunWith(AndroidTestingRunner::class)
-@SmallTest
-@RunWithLooper
-@Ignore
-class PrivacyItemControllerTest : SysuiTestCase() {
-
- companion object {
- val CURRENT_USER_ID = ActivityManager.getCurrentUser()
- val TEST_UID = CURRENT_USER_ID * UserHandle.PER_USER_RANGE
- const val SYSTEM_UID = 1000
- const val TEST_PACKAGE_NAME = "test"
- const val DEVICE_SERVICES_STRING = "Device services"
- const val TAG = "PrivacyItemControllerTest"
- fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
- }
-
- @Mock
- private lateinit var appOpsController: AppOpsController
- @Mock
- private lateinit var callback: PrivacyItemController.Callback
- @Mock
- private lateinit var userManager: UserManager
- @Mock
- private lateinit var broadcastDispatcher: BroadcastDispatcher
- @Captor
- private lateinit var argCaptor: ArgumentCaptor<List<PrivacyItem>>
- @Captor
- private lateinit var argCaptorCallback: ArgumentCaptor<AppOpsController.Callback>
-
- private lateinit var testableLooper: TestableLooper
- private lateinit var privacyItemController: PrivacyItemController
- private lateinit var handler: Handler
-
- fun PrivacyItemController(context: Context) =
- PrivacyItemController(context, appOpsController, handler, handler, broadcastDispatcher)
-
- @Before
- fun setup() {
- MockitoAnnotations.initMocks(this)
- testableLooper = TestableLooper.get(this)
- handler = Handler(testableLooper.looper)
-
- appOpsController = mDependency.injectMockDependency(AppOpsController::class.java)
- mDependency.injectTestDependency(Dependency.MAIN_HANDLER, handler)
- mContext.addMockSystemService(UserManager::class.java, userManager)
- mContext.getOrCreateTestableResources().addOverride(R.string.device_services,
- DEVICE_SERVICES_STRING)
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_PRIVACY,
- SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED,
- "true", false)
-
- doReturn(listOf(object : UserInfo() {
- init {
- id = CURRENT_USER_ID
- }
- })).`when`(userManager).getProfiles(anyInt())
-
- privacyItemController = PrivacyItemController(mContext)
- }
-
- @After
- fun tearDown() {
- DeviceConfig.resetToDefaults(RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_PRIVACY)
- }
-
- @Test
- fun testSetListeningTrueByAddingCallback() {
- privacyItemController.addCallback(callback)
- testableLooper.processAllMessages()
- verify(appOpsController).addCallback(eq(PrivacyItemController.OPS),
- any(AppOpsController.Callback::class.java))
- testableLooper.processAllMessages()
- verify(callback).privacyChanged(anyList())
- }
-
- @Test
- fun testSetListeningFalseByRemovingLastCallback() {
- privacyItemController.addCallback(callback)
- testableLooper.processAllMessages()
- verify(appOpsController, never()).removeCallback(any(IntArray::class.java),
- any(AppOpsController.Callback::class.java))
- privacyItemController.removeCallback(callback)
- testableLooper.processAllMessages()
- verify(appOpsController).removeCallback(eq(PrivacyItemController.OPS),
- any(AppOpsController.Callback::class.java))
- verify(callback).privacyChanged(emptyList())
- }
-
- @Test
- fun testDistinctItems() {
- doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 0),
- AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, "", 1)))
- .`when`(appOpsController).getActiveAppOpsForUser(anyInt())
-
- privacyItemController.addCallback(callback)
- testableLooper.processAllMessages()
- verify(callback).privacyChanged(capture(argCaptor))
- assertEquals(1, argCaptor.value.size)
- }
-
- @Test
- fun testSystemApps() {
- doReturn(listOf(AppOpItem(AppOpsManager.OP_COARSE_LOCATION, SYSTEM_UID, TEST_PACKAGE_NAME,
- 0))).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
- privacyItemController.addCallback(callback)
- testableLooper.processAllMessages()
- verify(callback).privacyChanged(capture(argCaptor))
- assertEquals(1, argCaptor.value.size)
- assertEquals(context.getString(R.string.device_services),
- argCaptor.value[0].application.applicationName)
- }
-
- @Test
- fun testRegisterReceiver_allUsers() {
- privacyItemController.addCallback(callback)
- testableLooper.processAllMessages()
- verify(broadcastDispatcher, atLeastOnce()).registerReceiver(
- eq(privacyItemController.userSwitcherReceiver), any(), eq(null), eq(UserHandle.ALL))
- verify(broadcastDispatcher, never())
- .unregisterReceiver(eq(privacyItemController.userSwitcherReceiver))
- }
-
- @Test
- fun testReceiver_ACTION_USER_FOREGROUND() {
- privacyItemController.userSwitcherReceiver.onReceive(context,
- Intent(Intent.ACTION_USER_FOREGROUND))
- verify(userManager).getProfiles(anyInt())
- }
-
- @Test
- fun testReceiver_ACTION_MANAGED_PROFILE_ADDED() {
- privacyItemController.userSwitcherReceiver.onReceive(context,
- Intent(Intent.ACTION_MANAGED_PROFILE_ADDED))
- verify(userManager).getProfiles(anyInt())
- }
-
- @Test
- fun testReceiver_ACTION_MANAGED_PROFILE_REMOVED() {
- privacyItemController.userSwitcherReceiver.onReceive(context,
- Intent(Intent.ACTION_MANAGED_PROFILE_REMOVED))
- verify(userManager).getProfiles(anyInt())
- }
-
- @Test
- fun testAddMultipleCallbacks() {
- val otherCallback = mock(PrivacyItemController.Callback::class.java)
- privacyItemController.addCallback(callback)
- testableLooper.processAllMessages()
- verify(callback).privacyChanged(anyList())
-
- privacyItemController.addCallback(otherCallback)
- testableLooper.processAllMessages()
- verify(otherCallback).privacyChanged(anyList())
- // Adding a callback should not unnecessarily call previous ones
- verifyNoMoreInteractions(callback)
- }
-
- @Test
- fun testMultipleCallbacksAreUpdated() {
- doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
-
- val otherCallback = mock(PrivacyItemController.Callback::class.java)
- privacyItemController.addCallback(callback)
- privacyItemController.addCallback(otherCallback)
- testableLooper.processAllMessages()
- reset(callback)
- reset(otherCallback)
-
- verify(appOpsController).addCallback(any<IntArray>(), capture(argCaptorCallback))
- argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true)
- testableLooper.processAllMessages()
- verify(callback).privacyChanged(anyList())
- verify(otherCallback).privacyChanged(anyList())
- }
-
- @Test
- fun testRemoveCallback() {
- doReturn(emptyList<AppOpItem>()).`when`(appOpsController).getActiveAppOpsForUser(anyInt())
- val otherCallback = mock(PrivacyItemController.Callback::class.java)
- privacyItemController.addCallback(callback)
- privacyItemController.addCallback(otherCallback)
- testableLooper.processAllMessages()
- reset(callback)
- reset(otherCallback)
-
- verify(appOpsController).addCallback(any<IntArray>(), capture(argCaptorCallback))
- privacyItemController.removeCallback(callback)
- argCaptorCallback.value.onActiveStateChanged(0, TEST_UID, "", true)
- testableLooper.processAllMessages()
- verify(callback, never()).privacyChanged(anyList())
- verify(otherCallback).privacyChanged(anyList())
- }
-
- @Test
- fun testListShouldNotHaveNull() {
- doReturn(listOf(AppOpItem(AppOpsManager.OP_ACTIVATE_VPN, TEST_UID, "", 0),
- AppOpItem(AppOpsManager.OP_COARSE_LOCATION, TEST_UID, "", 0)))
- .`when`(appOpsController).getActiveAppOpsForUser(anyInt())
- privacyItemController.addCallback(callback)
- testableLooper.processAllMessages()
-
- verify(callback).privacyChanged(capture(argCaptor))
- assertEquals(1, argCaptor.value.size)
- assertThat(argCaptor.value, not(hasItem(nullValue())))
- }
-
- @Test
- fun testListShouldBeCopy() {
- val list = listOf(PrivacyItem(PrivacyType.TYPE_CAMERA,
- PrivacyApplication("", TEST_UID, mContext)))
- privacyItemController.privacyList = list
- val privacyList = privacyItemController.privacyList
- assertEquals(list, privacyList)
- assertTrue(list !== privacyList)
- }
-
- @Test
- fun testNotListeningWhenIndicatorsDisabled() {
- val properties = getProperties(
- DeviceConfig.NAMESPACE_PRIVACY,
- SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED,
- false)
- privacyItemController.devicePropertiesChangedListener.onPropertiesChanged(properties)
- privacyItemController.addCallback(callback)
- testableLooper.processAllMessages()
- verify(appOpsController, never()).addCallback(eq(PrivacyItemController.OPS),
- any(AppOpsController.Callback::class.java))
- }
-
- private fun getProperties(namespace: String, name: String, value: Boolean):
- DeviceConfig.Properties {
- val properties = mock<DeviceConfig.Properties>(DeviceConfig.Properties::class.java)
- doReturn(namespace).`when`(properties).getNamespace()
- doReturn(setOf(name)).`when`(properties).getKeyset()
- doAnswer {
- val key: String = it.getArgument(0)
- val defaultValue: Boolean = it.getArgument(1)
- if (name.equals(key, ignoreCase = true)) {
- value
- } else {
- defaultValue
- }
- }.`when`(properties).getBoolean(anyString(), anyBoolean())
- return properties
- }
-}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index d4889ea..822fc90 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -1556,8 +1556,6 @@
public StorageManagerService(Context context) {
sSelf = this;
- updateFusePropFromSettings();
-
// Snapshot feature flag used for this boot
SystemProperties.set(StorageManager.PROP_ISOLATED_STORAGE_SNAPSHOT, Boolean.toString(
SystemProperties.getBoolean(StorageManager.PROP_ISOLATED_STORAGE, true)));
@@ -1757,6 +1755,7 @@
private void bootCompleted() {
mBootCompleted = true;
mHandler.obtainMessage(H_BOOT_COMPLETED).sendToTarget();
+ updateFusePropFromSettings();
}
private void handleBootCompleted() {
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index 5983785..2175ca0 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -46,7 +46,6 @@
import android.util.Xml;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.os.AtomicDirectory;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
@@ -128,6 +127,7 @@
private static final String PARAMETER_DELIMITER = ",";
private static final String PARAMETER_ASSIGNMENT = "=";
+ private static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled";
@GuardedBy("mLock")
private @NonNull LinkedList<HistoricalOps> mPendingWrites = new LinkedList<>();
@@ -701,7 +701,7 @@
private static boolean isApiEnabled() {
return Binder.getCallingUid() == Process.myUid()
|| DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
- SystemUiDeviceConfigFlags.PROPERTY_PERMISSIONS_HUB_ENABLED, false);
+ PROPERTY_PERMISSIONS_HUB_ENABLED, false);
}
private static final class Persistence {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 93249e9..dceca0a 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -494,7 +494,7 @@
}
// Only apps with INSTALL_PACKAGES are allowed to set an installer that is not the
// caller.
- if (!requestedInstallerPackageName.equals(installerPackageName)) {
+ if (!TextUtils.equals(requestedInstallerPackageName, installerPackageName)) {
if (mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES)
!= PackageManager.PERMISSION_GRANTED) {
mAppOps.checkPackage(callingUid, requestedInstallerPackageName);
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 9b50307..0beff7a 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -20,7 +20,6 @@
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AppGlobals;
-import android.app.admin.DevicePolicyManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -777,16 +776,6 @@
break;
case android.provider.Settings.Global.AUTO_TIME:
- DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
- if (dpm != null && dpm.getAutoTimeRequired()
- && "0".equals(value)) {
- return true;
- } else if (callingUid == Process.SYSTEM_UID) {
- return false;
- }
- restriction = UserManager.DISALLOW_CONFIG_DATE_TIME;
- break;
-
case android.provider.Settings.Global.AUTO_TIME_ZONE:
if (callingUid == Process.SYSTEM_UID) {
return false;
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorCallbackImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorCallbackImpl.java
index 23746ac..e034ad4 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorCallbackImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorCallbackImpl.java
@@ -43,7 +43,7 @@
}
@Override
- public boolean isTimeZoneDetectionEnabled() {
+ public boolean isAutoTimeZoneDetectionEnabled() {
return Settings.Global.getInt(mCr, Settings.Global.AUTO_TIME_ZONE, 1 /* default */) > 0;
}
@@ -66,14 +66,16 @@
}
@Override
- public void setDeviceTimeZone(String zoneId) {
+ public void setDeviceTimeZone(String zoneId, boolean sendNetworkBroadcast) {
AlarmManager alarmManager = mContext.getSystemService(AlarmManager.class);
alarmManager.setTimeZone(zoneId);
- // TODO Nothing in the platform appears to listen for this. Remove it.
- Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putExtra("time-zone", zoneId);
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+ if (sendNetworkBroadcast) {
+ // TODO Nothing in the platform appears to listen for this. Remove it.
+ Intent intent = new Intent(TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE);
+ intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+ intent.putExtra("time-zone", zoneId);
+ mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+ }
}
}
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
index 558aa9e..9a1fe65 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorService.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.timezonedetector.ITimeZoneDetectorService;
+import android.app.timezonedetector.ManualTimeZoneSuggestion;
import android.app.timezonedetector.PhoneTimeZoneSuggestion;
import android.content.ContentResolver;
import android.content.Context;
@@ -28,7 +29,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
-import com.android.internal.util.IndentingPrintWriter;
import com.android.server.FgThread;
import com.android.server.SystemService;
@@ -75,7 +75,7 @@
Settings.Global.getUriFor(Settings.Global.AUTO_TIME_ZONE), true,
new ContentObserver(handler) {
public void onChange(boolean selfChange) {
- timeZoneDetectorStrategy.handleTimeZoneDetectionChange();
+ timeZoneDetectorStrategy.handleAutoTimeZoneDetectionChange();
}
});
@@ -91,8 +91,16 @@
}
@Override
+ public void suggestManualTimeZone(@NonNull ManualTimeZoneSuggestion timeZoneSuggestion) {
+ enforceSuggestManualTimeZonePermission();
+ Objects.requireNonNull(timeZoneSuggestion);
+
+ mHandler.post(() -> mTimeZoneDetectorStrategy.suggestManualTimeZone(timeZoneSuggestion));
+ }
+
+ @Override
public void suggestPhoneTimeZone(@NonNull PhoneTimeZoneSuggestion timeZoneSuggestion) {
- enforceSetTimeZonePermission();
+ enforceSuggestPhoneTimeZonePermission();
Objects.requireNonNull(timeZoneSuggestion);
mHandler.post(() -> mTimeZoneDetectorStrategy.suggestPhoneTimeZone(timeZoneSuggestion));
@@ -103,13 +111,17 @@
@Nullable String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
- mTimeZoneDetectorStrategy.dumpState(pw);
- mTimeZoneDetectorStrategy.dumpLogs(new IndentingPrintWriter(pw, " "));
+ mTimeZoneDetectorStrategy.dumpState(pw, args);
}
- private void enforceSetTimeZonePermission() {
+ private void enforceSuggestPhoneTimeZonePermission() {
mContext.enforceCallingPermission(
android.Manifest.permission.SET_TIME_ZONE, "set time zone");
}
+
+ private void enforceSuggestManualTimeZonePermission() {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.SET_TIME_ZONE, "set time zone");
+ }
}
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
index e24c089..5db12c7 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategy.java
@@ -21,8 +21,10 @@
import static android.app.timezonedetector.PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET;
import static android.app.timezonedetector.PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.timezonedetector.ManualTimeZoneSuggestion;
import android.app.timezonedetector.PhoneTimeZoneSuggestion;
import android.content.Context;
import android.util.ArrayMap;
@@ -34,22 +36,34 @@
import com.android.internal.util.IndentingPrintWriter;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.LinkedList;
import java.util.Map;
import java.util.Objects;
/**
- * A singleton, stateful time zone detection strategy that is aware of multiple phone devices. It
- * keeps track of the most recent suggestion from each phone and it uses the best based on a scoring
- * algorithm. If several phones provide the same score then the phone with the lowest numeric ID
- * "wins". If the situation changes and it is no longer possible to be confident about the time
- * zone, phones must submit an empty suggestion in order to "withdraw" their previous suggestion.
+ * A singleton, stateful time zone detection strategy that is aware of user (manual) suggestions and
+ * suggestions from multiple phone devices. Suggestions are acted on or ignored as needed, dependent
+ * on the current "auto time zone detection" setting.
+ *
+ * <p>For automatic detection it keeps track of the most recent suggestion from each phone it uses
+ * the best suggestion based on a scoring algorithm. If several phones provide the same score then
+ * the phone with the lowest numeric ID "wins". If the situation changes and it is no longer
+ * possible to be confident about the time zone, phones must submit an empty suggestion in order to
+ * "withdraw" their previous suggestion.
*/
public class TimeZoneDetectorStrategy {
/**
* Used by {@link TimeZoneDetectorStrategy} to interact with the surrounding service. It can be
* faked for tests.
+ *
+ * <p>Note: Because the system properties-derived values like
+ * {@link #isAutoTimeZoneDetectionEnabled()}, {@link #isAutoTimeZoneDetectionEnabled()},
+ * {@link #getDeviceTimeZone()} can be modified independently and from different threads (and
+ * processes!), their use are prone to race conditions. That will be true until the
+ * responsibility for setting their values is moved to {@link TimeZoneDetectorStrategy}.
*/
@VisibleForTesting
public interface Callback {
@@ -57,7 +71,7 @@
/**
* Returns true if automatic time zone detection is enabled in settings.
*/
- boolean isTimeZoneDetectionEnabled();
+ boolean isAutoTimeZoneDetectionEnabled();
/**
* Returns true if the device has had an explicit time zone set.
@@ -72,22 +86,34 @@
/**
* Sets the device's time zone.
*/
- void setDeviceTimeZone(@NonNull String zoneId);
+ void setDeviceTimeZone(@NonNull String zoneId, boolean sendNetworkBroadcast);
}
- static final String LOG_TAG = "TimeZoneDetectorStrategy";
- static final boolean DBG = false;
+ private static final String LOG_TAG = "TimeZoneDetectorStrategy";
+ private static final boolean DBG = false;
+
+ @IntDef({ ORIGIN_PHONE, ORIGIN_MANUAL })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Origin {}
+
+ /** Used when a time value originated from a telephony signal. */
+ @Origin
+ private static final int ORIGIN_PHONE = 1;
+
+ /** Used when a time value originated from a user / manual settings. */
+ @Origin
+ private static final int ORIGIN_MANUAL = 2;
/**
- * The abstract score for an empty or invalid suggestion.
+ * The abstract score for an empty or invalid phone suggestion.
*
- * Used to score suggestions where there is no zone.
+ * Used to score phone suggestions where there is no zone.
*/
@VisibleForTesting
- public static final int SCORE_NONE = 0;
+ public static final int PHONE_SCORE_NONE = 0;
/**
- * The abstract score for a low quality suggestion.
+ * The abstract score for a low quality phone suggestion.
*
* Used to score suggestions where:
* The suggested zone ID is one of several possibilities, and the possibilities have different
@@ -96,10 +122,10 @@
* You would have to be quite desperate to want to use this choice.
*/
@VisibleForTesting
- public static final int SCORE_LOW = 1;
+ public static final int PHONE_SCORE_LOW = 1;
/**
- * The abstract score for a medium quality suggestion.
+ * The abstract score for a medium quality phone suggestion.
*
* Used for:
* The suggested zone ID is one of several possibilities but at least the possibilities have the
@@ -107,33 +133,36 @@
* switch to DST at the wrong time and (for example) their calendar events.
*/
@VisibleForTesting
- public static final int SCORE_MEDIUM = 2;
+ public static final int PHONE_SCORE_MEDIUM = 2;
/**
- * The abstract score for a high quality suggestion.
+ * The abstract score for a high quality phone suggestion.
*
* Used for:
* The suggestion was for one zone ID and the answer was unambiguous and likely correct given
* the info available.
*/
@VisibleForTesting
- public static final int SCORE_HIGH = 3;
+ public static final int PHONE_SCORE_HIGH = 3;
/**
- * The abstract score for a highest quality suggestion.
+ * The abstract score for a highest quality phone suggestion.
*
* Used for:
* Suggestions that must "win" because they constitute test or emulator zone ID.
*/
@VisibleForTesting
- public static final int SCORE_HIGHEST = 4;
+ public static final int PHONE_SCORE_HIGHEST = 4;
- /** The threshold at which suggestions are good enough to use to set the device's time zone. */
+ /**
+ * The threshold at which phone suggestions are good enough to use to set the device's time
+ * zone.
+ */
@VisibleForTesting
- public static final int SCORE_USAGE_THRESHOLD = SCORE_MEDIUM;
+ public static final int PHONE_SCORE_USAGE_THRESHOLD = PHONE_SCORE_MEDIUM;
/** The number of previous phone suggestions to keep for each ID (for use during debugging). */
- private static final int KEEP_SUGGESTION_HISTORY_SIZE = 30;
+ private static final int KEEP_PHONE_SUGGESTION_HISTORY_SIZE = 30;
@NonNull
private final Callback mCallback;
@@ -146,24 +175,16 @@
private final LocalLog mTimeZoneChangesLog = new LocalLog(30);
/**
- * A mapping from phoneId to a linked list of time zone suggestions (the head being the latest).
- * We typically expect one or two entries in this Map: devices will have a small number
+ * A mapping from phoneId to a linked list of phone time zone suggestions (the head being the
+ * latest). We typically expect one or two entries in this Map: devices will have a small number
* of telephony devices and phoneIds are assumed to be stable. The LinkedList associated with
- * the ID will not exceed {@link #KEEP_SUGGESTION_HISTORY_SIZE} in size.
+ * the ID will not exceed {@link #KEEP_PHONE_SUGGESTION_HISTORY_SIZE} in size.
*/
@GuardedBy("this")
private ArrayMap<Integer, LinkedList<QualifiedPhoneTimeZoneSuggestion>> mSuggestionByPhoneId =
new ArrayMap<>();
/**
- * The most recent best guess of time zone from all phones. Can be {@code null} to indicate
- * there would be no current suggestion.
- */
- @GuardedBy("this")
- @Nullable
- private QualifiedPhoneTimeZoneSuggestion mCurrentSuggestion;
-
- /**
* Creates a new instance of {@link TimeZoneDetectorStrategy}.
*/
public static TimeZoneDetectorStrategy create(Context context) {
@@ -176,56 +197,68 @@
mCallback = Objects.requireNonNull(callback);
}
+ /** Process the suggested manually- / user-entered time zone. */
+ public synchronized void suggestManualTimeZone(@NonNull ManualTimeZoneSuggestion suggestion) {
+ Objects.requireNonNull(suggestion);
+
+ String timeZoneId = suggestion.getZoneId();
+ String cause = "Manual time suggestion received: suggestion=" + suggestion;
+ setDeviceTimeZoneIfRequired(ORIGIN_MANUAL, timeZoneId, cause);
+ }
+
/**
* Suggests a time zone for the device, or withdraws a previous suggestion if
* {@link PhoneTimeZoneSuggestion#getZoneId()} is {@code null}. The suggestion is scoped to a
* specific {@link PhoneTimeZoneSuggestion#getPhoneId() phone}.
* See {@link PhoneTimeZoneSuggestion} for an explanation of the metadata associated with a
- * suggestion. The service uses suggestions to decide whether to modify the device's time zone
+ * suggestion. The strategy uses suggestions to decide whether to modify the device's time zone
* setting and what to set it to.
*/
- public synchronized void suggestPhoneTimeZone(@NonNull PhoneTimeZoneSuggestion newSuggestion) {
+ public synchronized void suggestPhoneTimeZone(@NonNull PhoneTimeZoneSuggestion suggestion) {
if (DBG) {
- Slog.d(LOG_TAG, "suggestPhoneTimeZone: newSuggestion=" + newSuggestion);
+ Slog.d(LOG_TAG, "Phone suggestion received. newSuggestion=" + suggestion);
}
- Objects.requireNonNull(newSuggestion);
+ Objects.requireNonNull(suggestion);
- int score = scoreSuggestion(newSuggestion);
+ // Score the suggestion.
+ int score = scorePhoneSuggestion(suggestion);
QualifiedPhoneTimeZoneSuggestion scoredSuggestion =
- new QualifiedPhoneTimeZoneSuggestion(newSuggestion, score);
+ new QualifiedPhoneTimeZoneSuggestion(suggestion, score);
- // Record the suggestion against the correct phoneId.
+ // Store the suggestion against the correct phoneId.
LinkedList<QualifiedPhoneTimeZoneSuggestion> suggestions =
- mSuggestionByPhoneId.get(newSuggestion.getPhoneId());
+ mSuggestionByPhoneId.get(suggestion.getPhoneId());
if (suggestions == null) {
suggestions = new LinkedList<>();
- mSuggestionByPhoneId.put(newSuggestion.getPhoneId(), suggestions);
+ mSuggestionByPhoneId.put(suggestion.getPhoneId(), suggestions);
}
suggestions.addFirst(scoredSuggestion);
- if (suggestions.size() > KEEP_SUGGESTION_HISTORY_SIZE) {
+ if (suggestions.size() > KEEP_PHONE_SUGGESTION_HISTORY_SIZE) {
suggestions.removeLast();
}
- // Now run the competition between the phones' suggestions.
- doTimeZoneDetection();
+ // Now perform auto time zone detection. The new suggestion may be used to modify the time
+ // zone setting.
+ String reason = "New phone time suggested. suggestion=" + suggestion;
+ doAutoTimeZoneDetection(reason);
}
- private static int scoreSuggestion(@NonNull PhoneTimeZoneSuggestion suggestion) {
+ private static int scorePhoneSuggestion(@NonNull PhoneTimeZoneSuggestion suggestion) {
int score;
if (suggestion.getZoneId() == null) {
- score = SCORE_NONE;
+ score = PHONE_SCORE_NONE;
} else if (suggestion.getMatchType() == MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY
|| suggestion.getMatchType() == MATCH_TYPE_EMULATOR_ZONE_ID) {
// Handle emulator / test cases : These suggestions should always just be used.
- score = SCORE_HIGHEST;
+ score = PHONE_SCORE_HIGHEST;
} else if (suggestion.getQuality() == QUALITY_SINGLE_ZONE) {
- score = SCORE_HIGH;
+ score = PHONE_SCORE_HIGH;
} else if (suggestion.getQuality() == QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET) {
// The suggestion may be wrong, but at least the offset should be correct.
- score = SCORE_MEDIUM;
+ score = PHONE_SCORE_MEDIUM;
} else if (suggestion.getQuality() == QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS) {
// The suggestion has a good chance of being wrong.
- score = SCORE_LOW;
+ score = PHONE_SCORE_LOW;
} else {
throw new AssertionError();
}
@@ -235,47 +268,46 @@
/**
* Finds the best available time zone suggestion from all phones. If it is high-enough quality
* and automatic time zone detection is enabled then it will be set on the device. The outcome
- * can be that this service becomes / remains un-opinionated and nothing is set.
+ * can be that this strategy becomes / remains un-opinionated and nothing is set.
*/
@GuardedBy("this")
- private void doTimeZoneDetection() {
- QualifiedPhoneTimeZoneSuggestion bestSuggestion = findBestSuggestion();
- boolean timeZoneDetectionEnabled = mCallback.isTimeZoneDetectionEnabled();
+ private void doAutoTimeZoneDetection(@NonNull String detectionReason) {
+ if (!mCallback.isAutoTimeZoneDetectionEnabled()) {
+ // Avoid doing unnecessary work with this (race-prone) check.
+ return;
+ }
+
+ QualifiedPhoneTimeZoneSuggestion bestPhoneSuggestion = findBestPhoneSuggestion();
// Work out what to do with the best suggestion.
- if (bestSuggestion == null) {
- // There is no suggestion. Become un-opinionated.
+ if (bestPhoneSuggestion == null) {
+ // There is no phone suggestion available at all. Become un-opinionated.
if (DBG) {
- Slog.d(LOG_TAG, "doTimeZoneDetection: No good suggestion."
- + " bestSuggestion=null"
- + ", timeZoneDetectionEnabled=" + timeZoneDetectionEnabled);
+ Slog.d(LOG_TAG, "Could not determine time zone: No best phone suggestion."
+ + " detectionReason=" + detectionReason);
}
- mCurrentSuggestion = null;
return;
}
// Special case handling for uninitialized devices. This should only happen once.
- String newZoneId = bestSuggestion.suggestion.getZoneId();
+ String newZoneId = bestPhoneSuggestion.suggestion.getZoneId();
if (newZoneId != null && !mCallback.isDeviceTimeZoneInitialized()) {
- Slog.i(LOG_TAG, "doTimeZoneDetection: Device has no time zone set so might set the"
- + " device to the best available suggestion."
- + " bestSuggestion=" + bestSuggestion
- + ", timeZoneDetectionEnabled=" + timeZoneDetectionEnabled);
-
- mCurrentSuggestion = bestSuggestion;
- if (timeZoneDetectionEnabled) {
- setDeviceTimeZone(bestSuggestion.suggestion);
- }
+ String cause = "Device has no time zone set. Attempting to set the device to the best"
+ + " available suggestion."
+ + " bestPhoneSuggestion=" + bestPhoneSuggestion
+ + ", detectionReason=" + detectionReason;
+ Slog.i(LOG_TAG, cause);
+ setDeviceTimeZoneIfRequired(ORIGIN_PHONE, newZoneId, cause);
return;
}
- boolean suggestionGoodEnough = bestSuggestion.score >= SCORE_USAGE_THRESHOLD;
+ boolean suggestionGoodEnough = bestPhoneSuggestion.score >= PHONE_SCORE_USAGE_THRESHOLD;
if (!suggestionGoodEnough) {
if (DBG) {
- Slog.d(LOG_TAG, "doTimeZoneDetection: Suggestion not good enough."
- + " bestSuggestion=" + bestSuggestion);
+ Slog.d(LOG_TAG, "Best suggestion not good enough."
+ + " bestPhoneSuggestion=" + bestPhoneSuggestion
+ + ", detectionReason=" + detectionReason);
}
- mCurrentSuggestion = null;
return;
}
@@ -283,63 +315,84 @@
// zone ID.
if (newZoneId == null) {
Slog.w(LOG_TAG, "Empty zone suggestion scored higher than expected. This is an error:"
- + " bestSuggestion=" + bestSuggestion);
- mCurrentSuggestion = null;
+ + " bestPhoneSuggestion=" + bestPhoneSuggestion
+ + " detectionReason=" + detectionReason);
return;
}
- // There is a good suggestion. Store the suggestion and set the device time zone if
- // settings allow.
- mCurrentSuggestion = bestSuggestion;
-
- // Only set the device time zone if time zone detection is enabled.
- if (!timeZoneDetectionEnabled) {
- if (DBG) {
- Slog.d(LOG_TAG, "doTimeZoneDetection: Not setting the time zone because time zone"
- + " detection is disabled."
- + " bestSuggestion=" + bestSuggestion);
- }
- return;
- }
- PhoneTimeZoneSuggestion suggestion = bestSuggestion.suggestion;
- setDeviceTimeZone(suggestion);
+ String zoneId = bestPhoneSuggestion.suggestion.getZoneId();
+ String cause = "Found good suggestion."
+ + ", bestPhoneSuggestion=" + bestPhoneSuggestion
+ + ", detectionReason=" + detectionReason;
+ setDeviceTimeZoneIfRequired(ORIGIN_PHONE, zoneId, cause);
}
- private void setDeviceTimeZone(@NonNull PhoneTimeZoneSuggestion suggestion) {
- String currentZoneId = mCallback.getDeviceTimeZone();
- String newZoneId = suggestion.getZoneId();
+ @GuardedBy("this")
+ private void setDeviceTimeZoneIfRequired(
+ @Origin int origin, @NonNull String newZoneId, @NonNull String cause) {
+ Objects.requireNonNull(newZoneId);
+ Objects.requireNonNull(cause);
- // Paranoia: This should never happen.
- if (newZoneId == null) {
- Slog.w(LOG_TAG, "setDeviceTimeZone: Suggested zone is null."
- + " timeZoneSuggestion=" + suggestion);
- return;
+ boolean sendNetworkBroadcast = (origin == ORIGIN_PHONE);
+ boolean isOriginAutomatic = isOriginAutomatic(origin);
+ if (isOriginAutomatic) {
+ if (!mCallback.isAutoTimeZoneDetectionEnabled()) {
+ if (DBG) {
+ Slog.d(LOG_TAG, "Auto time zone detection is not enabled."
+ + " origin=" + origin
+ + ", newZoneId=" + newZoneId
+ + ", cause=" + cause);
+ }
+ return;
+ }
+ } else {
+ if (mCallback.isAutoTimeZoneDetectionEnabled()) {
+ if (DBG) {
+ Slog.d(LOG_TAG, "Auto time zone detection is enabled."
+ + " origin=" + origin
+ + ", newZoneId=" + newZoneId
+ + ", cause=" + cause);
+ }
+ return;
+ }
}
+ String currentZoneId = mCallback.getDeviceTimeZone();
+
// Avoid unnecessary changes / intents.
if (newZoneId.equals(currentZoneId)) {
// No need to set the device time zone - the setting is already what we would be
// suggesting.
if (DBG) {
- Slog.d(LOG_TAG, "setDeviceTimeZone: No need to change the time zone;"
+ Slog.d(LOG_TAG, "No need to change the time zone;"
+ " device is already set to the suggested zone."
- + " timeZoneSuggestion=" + suggestion);
+ + " origin=" + origin
+ + ", newZoneId=" + newZoneId
+ + ", cause=" + cause);
}
return;
}
- String msg = "Changing device time zone. currentZoneId=" + currentZoneId
- + ", timeZoneSuggestion=" + suggestion;
+ mCallback.setDeviceTimeZone(newZoneId, sendNetworkBroadcast);
+ String msg = "Set device time zone."
+ + " origin=" + origin
+ + ", currentZoneId=" + currentZoneId
+ + ", newZoneId=" + newZoneId
+ + ", sendNetworkBroadcast" + sendNetworkBroadcast
+ + ", cause=" + cause;
if (DBG) {
Slog.d(LOG_TAG, msg);
}
mTimeZoneChangesLog.log(msg);
- mCallback.setDeviceTimeZone(newZoneId);
+ }
+
+ private static boolean isOriginAutomatic(@Origin int origin) {
+ return origin == ORIGIN_PHONE;
}
@GuardedBy("this")
@Nullable
- private QualifiedPhoneTimeZoneSuggestion findBestSuggestion() {
+ private QualifiedPhoneTimeZoneSuggestion findBestPhoneSuggestion() {
QualifiedPhoneTimeZoneSuggestion bestSuggestion = null;
// Iterate over the latest QualifiedPhoneTimeZoneSuggestion objects received for each phone
@@ -376,38 +429,44 @@
}
/**
- * Returns the current best suggestion. Not intended for general use: it is used during tests
- * to check service behavior.
+ * Returns the current best phone suggestion. Not intended for general use: it is used during
+ * tests to check strategy behavior.
*/
@VisibleForTesting
@Nullable
- public synchronized QualifiedPhoneTimeZoneSuggestion findBestSuggestionForTests() {
- return findBestSuggestion();
+ public synchronized QualifiedPhoneTimeZoneSuggestion findBestPhoneSuggestionForTests() {
+ return findBestPhoneSuggestion();
}
/**
- * Called when the has been a change to the automatic time zone detection setting.
+ * Called when there has been a change to the automatic time zone detection setting.
*/
@VisibleForTesting
- public synchronized void handleTimeZoneDetectionChange() {
+ public synchronized void handleAutoTimeZoneDetectionChange() {
if (DBG) {
Slog.d(LOG_TAG, "handleTimeZoneDetectionChange() called");
}
- if (mCallback.isTimeZoneDetectionEnabled()) {
+ if (mCallback.isAutoTimeZoneDetectionEnabled()) {
// When the user enabled time zone detection, run the time zone detection and change the
// device time zone if possible.
- doTimeZoneDetection();
+ String reason = "Auto time zone detection setting enabled.";
+ doAutoTimeZoneDetection(reason);
}
}
/**
- * Dumps any logs held to the supplied writer.
+ * Dumps internal state such as field values.
*/
- public synchronized void dumpLogs(IndentingPrintWriter ipw) {
- ipw.println("TimeZoneDetectorStrategy:");
+ public synchronized void dumpState(PrintWriter pw, String[] args) {
+ pw.println("TimeZoneDetectorStrategy:");
+ pw.println("mCallback.isTimeZoneDetectionEnabled()="
+ + mCallback.isAutoTimeZoneDetectionEnabled());
+ pw.println("mCallback.isDeviceTimeZoneInitialized()="
+ + mCallback.isDeviceTimeZoneInitialized());
+ pw.println("mCallback.getDeviceTimeZone()="
+ + mCallback.getDeviceTimeZone());
- ipw.increaseIndent(); // level 1
-
+ IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
ipw.println("Time zone change log:");
ipw.increaseIndent(); // level 2
mTimeZoneChangesLog.dump(ipw);
@@ -427,24 +486,13 @@
}
ipw.decreaseIndent(); // level 2
ipw.decreaseIndent(); // level 1
- }
+ ipw.flush();
- /**
- * Dumps internal state such as field values.
- */
- public synchronized void dumpState(PrintWriter pw) {
- pw.println("mCurrentSuggestion=" + mCurrentSuggestion);
- pw.println("mCallback.isTimeZoneDetectionEnabled()="
- + mCallback.isTimeZoneDetectionEnabled());
- pw.println("mCallback.isDeviceTimeZoneInitialized()="
- + mCallback.isDeviceTimeZoneInitialized());
- pw.println("mCallback.getDeviceTimeZone()="
- + mCallback.getDeviceTimeZone());
pw.flush();
}
/**
- * A method used to inspect service state during tests. Not intended for general use.
+ * A method used to inspect strategy state during tests. Not intended for general use.
*/
@VisibleForTesting
public synchronized QualifiedPhoneTimeZoneSuggestion getLatestPhoneSuggestion(int phoneId) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index b264684..2499ad8 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -7366,6 +7366,7 @@
}
}
+ // TODO: (b/145604635) Add upgrade case
// Turn AUTO_TIME on in settings if it is required
if (required) {
long ident = mInjector.binderClearCallingIdentity();
@@ -7409,6 +7410,42 @@
}
}
+ /**
+ * Set whether auto time is enabled on the device.
+ */
+ @Override
+ public void setAutoTime(ComponentName who, boolean enabled) {
+ if (!mHasFeature) {
+ return;
+ }
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ // TODO (b/145286957) Refactor security checks
+ enforceDeviceOwnerOrProfileOwnerOnUser0OrProfileOwnerOrganizationOwned();
+
+ mInjector.binderWithCleanCallingIdentity(() ->
+ mInjector.settingsGlobalPutInt(Settings.Global.AUTO_TIME, enabled ? 1 : 0));
+
+ DevicePolicyEventLogger
+ .createEvent(DevicePolicyEnums.SET_AUTO_TIME)
+ .setAdmin(who)
+ .setBoolean(enabled)
+ .write();
+ }
+
+ /**
+ * Returns whether or auto time is used on the device or not.
+ */
+ @Override
+ public boolean getAutoTime(ComponentName who) {
+ if (!mHasFeature) {
+ return false;
+ }
+ Preconditions.checkNotNull(who, "ComponentName is null");
+ enforceDeviceOwnerOrProfileOwnerOnUser0OrProfileOwnerOrganizationOwned();
+
+ return mInjector.settingsGlobalGetInt(Global.AUTO_TIME, 0) > 0;
+ }
+
@Override
public void setForceEphemeralUsers(ComponentName who, boolean forceEphemeralUsers) {
if (!mHasFeature) {
@@ -8599,20 +8636,42 @@
@Override
public boolean checkDeviceIdentifierAccess(String packageName, int pid, int uid) {
- // If the caller is not a system app then it should only be able to check its own device
- // identifier access.
- int callingUid = mInjector.binderGetCallingUid();
- int callingPid = mInjector.binderGetCallingPid();
- if (UserHandle.getAppId(callingUid) >= Process.FIRST_APPLICATION_UID
- && (callingUid != uid || callingPid != pid)) {
- String message = String.format(
- "Calling uid %d, pid %d cannot check device identifier access for package %s "
- + "(uid=%d, pid=%d)", callingUid, callingPid, packageName, uid, pid);
- Log.w(LOG_TAG, message);
- throw new SecurityException(message);
- }
+ ensureCallerIdentityMatchesIfNotSystem(packageName, pid, uid);
+
// Verify that the specified packages matches the provided uid.
- int userId = UserHandle.getUserId(uid);
+ if (!doesPackageMatchUid(packageName, uid)) {
+ return false;
+ }
+ // A device or profile owner must also have the READ_PHONE_STATE permission to access device
+ // identifiers. If the package being checked does not have this permission then deny access.
+ if (mContext.checkPermission(android.Manifest.permission.READ_PHONE_STATE, pid, uid)
+ != PackageManager.PERMISSION_GRANTED) {
+ return false;
+ }
+
+ // Allow access to the device owner or delegate cert installer.
+ ComponentName deviceOwner = getDeviceOwnerComponent(true);
+ if (deviceOwner != null && (deviceOwner.getPackageName().equals(packageName)
+ || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) {
+ return true;
+ }
+ final int userId = UserHandle.getUserId(uid);
+ // Allow access to the profile owner for the specified user, or delegate cert installer
+ // But only if this is an organization-owned device.
+ ComponentName profileOwner = getProfileOwnerAsUser(userId);
+ if (profileOwner != null && canProfileOwnerAccessDeviceIds(userId)
+ && (profileOwner.getPackageName().equals(packageName)
+ || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) {
+ return true;
+ }
+
+ Log.w(LOG_TAG, String.format("Package %s (uid=%d, pid=%d) cannot access Device IDs",
+ packageName, uid, pid));
+ return false;
+ }
+
+ private boolean doesPackageMatchUid(String packageName, int uid) {
+ final int userId = UserHandle.getUserId(uid);
try {
ApplicationInfo appInfo = mIPackageManager.getApplicationInfo(packageName, 0, userId);
// Since this call goes directly to PackageManagerService a NameNotFoundException is not
@@ -8634,29 +8693,22 @@
Log.e(LOG_TAG, "Exception caught obtaining appInfo for package " + packageName, e);
return false;
}
- // A device or profile owner must also have the READ_PHONE_STATE permission to access device
- // identifiers. If the package being checked does not have this permission then deny access.
- if (mContext.checkPermission(android.Manifest.permission.READ_PHONE_STATE, pid, uid)
- != PackageManager.PERMISSION_GRANTED) {
- return false;
- }
+ return true;
+ }
- // Allow access to the device owner or delegate cert installer.
- ComponentName deviceOwner = getDeviceOwnerComponent(true);
- if (deviceOwner != null && (deviceOwner.getPackageName().equals(packageName)
- || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) {
- return true;
+ private void ensureCallerIdentityMatchesIfNotSystem(String packageName, int pid, int uid) {
+ // If the caller is not a system app then it should only be able to check its own device
+ // identifier access.
+ int callingUid = mInjector.binderGetCallingUid();
+ int callingPid = mInjector.binderGetCallingPid();
+ if (UserHandle.getAppId(callingUid) >= Process.FIRST_APPLICATION_UID
+ && (callingUid != uid || callingPid != pid)) {
+ String message = String.format(
+ "Calling uid %d, pid %d cannot check device identifier access for package %s "
+ + "(uid=%d, pid=%d)", callingUid, callingPid, packageName, uid, pid);
+ Log.w(LOG_TAG, message);
+ throw new SecurityException(message);
}
- // Allow access to the profile owner for the specified user, or delegate cert installer
- ComponentName profileOwner = getProfileOwnerAsUser(userId);
- if (profileOwner != null && (profileOwner.getPackageName().equals(packageName)
- || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) {
- return true;
- }
-
- Log.w(LOG_TAG, String.format("Package %s (uid=%d, pid=%d) cannot access Device IDs",
- packageName, uid, pid));
- return false;
}
/**
@@ -8883,6 +8935,28 @@
"Only profile owner, device owner and system may call this method.");
}
+ private ActiveAdmin enforceDeviceOwnerOrProfileOwnerOnUser0OrProfileOwnerOrganizationOwned() {
+ synchronized (getLockObject()) {
+ // Check if there is a device owner
+ ActiveAdmin deviceOwner = getActiveAdminWithPolicyForUidLocked(null,
+ DeviceAdminInfo.USES_POLICY_DEVICE_OWNER, mInjector.binderGetCallingUid());
+ if (deviceOwner != null) return deviceOwner;
+
+ ActiveAdmin profileOwner = getActiveAdminWithPolicyForUidLocked(null,
+ DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, mInjector.binderGetCallingUid());
+
+ // Check if there is a profile owner of an organization owned device
+ if (isProfileOwnerOfOrganizationOwnedDevice(profileOwner)) return profileOwner;
+
+ // Check if there is a profile owner called on user 0
+ if (profileOwner != null) {
+ enforceCallerSystemUserHandle();
+ return profileOwner;
+ }
+ }
+ throw new SecurityException("No active admin found");
+ }
+
private void enforceProfileOwnerOrFullCrossUsersPermission(int userId) {
if (userId == mInjector.userHandleGetCallingUserId()) {
synchronized (getLockObject()) {
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 162e766..0590020 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -2635,6 +2635,16 @@
mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
}
+ private void setupProfileOwnerOnUser0() throws Exception {
+ mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
+
+ setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
+ dpm.setActiveAdmin(admin1, false);
+ assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
+
+ mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
+ }
+
private void setupDeviceOwner() throws Exception {
mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
@@ -3611,6 +3621,43 @@
Settings.System.SCREEN_BRIGHTNESS, "0", DpmMockContext.CALLER_USER_HANDLE);
}
+ public void testSetAutoTimeModifiesSetting() throws Exception {
+ mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+ setupDeviceOwner();
+ dpm.setAutoTime(admin1, true);
+ verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 1);
+
+ dpm.setAutoTime(admin1, false);
+ verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 0);
+ }
+
+ public void testSetAutoTimeWithPOOnUser0() throws Exception {
+ mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+ setupProfileOwnerOnUser0();
+ dpm.setAutoTime(admin1, true);
+ verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 1);
+
+ dpm.setAutoTime(admin1, false);
+ verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 0);
+ }
+
+ public void testSetAutoTimeFailWithPONotOnUser0() throws Exception {
+ setupProfileOwner();
+ assertExpectException(SecurityException.class, null, () -> dpm.setAutoTime(admin1, false));
+ verify(getServices().settings, never()).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 0);
+ }
+
+ public void testSetAutoTimeWithPOOfOrganizationOwnedDevice() throws Exception {
+ setupProfileOwner();
+ configureProfileOwnerOfOrgOwnedDevice(admin1, DpmMockContext.CALLER_USER_HANDLE);
+
+ dpm.setAutoTime(admin1, true);
+ verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 1);
+
+ dpm.setAutoTime(admin1, false);
+ verify(getServices().settings).settingsGlobalPutInt(Settings.Global.AUTO_TIME, 0);
+ }
+
public void testSetTime() throws Exception {
mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
setupDeviceOwner();
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyTest.java
index f9f23c3..270436d 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyTest.java
@@ -24,18 +24,19 @@
import static android.app.timezonedetector.PhoneTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET;
import static android.app.timezonedetector.PhoneTimeZoneSuggestion.QUALITY_SINGLE_ZONE;
-import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.SCORE_HIGH;
-import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.SCORE_HIGHEST;
-import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.SCORE_LOW;
-import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.SCORE_MEDIUM;
-import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.SCORE_NONE;
-import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.SCORE_USAGE_THRESHOLD;
+import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.PHONE_SCORE_HIGH;
+import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.PHONE_SCORE_HIGHEST;
+import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.PHONE_SCORE_LOW;
+import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.PHONE_SCORE_MEDIUM;
+import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.PHONE_SCORE_NONE;
+import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.PHONE_SCORE_USAGE_THRESHOLD;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import android.app.timezonedetector.ManualTimeZoneSuggestion;
import android.app.timezonedetector.PhoneTimeZoneSuggestion;
import android.app.timezonedetector.PhoneTimeZoneSuggestion.MatchType;
import android.app.timezonedetector.PhoneTimeZoneSuggestion.Quality;
@@ -49,6 +50,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
+import java.util.Objects;
/**
* White-box unit tests for {@link TimeZoneDetectorStrategy}.
@@ -64,16 +66,17 @@
// than the previous.
private static final SuggestionTestCase[] TEST_CASES = new SuggestionTestCase[] {
newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY,
- QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS, SCORE_LOW),
+ QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS, PHONE_SCORE_LOW),
newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY, QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET,
- SCORE_MEDIUM),
+ PHONE_SCORE_MEDIUM),
newTestCase(MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET,
- QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, SCORE_MEDIUM),
- newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY, QUALITY_SINGLE_ZONE, SCORE_HIGH),
- newTestCase(MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET, QUALITY_SINGLE_ZONE, SCORE_HIGH),
+ QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, PHONE_SCORE_MEDIUM),
+ newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY, QUALITY_SINGLE_ZONE, PHONE_SCORE_HIGH),
+ newTestCase(MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET, QUALITY_SINGLE_ZONE,
+ PHONE_SCORE_HIGH),
newTestCase(MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY,
- QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, SCORE_HIGHEST),
- newTestCase(MATCH_TYPE_EMULATOR_ZONE_ID, QUALITY_SINGLE_ZONE, SCORE_HIGHEST),
+ QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, PHONE_SCORE_HIGHEST),
+ newTestCase(MATCH_TYPE_EMULATOR_ZONE_ID, QUALITY_SINGLE_ZONE, PHONE_SCORE_HIGHEST),
};
private TimeZoneDetectorStrategy mTimeZoneDetectorStrategy;
@@ -87,11 +90,11 @@
}
@Test
- public void testEmptySuggestions() {
+ public void testEmptyPhoneSuggestions() {
PhoneTimeZoneSuggestion phone1TimeZoneSuggestion = createEmptyPhone1Suggestion();
PhoneTimeZoneSuggestion phone2TimeZoneSuggestion = createEmptyPhone2Suggestion();
Script script = new Script()
- .initializeTimeZoneDetectionEnabled(true)
+ .initializeAutoTimeZoneDetection(true)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
script.suggestPhoneTimeZone(phone1TimeZoneSuggestion)
@@ -99,38 +102,38 @@
// Assert internal service state.
QualifiedPhoneTimeZoneSuggestion expectedPhone1ScoredSuggestion =
- new QualifiedPhoneTimeZoneSuggestion(phone1TimeZoneSuggestion, SCORE_NONE);
+ new QualifiedPhoneTimeZoneSuggestion(phone1TimeZoneSuggestion, PHONE_SCORE_NONE);
assertEquals(expectedPhone1ScoredSuggestion,
mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
assertNull(mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE2_ID));
assertEquals(expectedPhone1ScoredSuggestion,
- mTimeZoneDetectorStrategy.findBestSuggestionForTests());
+ mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
script.suggestPhoneTimeZone(phone2TimeZoneSuggestion)
.verifyTimeZoneNotSet();
// Assert internal service state.
QualifiedPhoneTimeZoneSuggestion expectedPhone2ScoredSuggestion =
- new QualifiedPhoneTimeZoneSuggestion(phone2TimeZoneSuggestion, SCORE_NONE);
+ new QualifiedPhoneTimeZoneSuggestion(phone2TimeZoneSuggestion, PHONE_SCORE_NONE);
assertEquals(expectedPhone1ScoredSuggestion,
mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
assertEquals(expectedPhone2ScoredSuggestion,
mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE2_ID));
// Phone 1 should always beat phone 2, all other things being equal.
assertEquals(expectedPhone1ScoredSuggestion,
- mTimeZoneDetectorStrategy.findBestSuggestionForTests());
+ mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
}
@Test
- public void testFirstPlausibleSuggestionAcceptedWhenTimeZoneUninitialized() {
+ public void testFirstPlausiblePhoneSuggestionAcceptedWhenTimeZoneUninitialized() {
SuggestionTestCase testCase = newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY,
- QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS, SCORE_LOW);
+ QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS, PHONE_SCORE_LOW);
PhoneTimeZoneSuggestion lowQualitySuggestion =
testCase.createSuggestion(PHONE1_ID, "America/New_York");
// The device time zone setting is left uninitialized.
Script script = new Script()
- .initializeTimeZoneDetectionEnabled(true);
+ .initializeAutoTimeZoneDetection(true);
// The very first suggestion will be taken.
script.suggestPhoneTimeZone(lowQualitySuggestion)
@@ -142,7 +145,7 @@
assertEquals(expectedScoredSuggestion,
mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
assertEquals(expectedScoredSuggestion,
- mTimeZoneDetectorStrategy.findBestSuggestionForTests());
+ mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
// Another low quality suggestion will be ignored now that the setting is initialized.
PhoneTimeZoneSuggestion lowQualitySuggestion2 =
@@ -156,7 +159,7 @@
assertEquals(expectedScoredSuggestion2,
mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
assertEquals(expectedScoredSuggestion2,
- mTimeZoneDetectorStrategy.findBestSuggestionForTests());
+ mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
}
/**
@@ -164,12 +167,12 @@
* the strategy is "opinionated".
*/
@Test
- public void testTogglingTimeZoneDetection() {
+ public void testTogglingAutoTimeZoneDetection() {
Script script = new Script();
for (SuggestionTestCase testCase : TEST_CASES) {
// Start with the device in a known state.
- script.initializeTimeZoneDetectionEnabled(false)
+ script.initializeAutoTimeZoneDetection(false)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
PhoneTimeZoneSuggestion suggestion =
@@ -186,14 +189,14 @@
assertEquals(expectedScoredSuggestion,
mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
assertEquals(expectedScoredSuggestion,
- mTimeZoneDetectorStrategy.findBestSuggestionForTests());
+ mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
// Toggling the time zone setting on should cause the device setting to be set.
- script.timeZoneDetectionEnabled(true);
+ script.autoTimeZoneDetectionEnabled(true);
// When time zone detection is already enabled the suggestion (if it scores highly
// enough) should be set immediately.
- if (testCase.expectedScore >= SCORE_USAGE_THRESHOLD) {
+ if (testCase.expectedScore >= PHONE_SCORE_USAGE_THRESHOLD) {
script.verifyTimeZoneSetAndReset(suggestion);
} else {
script.verifyTimeZoneNotSet();
@@ -203,24 +206,24 @@
assertEquals(expectedScoredSuggestion,
mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
assertEquals(expectedScoredSuggestion,
- mTimeZoneDetectorStrategy.findBestSuggestionForTests());
+ mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
// Toggling the time zone setting should off should do nothing.
- script.timeZoneDetectionEnabled(false)
+ script.autoTimeZoneDetectionEnabled(false)
.verifyTimeZoneNotSet();
// Assert internal service state.
assertEquals(expectedScoredSuggestion,
mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
assertEquals(expectedScoredSuggestion,
- mTimeZoneDetectorStrategy.findBestSuggestionForTests());
+ mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
}
}
@Test
- public void testSuggestionsSinglePhone() {
+ public void testPhoneSuggestionsSinglePhone() {
Script script = new Script()
- .initializeTimeZoneDetectionEnabled(true)
+ .initializeAutoTimeZoneDetection(true)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID);
for (SuggestionTestCase testCase : TEST_CASES) {
@@ -254,7 +257,7 @@
new QualifiedPhoneTimeZoneSuggestion(zonePhone1Suggestion, testCase.expectedScore);
script.suggestPhoneTimeZone(zonePhone1Suggestion);
- if (testCase.expectedScore >= SCORE_USAGE_THRESHOLD) {
+ if (testCase.expectedScore >= PHONE_SCORE_USAGE_THRESHOLD) {
script.verifyTimeZoneSetAndReset(zonePhone1Suggestion);
} else {
script.verifyTimeZoneNotSet();
@@ -264,7 +267,7 @@
assertEquals(expectedZonePhone1ScoredSuggestion,
mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE1_ID));
assertEquals(expectedZonePhone1ScoredSuggestion,
- mTimeZoneDetectorStrategy.findBestSuggestionForTests());
+ mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
}
/**
@@ -278,12 +281,12 @@
PhoneTimeZoneSuggestion emptyPhone1Suggestion = createEmptyPhone1Suggestion();
PhoneTimeZoneSuggestion emptyPhone2Suggestion = createEmptyPhone2Suggestion();
QualifiedPhoneTimeZoneSuggestion expectedEmptyPhone1ScoredSuggestion =
- new QualifiedPhoneTimeZoneSuggestion(emptyPhone1Suggestion, SCORE_NONE);
+ new QualifiedPhoneTimeZoneSuggestion(emptyPhone1Suggestion, PHONE_SCORE_NONE);
QualifiedPhoneTimeZoneSuggestion expectedEmptyPhone2ScoredSuggestion =
- new QualifiedPhoneTimeZoneSuggestion(emptyPhone2Suggestion, SCORE_NONE);
+ new QualifiedPhoneTimeZoneSuggestion(emptyPhone2Suggestion, PHONE_SCORE_NONE);
Script script = new Script()
- .initializeTimeZoneDetectionEnabled(true)
+ .initializeAutoTimeZoneDetection(true)
.initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID)
// Initialize the latest suggestions as empty so we don't need to worry about nulls
// below for the first loop.
@@ -305,7 +308,7 @@
// Start the test by making a suggestion for phone 1.
script.suggestPhoneTimeZone(zonePhone1Suggestion);
- if (testCase.expectedScore >= SCORE_USAGE_THRESHOLD) {
+ if (testCase.expectedScore >= PHONE_SCORE_USAGE_THRESHOLD) {
script.verifyTimeZoneSetAndReset(zonePhone1Suggestion);
} else {
script.verifyTimeZoneNotSet();
@@ -317,7 +320,7 @@
assertEquals(expectedEmptyPhone2ScoredSuggestion,
mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE2_ID));
assertEquals(expectedZonePhone1ScoredSuggestion,
- mTimeZoneDetectorStrategy.findBestSuggestionForTests());
+ mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
// Phone 2 then makes an alternative suggestion with an identical score. Phone 1's
// suggestion should still "win" if it is above the required threshold.
@@ -331,13 +334,13 @@
mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE2_ID));
// Phone 1 should always beat phone 2, all other things being equal.
assertEquals(expectedZonePhone1ScoredSuggestion,
- mTimeZoneDetectorStrategy.findBestSuggestionForTests());
+ mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
// Withdrawing phone 1's suggestion should leave phone 2 as the new winner. Since the
// zoneId is different, the time zone setting should be updated if the score is high
// enough.
script.suggestPhoneTimeZone(emptyPhone1Suggestion);
- if (testCase.expectedScore >= SCORE_USAGE_THRESHOLD) {
+ if (testCase.expectedScore >= PHONE_SCORE_USAGE_THRESHOLD) {
script.verifyTimeZoneSetAndReset(zonePhone2Suggestion);
} else {
script.verifyTimeZoneNotSet();
@@ -349,7 +352,7 @@
assertEquals(expectedZonePhone2ScoredSuggestion,
mTimeZoneDetectorStrategy.getLatestPhoneSuggestion(PHONE2_ID));
assertEquals(expectedZonePhone2ScoredSuggestion,
- mTimeZoneDetectorStrategy.findBestSuggestionForTests());
+ mTimeZoneDetectorStrategy.findBestPhoneSuggestionForTests());
// Reset the state for the next loop.
script.suggestPhoneTimeZone(emptyPhone2Suggestion)
@@ -369,10 +372,11 @@
@Test
public void testTimeZoneDetectorStrategyDoesNotAssumeCurrentSetting() {
Script script = new Script()
- .initializeTimeZoneDetectionEnabled(true);
+ .initializeAutoTimeZoneDetection(true);
SuggestionTestCase testCase =
- newTestCase(MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET, QUALITY_SINGLE_ZONE, SCORE_HIGH);
+ newTestCase(MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET, QUALITY_SINGLE_ZONE,
+ PHONE_SCORE_HIGH);
PhoneTimeZoneSuggestion losAngelesSuggestion =
testCase.createSuggestion(PHONE1_ID, "America/Los_Angeles");
PhoneTimeZoneSuggestion newYorkSuggestion =
@@ -387,21 +391,49 @@
// Toggling time zone detection should set the device time zone only if the current setting
// value is different from the most recent phone suggestion.
- script.timeZoneDetectionEnabled(false)
+ script.autoTimeZoneDetectionEnabled(false)
.verifyTimeZoneNotSet()
- .timeZoneDetectionEnabled(true)
+ .autoTimeZoneDetectionEnabled(true)
.verifyTimeZoneNotSet();
// Simulate a user turning auto detection off, a new suggestion being made while auto
// detection is off, and the user turning it on again.
- script.timeZoneDetectionEnabled(false)
+ script.autoTimeZoneDetectionEnabled(false)
.suggestPhoneTimeZone(newYorkSuggestion)
.verifyTimeZoneNotSet();
// Latest suggestion should be used.
- script.timeZoneDetectionEnabled(true)
+ script.autoTimeZoneDetectionEnabled(true)
.verifyTimeZoneSetAndReset(newYorkSuggestion);
}
+ @Test
+ public void testManualSuggestion_autoTimeZoneDetectionEnabled() {
+ Script script = new Script()
+ .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID)
+ .initializeAutoTimeZoneDetection(true);
+
+ // Auto time zone detection is enabled so the manual suggestion should be ignored.
+ script.suggestManualTimeZone(createManualSuggestion("Europe/Paris"))
+ .verifyTimeZoneNotSet();
+ }
+
+
+ @Test
+ public void testManualSuggestion_autoTimeZoneDetectionDisabled() {
+ Script script = new Script()
+ .initializeTimeZoneSetting(ARBITRARY_TIME_ZONE_ID)
+ .initializeAutoTimeZoneDetection(false);
+
+ // Auto time zone detection is disabled so the manual suggestion should be used.
+ ManualTimeZoneSuggestion manualSuggestion = createManualSuggestion("Europe/Paris");
+ script.suggestManualTimeZone(manualSuggestion)
+ .verifyTimeZoneSetAndReset(manualSuggestion);
+ }
+
+ private ManualTimeZoneSuggestion createManualSuggestion(String zoneId) {
+ return new ManualTimeZoneSuggestion(zoneId);
+ }
+
private static PhoneTimeZoneSuggestion createEmptyPhone1Suggestion() {
return new PhoneTimeZoneSuggestion.Builder(PHONE1_ID).build();
}
@@ -410,55 +442,86 @@
return new PhoneTimeZoneSuggestion.Builder(PHONE2_ID).build();
}
- class FakeTimeZoneDetectorStrategyCallback implements TimeZoneDetectorStrategy.Callback {
+ static class FakeTimeZoneDetectorStrategyCallback implements TimeZoneDetectorStrategy.Callback {
- private boolean mTimeZoneDetectionEnabled;
- private TestState<String> mTimeZoneId = new TestState<>();
+ private boolean mAutoTimeZoneDetectionEnabled;
+ private TestState<TimeZoneChange> mTimeZoneChanges = new TestState<>();
+ private String mTimeZoneId;
@Override
- public boolean isTimeZoneDetectionEnabled() {
- return mTimeZoneDetectionEnabled;
+ public boolean isAutoTimeZoneDetectionEnabled() {
+ return mAutoTimeZoneDetectionEnabled;
}
@Override
public boolean isDeviceTimeZoneInitialized() {
- return mTimeZoneId.getLatest() != null;
+ return mTimeZoneId != null;
}
@Override
public String getDeviceTimeZone() {
- return mTimeZoneId.getLatest();
+ return mTimeZoneId;
}
@Override
- public void setDeviceTimeZone(String zoneId) {
- mTimeZoneId.set(zoneId);
+ public void setDeviceTimeZone(String zoneId, boolean withNetworkBroadcast) {
+ mTimeZoneId = zoneId;
+ mTimeZoneChanges.set(new TimeZoneChange(zoneId, withNetworkBroadcast));
}
- void initializeTimeZoneDetectionEnabled(boolean enabled) {
- mTimeZoneDetectionEnabled = enabled;
+ void initializeAutoTimeZoneDetection(boolean enabled) {
+ mAutoTimeZoneDetectionEnabled = enabled;
}
void initializeTimeZone(String zoneId) {
- mTimeZoneId.init(zoneId);
+ mTimeZoneId = zoneId;
}
- void setTimeZoneDetectionEnabled(boolean enabled) {
- mTimeZoneDetectionEnabled = enabled;
+ void setAutoTimeZoneDetectionEnabled(boolean enabled) {
+ mAutoTimeZoneDetectionEnabled = enabled;
}
void assertTimeZoneNotSet() {
- mTimeZoneId.assertHasNotBeenSet();
+ mTimeZoneChanges.assertHasNotBeenSet();
}
- void assertTimeZoneSet(String timeZoneId) {
- mTimeZoneId.assertHasBeenSet();
- mTimeZoneId.assertChangeCount(1);
- mTimeZoneId.assertLatestEquals(timeZoneId);
+ void assertTimeZoneSet(String timeZoneId, boolean withNetworkBroadcast) {
+ mTimeZoneChanges.assertHasBeenSet();
+ mTimeZoneChanges.assertChangeCount(1);
+ TimeZoneChange expectedChange = new TimeZoneChange(timeZoneId, withNetworkBroadcast);
+ mTimeZoneChanges.assertLatestEquals(expectedChange);
}
void commitAllChanges() {
- mTimeZoneId.commitLatest();
+ mTimeZoneChanges.commitLatest();
+ }
+ }
+
+ private static class TimeZoneChange {
+ private final String mTimeZoneId;
+ private final boolean mWithNetworkBroadcast;
+
+ private TimeZoneChange(String timeZoneId, boolean withNetworkBroadcast) {
+ mTimeZoneId = timeZoneId;
+ mWithNetworkBroadcast = withNetworkBroadcast;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ TimeZoneChange that = (TimeZoneChange) o;
+ return mWithNetworkBroadcast == that.mWithNetworkBroadcast
+ && mTimeZoneId.equals(that.mTimeZoneId);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mTimeZoneId, mWithNetworkBroadcast);
}
}
@@ -517,8 +580,8 @@
*/
private class Script {
- Script initializeTimeZoneDetectionEnabled(boolean enabled) {
- mFakeTimeZoneDetectorStrategyCallback.initializeTimeZoneDetectionEnabled(enabled);
+ Script initializeAutoTimeZoneDetection(boolean enabled) {
+ mFakeTimeZoneDetectorStrategyCallback.initializeAutoTimeZoneDetection(enabled);
return this;
}
@@ -527,24 +590,21 @@
return this;
}
- Script timeZoneDetectionEnabled(boolean enabled) {
- mFakeTimeZoneDetectorStrategyCallback.setTimeZoneDetectionEnabled(enabled);
- mTimeZoneDetectorStrategy.handleTimeZoneDetectionChange();
+ Script autoTimeZoneDetectionEnabled(boolean enabled) {
+ mFakeTimeZoneDetectorStrategyCallback.setAutoTimeZoneDetectionEnabled(enabled);
+ mTimeZoneDetectorStrategy.handleAutoTimeZoneDetectionChange();
return this;
}
- /** Simulates the time zone detection service receiving a phone-originated suggestion. */
+ /** Simulates the time zone detection strategy receiving a phone-originated suggestion. */
Script suggestPhoneTimeZone(PhoneTimeZoneSuggestion phoneTimeZoneSuggestion) {
mTimeZoneDetectorStrategy.suggestPhoneTimeZone(phoneTimeZoneSuggestion);
return this;
}
- /** Simulates the user manually setting the time zone. */
- Script manuallySetTimeZone(String timeZoneId) {
- // Assert the test code is correct to call this method.
- assertFalse(mFakeTimeZoneDetectorStrategyCallback.isTimeZoneDetectionEnabled());
-
- mFakeTimeZoneDetectorStrategyCallback.initializeTimeZone(timeZoneId);
+ /** Simulates the time zone detection strategy receiving a user-originated suggestion. */
+ Script suggestManualTimeZone(ManualTimeZoneSuggestion manualTimeZoneSuggestion) {
+ mTimeZoneDetectorStrategy.suggestManualTimeZone(manualTimeZoneSuggestion);
return this;
}
@@ -553,8 +613,22 @@
return this;
}
- Script verifyTimeZoneSetAndReset(PhoneTimeZoneSuggestion timeZoneSuggestion) {
- mFakeTimeZoneDetectorStrategyCallback.assertTimeZoneSet(timeZoneSuggestion.getZoneId());
+ Script verifyTimeZoneSetAndReset(PhoneTimeZoneSuggestion suggestion) {
+ // Phone suggestions should cause a TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE
+ // broadcast.
+ boolean withNetworkBroadcast = true;
+ mFakeTimeZoneDetectorStrategyCallback.assertTimeZoneSet(
+ suggestion.getZoneId(), withNetworkBroadcast);
+ mFakeTimeZoneDetectorStrategyCallback.commitAllChanges();
+ return this;
+ }
+
+ Script verifyTimeZoneSetAndReset(ManualTimeZoneSuggestion suggestion) {
+ // Manual suggestions should not cause a TelephonyIntents.ACTION_NETWORK_SET_TIMEZONE
+ // broadcast.
+ boolean withNetworkBroadcast = false;
+ mFakeTimeZoneDetectorStrategyCallback.assertTimeZoneSet(
+ suggestion.getZoneId(), withNetworkBroadcast);
mFakeTimeZoneDetectorStrategyCallback.commitAllChanges();
return this;
}
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 3ecf8d7..a0739c4 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -1512,7 +1512,6 @@
*/
@SystemApi
@TestApi
- //@RequiresPermission(android.Manifest.permission.BACKGROUND_CALL_AUDIO)
public void enterBackgroundAudioProcessing() {
if (mState != STATE_ACTIVE && mState != STATE_RINGING) {
throw new IllegalStateException("Call must be active or ringing");
@@ -1534,7 +1533,6 @@
*/
@SystemApi
@TestApi
- //@RequiresPermission(android.Manifest.permission.BACKGROUND_CALL_AUDIO)
public void exitBackgroundAudioProcessing(boolean shouldRing) {
if (mState != STATE_AUDIO_PROCESSING) {
throw new IllegalStateException("Call must in the audio processing state");
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index b91787c..f8722f4 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -144,7 +144,7 @@
private final boolean mShouldSilenceCall;
private final boolean mShouldSkipCallLog;
private final boolean mShouldSkipNotification;
- private final boolean mShouldScreenCallFurther;
+ private final boolean mShouldScreenCallViaAudioProcessing;
private CallResponse(
boolean shouldDisallowCall,
@@ -152,13 +152,13 @@
boolean shouldSilenceCall,
boolean shouldSkipCallLog,
boolean shouldSkipNotification,
- boolean shouldScreenCallFurther) {
+ boolean shouldScreenCallViaAudioProcessing) {
if (!shouldDisallowCall
&& (shouldRejectCall || shouldSkipCallLog || shouldSkipNotification)) {
throw new IllegalStateException("Invalid response state for allowed call.");
}
- if (shouldDisallowCall && shouldScreenCallFurther) {
+ if (shouldDisallowCall && shouldScreenCallViaAudioProcessing) {
throw new IllegalStateException("Invalid response state for allowed call.");
}
@@ -167,7 +167,7 @@
mShouldSkipCallLog = shouldSkipCallLog;
mShouldSkipNotification = shouldSkipNotification;
mShouldSilenceCall = shouldSilenceCall;
- mShouldScreenCallFurther = shouldScreenCallFurther;
+ mShouldScreenCallViaAudioProcessing = shouldScreenCallViaAudioProcessing;
}
/*
@@ -211,8 +211,8 @@
* for further screening of the call.
* @hide
*/
- public boolean getShouldScreenCallFurther() {
- return mShouldScreenCallFurther;
+ public boolean getShouldScreenCallViaAudioProcessing() {
+ return mShouldScreenCallViaAudioProcessing;
}
public static class Builder {
@@ -221,7 +221,7 @@
private boolean mShouldSilenceCall;
private boolean mShouldSkipCallLog;
private boolean mShouldSkipNotification;
- private boolean mShouldScreenCallFurther;
+ private boolean mShouldScreenCallViaAudioProcessing;
/**
* Sets whether the incoming call should be blocked.
@@ -285,13 +285,14 @@
* This request will only be honored if the {@link CallScreeningService} shares the same
* uid as the default dialer app. Otherwise, the call will go through as usual.
*
- * @param shouldScreenCallFurther Whether to request further call screening.
+ * @param shouldScreenCallViaAudioProcessing Whether to request further call screening.
* @hide
*/
@SystemApi
@TestApi
- public Builder setShouldScreenCallFurther(boolean shouldScreenCallFurther) {
- mShouldScreenCallFurther = shouldScreenCallFurther;
+ public @NonNull Builder setShouldScreenCallViaAudioProcessing(
+ boolean shouldScreenCallViaAudioProcessing) {
+ mShouldScreenCallViaAudioProcessing = shouldScreenCallViaAudioProcessing;
return this;
}
@@ -302,7 +303,7 @@
mShouldSilenceCall,
mShouldSkipCallLog,
mShouldSkipNotification,
- mShouldScreenCallFurther);
+ mShouldScreenCallViaAudioProcessing);
}
}
}
@@ -380,7 +381,7 @@
new ComponentName(getPackageName(), getClass().getName()));
} else if (response.getSilenceCall()) {
mCallScreeningAdapter.silenceCall(callDetails.getTelecomCallId());
- } else if (response.getShouldScreenCallFurther()) {
+ } else if (response.getShouldScreenCallViaAudioProcessing()) {
mCallScreeningAdapter.screenCallFurther(callDetails.getTelecomCallId());
} else {
mCallScreeningAdapter.allowCall(callDetails.getTelecomCallId());
diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java
index 0320f75..bb28df2 100644
--- a/telephony/java/android/telephony/AccessNetworkConstants.java
+++ b/telephony/java/android/telephony/AccessNetworkConstants.java
@@ -261,16 +261,22 @@
public static final int BAND_7 = 7;
public static final int BAND_8 = 8;
public static final int BAND_12 = 12;
+ public static final int BAND_14 = 14;
+ public static final int BAND_18 = 18;
public static final int BAND_20 = 20;
public static final int BAND_25 = 25;
public static final int BAND_28 = 28;
+ public static final int BAND_29 = 29;
+ public static final int BAND_30 = 30;
public static final int BAND_34 = 34;
public static final int BAND_38 = 38;
public static final int BAND_39 = 39;
public static final int BAND_40 = 40;
public static final int BAND_41 = 41;
+ public static final int BAND_48 = 48;
public static final int BAND_50 = 50;
public static final int BAND_51 = 51;
+ public static final int BAND_65 = 65;
public static final int BAND_66 = 66;
public static final int BAND_70 = 70;
public static final int BAND_71 = 71;
@@ -286,6 +292,7 @@
public static final int BAND_83 = 83;
public static final int BAND_84 = 84;
public static final int BAND_86 = 86;
+ public static final int BAND_90 = 90;
/** FR2 bands */
public static final int BAND_257 = 257;
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index 663b09a..f4b2cef 100644
--- a/telephony/java/android/telephony/ims/ImsReasonInfo.java
+++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java
@@ -18,9 +18,10 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
+import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
@@ -28,12 +29,13 @@
import java.lang.annotation.RetentionPolicy;
/**
- * This class enables an application to get details on why a method call failed.
- *
- * @hide
+ * Provides details on why an IMS call failed. Applications can use the methods in this class to
+ * get local or network fault behind an IMS services failure. For example, if the code is
+ * CODE_CALL_BARRED, then the call was blocked by network call barring configuration and it is not
+ * the device's bug and the user can retry the call when network lift the barring.
+ * Typical use case includes call backs when IMS call state changed with this class as a param
+ * containing details on why IMS call changed state/failed.
*/
-@SystemApi
-@TestApi
public final class ImsReasonInfo implements Parcelable {
/**
@@ -1096,9 +1098,11 @@
/**
* Network string error messages.
* mExtraMessage may have these values.
+ * @hide
*/
- public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED
- = "Forbidden. Not Authorized for Service";
+ @SystemApi
+ public static final String EXTRA_MSG_SERVICE_NOT_AUTHORIZED =
+ "Forbidden. Not Authorized for Service";
/*
@@ -1106,21 +1110,21 @@
* This value can be referred when the code is CODE_LOCAL_CALL_CS_RETRY_REQUIRED.
*/
/**
- * An extra that may be populated when the {@link CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has
+ * An extra that may be populated when the {@link #CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has
* been returned.
* <p>
* Try to connect the call using CS
*/
public static final int EXTRA_CODE_CALL_RETRY_NORMAL = 1;
/**
- * An extra that may be populated when the {@link CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has
+ * An extra that may be populated when the {@link #CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has
* been returned.
* <p>
* Try to connect the call using CS and do not notify the user.
*/
public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2;
/**
- * An extra that may be populated when the {@link CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has
+ * An extra that may be populated when the {@link #CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has
* been returned.
* <p>
* Try to connect the call using CS by using the settings.
@@ -1130,15 +1134,18 @@
// For main reason code
/** @hide */
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
+ + "#getCode()}")
public int mCode;
// For the extra code value; it depends on the code value.
/** @hide */
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
+ + "#getExtraCode()}")
public int mExtraCode;
// For the additional message of the reason info.
/** @hide */
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
+ + "#getExtraMessage()}")
public String mExtraMessage;
/** @hide */
@@ -1162,7 +1169,7 @@
mExtraMessage = null;
}
- public ImsReasonInfo(int code, int extraCode, String extraMessage) {
+ public ImsReasonInfo(@ImsCode int code, int extraCode, @Nullable String extraMessage) {
mCode = code;
mExtraCode = extraCode;
mExtraMessage = extraMessage;
@@ -1186,7 +1193,7 @@
* @return an optional OEM specified string that provides extra information about the operation
* result.
*/
- public String getExtraMessage() {
+ public @Nullable String getExtraMessage() {
return mExtraMessage;
}
@@ -1205,13 +1212,13 @@
}
@Override
- public void writeToParcel(Parcel out, int flags) {
+ public void writeToParcel(@NonNull Parcel out, int flags) {
out.writeInt(mCode);
out.writeInt(mExtraCode);
out.writeString(mExtraMessage);
}
- public static final @android.annotation.NonNull Creator<ImsReasonInfo> CREATOR = new Creator<ImsReasonInfo>() {
+ public static final @NonNull Creator<ImsReasonInfo> CREATOR = new Creator<ImsReasonInfo>() {
@Override
public ImsReasonInfo createFromParcel(Parcel in) {
return new ImsReasonInfo(in);