Merge "WiFi: Basic support for 11be"
diff --git a/Android.bp b/Android.bp
index 8d82b38..8bc5d7a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -77,7 +77,6 @@
// Java/AIDL sources under frameworks/base
":framework-annotations",
":framework-blobstore-sources",
- ":framework-bluetooth-sources", // TODO(b/214988855) : Remove once framework-bluetooth jar is ready
":framework-connectivity-tiramisu-sources",
":framework-core-sources",
":framework-drm-sources",
@@ -297,6 +296,7 @@
defaults: ["framework-aidl-export-defaults"],
srcs: [
":framework-non-updatable-sources",
+ ":framework-bluetooth-sources", // TODO(b/214988855) : Remove once framework-bluetooth jar is ready
"core/java/**/*.logtags",
":apex-info-list",
],
@@ -602,6 +602,7 @@
libs: [
"art.module.public.api",
"sdk_module-lib_current_framework-tethering",
+ "sdk_public_current_framework-bluetooth",
// There are a few classes from modules used by the core that
// need to be resolved by metalava. We use a prebuilt stub of the
// full sdk to ensure we can resolve them. If a new class gets added,
diff --git a/ApiDocs.bp b/ApiDocs.bp
index 3d6b52f..c50d446 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -102,6 +102,7 @@
":framework-appsearch-sources",
":framework-connectivity-sources",
+ ":framework-bluetooth-sources",
":framework-connectivity-tiramisu-updatable-sources",
":framework-graphics-srcs",
":framework-mediaprovider-sources",
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 8a15758..a0a426e 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -215,52 +215,6 @@
// from stub sources
/////////////////////////////////////////////////////////////////////
-modules_public_stubs = [
- "android.net.ipsec.ike.stubs",
- "art.module.public.api.stubs",
- "conscrypt.module.public.api.stubs",
- "framework-appsearch.stubs",
- "framework-connectivity.stubs",
- "framework-connectivity-tiramisu.stubs",
- "framework-graphics.stubs",
- "framework-media.stubs",
- "framework-mediaprovider.stubs",
- "framework-nearby.stubs",
- "framework-permission.stubs",
- "framework-permission-s.stubs",
- "framework-scheduling.stubs",
- "framework-sdkextensions.stubs",
- "framework-statsd.stubs",
- "framework-supplementalprocess.stubs",
- "framework-tethering.stubs",
- "framework-uwb.stubs",
- "framework-wifi.stubs",
- "i18n.module.public.api.stubs",
-]
-
-modules_system_stubs = [
- "android.net.ipsec.ike.stubs.system",
- "art.module.public.api.stubs.system",
- "conscrypt.module.public.api.stubs", // Only has public stubs
- "framework-appsearch.stubs.system",
- "framework-connectivity.stubs.system",
- "framework-connectivity-tiramisu.stubs.system",
- "framework-graphics.stubs.system",
- "framework-media.stubs.system",
- "framework-mediaprovider.stubs.system",
- "framework-nearby.stubs.system",
- "framework-permission.stubs.system",
- "framework-permission-s.stubs.system",
- "framework-scheduling.stubs.system",
- "framework-sdkextensions.stubs.system",
- "framework-statsd.stubs.system",
- "framework-supplementalprocess.stubs",
- "framework-tethering.stubs.system",
- "framework-uwb.stubs.system",
- "framework-wifi.stubs.system",
- "i18n.module.public.api.stubs", // Only has public stubs
-]
-
java_defaults {
name: "android-non-updatable_defaults_stubs_current",
libs: ["stub-annotations"],
@@ -282,14 +236,7 @@
name: "android-non-updatable.stubs",
defaults: ["android-non-updatable_defaults_stubs_current"],
srcs: [":api-stubs-docs-non-updatable"],
- libs: modules_public_stubs,
- soong_config_variables: {
- include_nonpublic_framework_api: {
- libs: [
- "framework-supplementalapi.stubs",
- ],
- },
- },
+ libs: ["all-modules-public-stubs"],
dist: {
dir: "apistubs/android/public",
},
@@ -299,14 +246,7 @@
name: "android-non-updatable.stubs.system",
defaults: ["android-non-updatable_defaults_stubs_current"],
srcs: [":system-api-stubs-docs-non-updatable"],
- libs: modules_system_stubs,
- soong_config_variables: {
- include_nonpublic_framework_api: {
- libs: [
- "framework-supplementalapi.stubs",
- ],
- },
- },
+ libs: ["all-modules-system-stubs"],
dist: {
dir: "apistubs/android/system",
},
@@ -318,6 +258,8 @@
srcs: [":module-lib-api-stubs-docs-non-updatable"],
libs: [
"sdk_module-lib_current_framework-tethering",
+ "sdk_public_current_framework-bluetooth",
+ // NOTE: The below can be removed once the prebuilt stub contains bluetooth.
"sdk_system_current_android",
// NOTE: The below can be removed once the prebuilt stub contains IKE.
"sdk_system_current_android.net.ipsec.ike",
@@ -331,14 +273,7 @@
name: "android-non-updatable.stubs.test",
defaults: ["android-non-updatable_defaults_stubs_current"],
srcs: [":test-api-stubs-docs-non-updatable"],
- libs: modules_system_stubs,
- soong_config_variables: {
- include_nonpublic_framework_api: {
- libs: [
- "framework-supplementalapi.stubs",
- ],
- },
- },
+ libs: ["all-modules-system-stubs"],
dist: {
dir: "apistubs/android/test",
},
@@ -356,33 +291,21 @@
java_library_with_nonpublic_deps {
name: "android_stubs_current",
- static_libs: modules_public_stubs + [
+ static_libs: [
+ "all-modules-public-stubs",
"android-non-updatable.stubs",
"private-stub-annotations-jar",
],
- soong_config_variables: {
- include_nonpublic_framework_api: {
- static_libs: [
- "framework-supplementalapi.stubs",
- ],
- },
- },
defaults: ["android.jar_defaults"],
}
java_library_with_nonpublic_deps {
name: "android_system_stubs_current",
- static_libs: modules_system_stubs + [
+ static_libs: [
+ "all-modules-system-stubs",
"android-non-updatable.stubs.system",
"private-stub-annotations-jar",
],
- soong_config_variables: {
- include_nonpublic_framework_api: {
- static_libs: [
- "framework-supplementalapi.stubs",
- ],
- },
- },
defaults: [
"android.jar_defaults",
"android_stubs_dists_default",
@@ -404,17 +327,11 @@
name: "android_test_stubs_current",
// Modules do not have test APIs, but we want to include their SystemApis, like we include
// the SystemApi of framework-non-updatable-sources.
- static_libs: modules_system_stubs + [
+ static_libs: [
+ "all-modules-system-stubs",
"android-non-updatable.stubs.test",
"private-stub-annotations-jar",
],
- soong_config_variables: {
- include_nonpublic_framework_api: {
- static_libs: [
- "framework-supplementalapi.stubs",
- ],
- },
- },
defaults: [
"android.jar_defaults",
"android_stubs_dists_default",
diff --git a/api/Android.bp b/api/Android.bp
index a22c2f6..d8727f9 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -110,6 +110,7 @@
"art.module.public.api",
"conscrypt.module.public.api",
"framework-appsearch",
+ "framework-bluetooth",
"framework-connectivity",
"framework-connectivity-tiramisu",
"framework-graphics",
diff --git a/api/api.go b/api/api.go
index 4b6ebc1..aa9e399e 100644
--- a/api/api.go
+++ b/api/api.go
@@ -27,6 +27,7 @@
const art = "art.module.public.api"
const conscrypt = "conscrypt.module.public.api"
const i18n = "i18n.module.public.api"
+var modules_with_only_public_scope = []string{i18n, conscrypt}
// The intention behind this soong plugin is to generate a number of "merged"
// API-related modules that would otherwise require a large amount of very
@@ -183,6 +184,27 @@
ctx.CreateModule(genrule.GenRuleFactory, &props)
}
+func createMergedPublicStubs(ctx android.LoadHookContext, modules []string) {
+ props := libraryProps{}
+ props.Name = proptools.StringPtr("all-modules-public-stubs")
+ props.Static_libs = transformArray(modules, "", ".stubs")
+ props.Sdk_version = proptools.StringPtr("module_current")
+ props.Visibility = []string{"//frameworks/base"}
+ ctx.CreateModule(java.LibraryFactory, &props)
+}
+
+func createMergedSystemStubs(ctx android.LoadHookContext, modules []string) {
+ props := libraryProps{}
+ modules_with_system_stubs := removeAll(modules, modules_with_only_public_scope)
+ props.Name = proptools.StringPtr("all-modules-system-stubs")
+ props.Static_libs = append(
+ transformArray(modules_with_only_public_scope, "", ".stubs"),
+ transformArray(modules_with_system_stubs, "", ".stubs.system")...)
+ props.Sdk_version = proptools.StringPtr("module_current")
+ props.Visibility = []string{"//frameworks/base"}
+ ctx.CreateModule(java.LibraryFactory, &props)
+}
+
func createMergedModuleLibStubs(ctx android.LoadHookContext, modules []string) {
// The user of this module compiles against the "core" SDK, so remove core libraries to avoid dupes.
modules = removeAll(modules, []string{art, conscrypt, i18n})
@@ -205,7 +227,7 @@
func createMergedTxts(ctx android.LoadHookContext, bootclasspath, system_server_classpath []string) {
var textFiles []MergedTxtDefinition
// Two module libraries currently do not support @SystemApi so only have the public scope.
- bcpWithSystemApi := removeAll(bootclasspath, []string{conscrypt, i18n})
+ bcpWithSystemApi := removeAll(bootclasspath, modules_with_only_public_scope)
tagSuffix := []string{".api.txt}", ".removed-api.txt}"}
for i, f := range []string{"current.txt", "removed.txt"} {
@@ -253,6 +275,8 @@
createMergedStubsSrcjar(ctx, bootclasspath)
+ createMergedPublicStubs(ctx, bootclasspath)
+ createMergedSystemStubs(ctx, bootclasspath)
createMergedModuleLibStubs(ctx, bootclasspath)
createMergedAnnotations(ctx, bootclasspath)
diff --git a/core/api/current.txt b/core/api/current.txt
index cb2ede8..0316875 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -8874,1365 +8874,6 @@
}
-package android.bluetooth {
-
- public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile {
- method public void finalize();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isA2dpPlaying(android.bluetooth.BluetoothDevice);
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_PLAYING_STATE_CHANGED = "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED";
- field public static final int STATE_NOT_PLAYING = 11; // 0xb
- field public static final int STATE_PLAYING = 10; // 0xa
- }
-
- public final class BluetoothAdapter {
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean cancelDiscovery();
- method public static boolean checkBluetoothAddress(String);
- method public void closeProfileProxy(int, android.bluetooth.BluetoothProfile);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disable();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean enable();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, "android.permission.LOCAL_MAC_ADDRESS"}) public String getAddress();
- method public android.bluetooth.le.BluetoothLeAdvertiser getBluetoothLeAdvertiser();
- method public android.bluetooth.le.BluetoothLeScanner getBluetoothLeScanner();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.Set<android.bluetooth.BluetoothDevice> getBondedDevices();
- method @Deprecated public static android.bluetooth.BluetoothAdapter getDefaultAdapter();
- method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public java.time.Duration getDiscoverableTimeout();
- method public int getLeMaximumAdvertisingDataLength();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getMaxConnectedAudioDevices();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public String getName();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getProfileConnectionState(int);
- method public boolean getProfileProxy(android.content.Context, android.bluetooth.BluetoothProfile.ServiceListener, int);
- method public android.bluetooth.BluetoothDevice getRemoteDevice(String);
- method public android.bluetooth.BluetoothDevice getRemoteDevice(byte[]);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public int getScanMode();
- method public int getState();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean isDiscovering();
- method public boolean isEnabled();
- method public boolean isLe2MPhySupported();
- method public int isLeAudioBroadcastAssistantSupported();
- method public int isLeAudioBroadcastSourceSupported();
- method public int isLeAudioSupported();
- method public boolean isLeCodedPhySupported();
- method public boolean isLeExtendedAdvertisingSupported();
- method public boolean isLePeriodicAdvertisingSupported();
- method public boolean isMultipleAdvertisementSupported();
- method public boolean isOffloadedFilteringSupported();
- method public boolean isOffloadedScanBatchingSupported();
- method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothServerSocket listenUsingInsecureL2capChannel() throws java.io.IOException;
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(String, java.util.UUID) throws java.io.IOException;
- method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothServerSocket listenUsingL2capChannel() throws java.io.IOException;
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothServerSocket listenUsingRfcommWithServiceRecord(String, java.util.UUID) throws java.io.IOException;
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean setName(String);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean startDiscovery();
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean startLeScan(android.bluetooth.BluetoothAdapter.LeScanCallback);
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean startLeScan(java.util.UUID[], android.bluetooth.BluetoothAdapter.LeScanCallback);
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void stopLeScan(android.bluetooth.BluetoothAdapter.LeScanCallback);
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public static final String ACTION_DISCOVERY_FINISHED = "android.bluetooth.adapter.action.DISCOVERY_FINISHED";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public static final String ACTION_DISCOVERY_STARTED = "android.bluetooth.adapter.action.DISCOVERY_STARTED";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_LOCAL_NAME_CHANGED = "android.bluetooth.adapter.action.LOCAL_NAME_CHANGED";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public static final String ACTION_REQUEST_DISCOVERABLE = "android.bluetooth.adapter.action.REQUEST_DISCOVERABLE";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_REQUEST_ENABLE = "android.bluetooth.adapter.action.REQUEST_ENABLE";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public static final String ACTION_SCAN_MODE_CHANGED = "android.bluetooth.adapter.action.SCAN_MODE_CHANGED";
- field public static final String ACTION_STATE_CHANGED = "android.bluetooth.adapter.action.STATE_CHANGED";
- field public static final int ERROR = -2147483648; // 0x80000000
- field public static final String EXTRA_CONNECTION_STATE = "android.bluetooth.adapter.extra.CONNECTION_STATE";
- field public static final String EXTRA_DISCOVERABLE_DURATION = "android.bluetooth.adapter.extra.DISCOVERABLE_DURATION";
- field public static final String EXTRA_LOCAL_NAME = "android.bluetooth.adapter.extra.LOCAL_NAME";
- field public static final String EXTRA_PREVIOUS_CONNECTION_STATE = "android.bluetooth.adapter.extra.PREVIOUS_CONNECTION_STATE";
- field public static final String EXTRA_PREVIOUS_SCAN_MODE = "android.bluetooth.adapter.extra.PREVIOUS_SCAN_MODE";
- field public static final String EXTRA_PREVIOUS_STATE = "android.bluetooth.adapter.extra.PREVIOUS_STATE";
- field public static final String EXTRA_SCAN_MODE = "android.bluetooth.adapter.extra.SCAN_MODE";
- field public static final String EXTRA_STATE = "android.bluetooth.adapter.extra.STATE";
- field public static final int SCAN_MODE_CONNECTABLE = 21; // 0x15
- field public static final int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 23; // 0x17
- field public static final int SCAN_MODE_NONE = 20; // 0x14
- field public static final int STATE_CONNECTED = 2; // 0x2
- field public static final int STATE_CONNECTING = 1; // 0x1
- field public static final int STATE_DISCONNECTED = 0; // 0x0
- field public static final int STATE_DISCONNECTING = 3; // 0x3
- field public static final int STATE_OFF = 10; // 0xa
- field public static final int STATE_ON = 12; // 0xc
- field public static final int STATE_TURNING_OFF = 13; // 0xd
- field public static final int STATE_TURNING_ON = 11; // 0xb
- }
-
- public static interface BluetoothAdapter.LeScanCallback {
- method public void onLeScan(android.bluetooth.BluetoothDevice, int, byte[]);
- }
-
- public class BluetoothAssignedNumbers {
- field public static final int AAMP_OF_AMERICA = 190; // 0xbe
- field public static final int ACCEL_SEMICONDUCTOR = 74; // 0x4a
- field public static final int ACE_SENSOR = 188; // 0xbc
- field public static final int ADIDAS = 195; // 0xc3
- field public static final int ADVANCED_PANMOBIL_SYSTEMS = 145; // 0x91
- field public static final int AIROHA_TECHNOLOGY = 148; // 0x94
- field public static final int ALCATEL = 36; // 0x24
- field public static final int ALPWISE = 154; // 0x9a
- field public static final int AMICCOM_ELECTRONICS = 192; // 0xc0
- field public static final int APLIX = 189; // 0xbd
- field public static final int APPLE = 76; // 0x4c
- field public static final int APT_LICENSING = 79; // 0x4f
- field public static final int ARCHOS = 207; // 0xcf
- field public static final int ARP_DEVICES = 168; // 0xa8
- field public static final int ATHEROS_COMMUNICATIONS = 69; // 0x45
- field public static final int ATMEL = 19; // 0x13
- field public static final int AUSTCO_COMMUNICATION_SYSTEMS = 213; // 0xd5
- field public static final int AUTONET_MOBILE = 127; // 0x7f
- field public static final int AVAGO = 78; // 0x4e
- field public static final int AVM_BERLIN = 31; // 0x1f
- field public static final int A_AND_D_ENGINEERING = 105; // 0x69
- field public static final int A_AND_R_CAMBRIDGE = 124; // 0x7c
- field public static final int BANDSPEED = 32; // 0x20
- field public static final int BAND_XI_INTERNATIONAL = 100; // 0x64
- field public static final int BDE_TECHNOLOGY = 180; // 0xb4
- field public static final int BEATS_ELECTRONICS = 204; // 0xcc
- field public static final int BEAUTIFUL_ENTERPRISE = 108; // 0x6c
- field public static final int BEKEY = 178; // 0xb2
- field public static final int BELKIN_INTERNATIONAL = 92; // 0x5c
- field public static final int BINAURIC = 203; // 0xcb
- field public static final int BIOSENTRONICS = 219; // 0xdb
- field public static final int BLUEGIGA = 71; // 0x47
- field public static final int BLUERADIOS = 133; // 0x85
- field public static final int BLUETOOTH_SIG = 63; // 0x3f
- field public static final int BLUETREK_TECHNOLOGIES = 151; // 0x97
- field public static final int BOSE = 158; // 0x9e
- field public static final int BRIARTEK = 109; // 0x6d
- field public static final int BROADCOM = 15; // 0xf
- field public static final int CAEN_RFID = 170; // 0xaa
- field public static final int CAMBRIDGE_SILICON_RADIO = 10; // 0xa
- field public static final int CATC = 52; // 0x34
- field public static final int CINETIX = 175; // 0xaf
- field public static final int CLARINOX_TECHNOLOGIES = 179; // 0xb3
- field public static final int COLORFY = 156; // 0x9c
- field public static final int COMMIL = 51; // 0x33
- field public static final int CONEXANT_SYSTEMS = 28; // 0x1c
- field public static final int CONNECTBLUE = 113; // 0x71
- field public static final int CONTINENTAL_AUTOMOTIVE = 75; // 0x4b
- field public static final int CONWISE_TECHNOLOGY = 66; // 0x42
- field public static final int CREATIVE_TECHNOLOGY = 118; // 0x76
- field public static final int C_TECHNOLOGIES = 38; // 0x26
- field public static final int DANLERS = 225; // 0xe1
- field public static final int DELORME_PUBLISHING_COMPANY = 128; // 0x80
- field public static final int DEXCOM = 208; // 0xd0
- field public static final int DIALOG_SEMICONDUCTOR = 210; // 0xd2
- field public static final int DIGIANSWER = 12; // 0xc
- field public static final int ECLIPSE = 53; // 0x35
- field public static final int ECOTEST = 136; // 0x88
- field public static final int ELGATO_SYSTEMS = 206; // 0xce
- field public static final int EM_MICROELECTRONIC_MARIN = 90; // 0x5a
- field public static final int EQUINOX_AG = 134; // 0x86
- field public static final int ERICSSON_TECHNOLOGY = 0; // 0x0
- field public static final int EVLUMA = 201; // 0xc9
- field public static final int FREE2MOVE = 83; // 0x53
- field public static final int FUNAI_ELECTRIC = 144; // 0x90
- field public static final int GARMIN_INTERNATIONAL = 135; // 0x87
- field public static final int GCT_SEMICONDUCTOR = 45; // 0x2d
- field public static final int GELO = 200; // 0xc8
- field public static final int GENEQ = 194; // 0xc2
- field public static final int GENERAL_MOTORS = 104; // 0x68
- field public static final int GENNUM = 59; // 0x3b
- field public static final int GEOFORCE = 157; // 0x9d
- field public static final int GIBSON_GUITARS = 98; // 0x62
- field public static final int GN_NETCOM = 103; // 0x67
- field public static final int GN_RESOUND = 137; // 0x89
- field public static final int GOOGLE = 224; // 0xe0
- field public static final int GREEN_THROTTLE_GAMES = 172; // 0xac
- field public static final int GROUP_SENSE = 115; // 0x73
- field public static final int HANLYNN_TECHNOLOGIES = 123; // 0x7b
- field public static final int HARMAN_INTERNATIONAL = 87; // 0x57
- field public static final int HEWLETT_PACKARD = 101; // 0x65
- field public static final int HITACHI = 41; // 0x29
- field public static final int HOSIDEN = 221; // 0xdd
- field public static final int IBM = 3; // 0x3
- field public static final int INFINEON_TECHNOLOGIES = 9; // 0x9
- field public static final int INGENIEUR_SYSTEMGRUPPE_ZAHN = 171; // 0xab
- field public static final int INTEGRATED_SILICON_SOLUTION = 65; // 0x41
- field public static final int INTEGRATED_SYSTEM_SOLUTION = 57; // 0x39
- field public static final int INTEL = 2; // 0x2
- field public static final int INVENTEL = 30; // 0x1e
- field public static final int IPEXTREME = 61; // 0x3d
- field public static final int I_TECH_DYNAMIC_GLOBAL_DISTRIBUTION = 153; // 0x99
- field public static final int JAWBONE = 138; // 0x8a
- field public static final int JIANGSU_TOPPOWER_AUTOMOTIVE_ELECTRONICS = 155; // 0x9b
- field public static final int JOHNSON_CONTROLS = 185; // 0xb9
- field public static final int J_AND_M = 82; // 0x52
- field public static final int KAWANTECH = 212; // 0xd4
- field public static final int KC_TECHNOLOGY = 22; // 0x16
- field public static final int KENSINGTON_COMPUTER_PRODUCTS_GROUP = 160; // 0xa0
- field public static final int LAIRD_TECHNOLOGIES = 119; // 0x77
- field public static final int LESSWIRE = 121; // 0x79
- field public static final int LG_ELECTRONICS = 196; // 0xc4
- field public static final int LINAK = 164; // 0xa4
- field public static final int LUCENT = 7; // 0x7
- field public static final int LUDUS_HELSINKI = 132; // 0x84
- field public static final int MACRONIX = 44; // 0x2c
- field public static final int MAGNETI_MARELLI = 169; // 0xa9
- field public static final int MANSELLA = 33; // 0x21
- field public static final int MARVELL = 72; // 0x48
- field public static final int MATSUSHITA_ELECTRIC = 58; // 0x3a
- field public static final int MC10 = 202; // 0xca
- field public static final int MEDIATEK = 70; // 0x46
- field public static final int MESO_INTERNATIONAL = 182; // 0xb6
- field public static final int META_WATCH = 163; // 0xa3
- field public static final int MEWTEL_TECHNOLOGY = 47; // 0x2f
- field public static final int MICOMMAND = 99; // 0x63
- field public static final int MICROCHIP_TECHNOLOGY = 205; // 0xcd
- field public static final int MICROSOFT = 6; // 0x6
- field public static final int MINDTREE = 106; // 0x6a
- field public static final int MISFIT_WEARABLES = 223; // 0xdf
- field public static final int MITEL_SEMICONDUCTOR = 16; // 0x10
- field public static final int MITSUBISHI_ELECTRIC = 20; // 0x14
- field public static final int MOBILIAN_CORPORATION = 55; // 0x37
- field public static final int MONSTER = 112; // 0x70
- field public static final int MOTOROLA = 8; // 0x8
- field public static final int MSTAR_SEMICONDUCTOR = 122; // 0x7a
- field public static final int MUZIK = 222; // 0xde
- field public static final int NEC = 34; // 0x22
- field public static final int NEC_LIGHTING = 149; // 0x95
- field public static final int NEWLOGIC = 23; // 0x17
- field public static final int NIKE = 120; // 0x78
- field public static final int NINE_SOLUTIONS = 102; // 0x66
- field public static final int NOKIA_MOBILE_PHONES = 1; // 0x1
- field public static final int NORDIC_SEMICONDUCTOR = 89; // 0x59
- field public static final int NORWOOD_SYSTEMS = 46; // 0x2e
- field public static final int ODM_TECHNOLOGY = 150; // 0x96
- field public static final int OMEGAWAVE = 174; // 0xae
- field public static final int ONSET_COMPUTER = 197; // 0xc5
- field public static final int OPEN_INTERFACE = 39; // 0x27
- field public static final int OTL_DYNAMICS = 165; // 0xa5
- field public static final int PANDA_OCEAN = 166; // 0xa6
- field public static final int PARROT = 67; // 0x43
- field public static final int PARTHUS_TECHNOLOGIES = 14; // 0xe
- field public static final int PASSIF_SEMICONDUCTOR = 176; // 0xb0
- field public static final int PETER_SYSTEMTECHNIK = 173; // 0xad
- field public static final int PHILIPS_SEMICONDUCTORS = 37; // 0x25
- field public static final int PLANTRONICS = 85; // 0x55
- field public static final int POLAR_ELECTRO = 107; // 0x6b
- field public static final int POLAR_ELECTRO_EUROPE = 209; // 0xd1
- field public static final int PROCTER_AND_GAMBLE = 220; // 0xdc
- field public static final int QUALCOMM = 29; // 0x1d
- field public static final int QUALCOMM_CONNECTED_EXPERIENCES = 216; // 0xd8
- field public static final int QUALCOMM_INNOVATION_CENTER = 184; // 0xb8
- field public static final int QUALCOMM_LABS = 140; // 0x8c
- field public static final int QUALCOMM_TECHNOLOGIES = 215; // 0xd7
- field public static final int QUINTIC = 142; // 0x8e
- field public static final int QUUPPA = 199; // 0xc7
- field public static final int RALINK_TECHNOLOGY = 91; // 0x5b
- field public static final int RDA_MICROELECTRONICS = 97; // 0x61
- field public static final int REALTEK_SEMICONDUCTOR = 93; // 0x5d
- field public static final int RED_M = 50; // 0x32
- field public static final int RENESAS_TECHNOLOGY = 54; // 0x36
- field public static final int RESEARCH_IN_MOTION = 60; // 0x3c
- field public static final int RF_MICRO_DEVICES = 40; // 0x28
- field public static final int RIVIERAWAVES = 96; // 0x60
- field public static final int ROHDE_AND_SCHWARZ = 25; // 0x19
- field public static final int RTX_TELECOM = 21; // 0x15
- field public static final int SAMSUNG_ELECTRONICS = 117; // 0x75
- field public static final int SARIS_CYCLING_GROUP = 177; // 0xb1
- field public static final int SEERS_TECHNOLOGY = 125; // 0x7d
- field public static final int SEIKO_EPSON = 64; // 0x40
- field public static final int SELFLY = 198; // 0xc6
- field public static final int SEMILINK = 226; // 0xe2
- field public static final int SENNHEISER_COMMUNICATIONS = 130; // 0x82
- field public static final int SHANGHAI_SUPER_SMART_ELECTRONICS = 114; // 0x72
- field public static final int SHENZHEN_EXCELSECU_DATA_TECHNOLOGY = 193; // 0xc1
- field public static final int SIGNIA_TECHNOLOGIES = 27; // 0x1b
- field public static final int SILICON_WAVE = 11; // 0xb
- field public static final int SIRF_TECHNOLOGY = 80; // 0x50
- field public static final int SOCKET_MOBILE = 68; // 0x44
- field public static final int SONY_ERICSSON = 86; // 0x56
- field public static final int SOUND_ID = 111; // 0x6f
- field public static final int SPORTS_TRACKING_TECHNOLOGIES = 126; // 0x7e
- field public static final int SR_MEDIZINELEKTRONIK = 161; // 0xa1
- field public static final int STACCATO_COMMUNICATIONS = 77; // 0x4d
- field public static final int STALMART_TECHNOLOGY = 191; // 0xbf
- field public static final int STARKEY_LABORATORIES = 186; // 0xba
- field public static final int STOLLMAN_E_PLUS_V = 143; // 0x8f
- field public static final int STONESTREET_ONE = 94; // 0x5e
- field public static final int ST_MICROELECTRONICS = 48; // 0x30
- field public static final int SUMMIT_DATA_COMMUNICATIONS = 110; // 0x6e
- field public static final int SUUNTO = 159; // 0x9f
- field public static final int SWIRL_NETWORKS = 181; // 0xb5
- field public static final int SYMBOL_TECHNOLOGIES = 42; // 0x2a
- field public static final int SYNOPSYS = 49; // 0x31
- field public static final int SYSTEMS_AND_CHIPS = 62; // 0x3e
- field public static final int S_POWER_ELECTRONICS = 187; // 0xbb
- field public static final int TAIXINGBANG_TECHNOLOGY = 211; // 0xd3
- field public static final int TENOVIS = 43; // 0x2b
- field public static final int TERAX = 56; // 0x38
- field public static final int TEXAS_INSTRUMENTS = 13; // 0xd
- field public static final int THINKOPTICS = 146; // 0x92
- field public static final int THREECOM = 5; // 0x5
- field public static final int THREE_DIJOY = 84; // 0x54
- field public static final int THREE_DSP = 73; // 0x49
- field public static final int TIMEKEEPING_SYSTEMS = 131; // 0x83
- field public static final int TIMEX_GROUP_USA = 214; // 0xd6
- field public static final int TOPCORN_POSITIONING_SYSTEMS = 139; // 0x8b
- field public static final int TOSHIBA = 4; // 0x4
- field public static final int TRANSILICA = 24; // 0x18
- field public static final int TRELAB = 183; // 0xb7
- field public static final int TTPCOM = 26; // 0x1a
- field public static final int TXTR = 218; // 0xda
- field public static final int TZERO_TECHNOLOGIES = 81; // 0x51
- field public static final int UNIVERSAL_ELECTRONICS = 147; // 0x93
- field public static final int VERTU = 162; // 0xa2
- field public static final int VISTEON = 167; // 0xa7
- field public static final int VIZIO = 88; // 0x58
- field public static final int VOYETRA_TURTLE_BEACH = 217; // 0xd9
- field public static final int WAVEPLUS_TECHNOLOGY = 35; // 0x23
- field public static final int WICENTRIC = 95; // 0x5f
- field public static final int WIDCOMM = 17; // 0x11
- field public static final int WUXI_VIMICRO = 129; // 0x81
- field public static final int ZEEVO = 18; // 0x12
- field public static final int ZER01_TV = 152; // 0x98
- field public static final int ZOMM = 116; // 0x74
- field public static final int ZSCAN_SOFTWARE = 141; // 0x8d
- }
-
- public final class BluetoothClass implements android.os.Parcelable {
- method public int describeContents();
- method public boolean doesClassMatch(int);
- method public int getDeviceClass();
- method public int getMajorDeviceClass();
- method public boolean hasService(int);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothClass> CREATOR;
- field public static final int PROFILE_A2DP = 1; // 0x1
- field public static final int PROFILE_HEADSET = 0; // 0x0
- field public static final int PROFILE_HID = 3; // 0x3
- }
-
- public static class BluetoothClass.Device {
- ctor public BluetoothClass.Device();
- field public static final int AUDIO_VIDEO_CAMCORDER = 1076; // 0x434
- field public static final int AUDIO_VIDEO_CAR_AUDIO = 1056; // 0x420
- field public static final int AUDIO_VIDEO_HANDSFREE = 1032; // 0x408
- field public static final int AUDIO_VIDEO_HEADPHONES = 1048; // 0x418
- field public static final int AUDIO_VIDEO_HIFI_AUDIO = 1064; // 0x428
- field public static final int AUDIO_VIDEO_LOUDSPEAKER = 1044; // 0x414
- field public static final int AUDIO_VIDEO_MICROPHONE = 1040; // 0x410
- field public static final int AUDIO_VIDEO_PORTABLE_AUDIO = 1052; // 0x41c
- field public static final int AUDIO_VIDEO_SET_TOP_BOX = 1060; // 0x424
- field public static final int AUDIO_VIDEO_UNCATEGORIZED = 1024; // 0x400
- field public static final int AUDIO_VIDEO_VCR = 1068; // 0x42c
- field public static final int AUDIO_VIDEO_VIDEO_CAMERA = 1072; // 0x430
- field public static final int AUDIO_VIDEO_VIDEO_CONFERENCING = 1088; // 0x440
- field public static final int AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER = 1084; // 0x43c
- field public static final int AUDIO_VIDEO_VIDEO_GAMING_TOY = 1096; // 0x448
- field public static final int AUDIO_VIDEO_VIDEO_MONITOR = 1080; // 0x438
- field public static final int AUDIO_VIDEO_WEARABLE_HEADSET = 1028; // 0x404
- field public static final int COMPUTER_DESKTOP = 260; // 0x104
- field public static final int COMPUTER_HANDHELD_PC_PDA = 272; // 0x110
- field public static final int COMPUTER_LAPTOP = 268; // 0x10c
- field public static final int COMPUTER_PALM_SIZE_PC_PDA = 276; // 0x114
- field public static final int COMPUTER_SERVER = 264; // 0x108
- field public static final int COMPUTER_UNCATEGORIZED = 256; // 0x100
- field public static final int COMPUTER_WEARABLE = 280; // 0x118
- field public static final int HEALTH_BLOOD_PRESSURE = 2308; // 0x904
- field public static final int HEALTH_DATA_DISPLAY = 2332; // 0x91c
- field public static final int HEALTH_GLUCOSE = 2320; // 0x910
- field public static final int HEALTH_PULSE_OXIMETER = 2324; // 0x914
- field public static final int HEALTH_PULSE_RATE = 2328; // 0x918
- field public static final int HEALTH_THERMOMETER = 2312; // 0x908
- field public static final int HEALTH_UNCATEGORIZED = 2304; // 0x900
- field public static final int HEALTH_WEIGHING = 2316; // 0x90c
- field public static final int PHONE_CELLULAR = 516; // 0x204
- field public static final int PHONE_CORDLESS = 520; // 0x208
- field public static final int PHONE_ISDN = 532; // 0x214
- field public static final int PHONE_MODEM_OR_GATEWAY = 528; // 0x210
- field public static final int PHONE_SMART = 524; // 0x20c
- field public static final int PHONE_UNCATEGORIZED = 512; // 0x200
- field public static final int TOY_CONTROLLER = 2064; // 0x810
- field public static final int TOY_DOLL_ACTION_FIGURE = 2060; // 0x80c
- field public static final int TOY_GAME = 2068; // 0x814
- field public static final int TOY_ROBOT = 2052; // 0x804
- field public static final int TOY_UNCATEGORIZED = 2048; // 0x800
- field public static final int TOY_VEHICLE = 2056; // 0x808
- field public static final int WEARABLE_GLASSES = 1812; // 0x714
- field public static final int WEARABLE_HELMET = 1808; // 0x710
- field public static final int WEARABLE_JACKET = 1804; // 0x70c
- field public static final int WEARABLE_PAGER = 1800; // 0x708
- field public static final int WEARABLE_UNCATEGORIZED = 1792; // 0x700
- field public static final int WEARABLE_WRIST_WATCH = 1796; // 0x704
- }
-
- public static class BluetoothClass.Device.Major {
- ctor public BluetoothClass.Device.Major();
- field public static final int AUDIO_VIDEO = 1024; // 0x400
- field public static final int COMPUTER = 256; // 0x100
- field public static final int HEALTH = 2304; // 0x900
- field public static final int IMAGING = 1536; // 0x600
- field public static final int MISC = 0; // 0x0
- field public static final int NETWORKING = 768; // 0x300
- field public static final int PERIPHERAL = 1280; // 0x500
- field public static final int PHONE = 512; // 0x200
- field public static final int TOY = 2048; // 0x800
- field public static final int UNCATEGORIZED = 7936; // 0x1f00
- field public static final int WEARABLE = 1792; // 0x700
- }
-
- public static final class BluetoothClass.Service {
- ctor public BluetoothClass.Service();
- field public static final int AUDIO = 2097152; // 0x200000
- field public static final int CAPTURE = 524288; // 0x80000
- field public static final int INFORMATION = 8388608; // 0x800000
- field public static final int LE_AUDIO = 16384; // 0x4000
- field public static final int LIMITED_DISCOVERABILITY = 8192; // 0x2000
- field public static final int NETWORKING = 131072; // 0x20000
- field public static final int OBJECT_TRANSFER = 1048576; // 0x100000
- field public static final int POSITIONING = 65536; // 0x10000
- field public static final int RENDER = 262144; // 0x40000
- field public static final int TELEPHONY = 4194304; // 0x400000
- }
-
- public final class BluetoothCodecConfig implements android.os.Parcelable {
- ctor public BluetoothCodecConfig(int);
- method public int describeContents();
- method public int getBitsPerSample();
- method public int getChannelMode();
- method public int getCodecPriority();
- method public long getCodecSpecific1();
- method public long getCodecSpecific2();
- method public long getCodecSpecific3();
- method public long getCodecSpecific4();
- method public int getCodecType();
- method public static int getMaxCodecType();
- method public int getSampleRate();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int BITS_PER_SAMPLE_16 = 1; // 0x1
- field public static final int BITS_PER_SAMPLE_24 = 2; // 0x2
- field public static final int BITS_PER_SAMPLE_32 = 4; // 0x4
- field public static final int BITS_PER_SAMPLE_NONE = 0; // 0x0
- field public static final int CHANNEL_MODE_MONO = 1; // 0x1
- field public static final int CHANNEL_MODE_NONE = 0; // 0x0
- field public static final int CHANNEL_MODE_STEREO = 2; // 0x2
- field public static final int CODEC_PRIORITY_DEFAULT = 0; // 0x0
- field public static final int CODEC_PRIORITY_DISABLED = -1; // 0xffffffff
- field public static final int CODEC_PRIORITY_HIGHEST = 1000000; // 0xf4240
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothCodecConfig> CREATOR;
- field public static final int SAMPLE_RATE_176400 = 16; // 0x10
- field public static final int SAMPLE_RATE_192000 = 32; // 0x20
- field public static final int SAMPLE_RATE_44100 = 1; // 0x1
- field public static final int SAMPLE_RATE_48000 = 2; // 0x2
- field public static final int SAMPLE_RATE_88200 = 4; // 0x4
- field public static final int SAMPLE_RATE_96000 = 8; // 0x8
- field public static final int SAMPLE_RATE_NONE = 0; // 0x0
- field public static final int SOURCE_CODEC_TYPE_AAC = 1; // 0x1
- field public static final int SOURCE_CODEC_TYPE_APTX = 2; // 0x2
- field public static final int SOURCE_CODEC_TYPE_APTX_HD = 3; // 0x3
- field public static final int SOURCE_CODEC_TYPE_INVALID = 1000000; // 0xf4240
- field public static final int SOURCE_CODEC_TYPE_LC3 = 5; // 0x5
- field public static final int SOURCE_CODEC_TYPE_LDAC = 4; // 0x4
- field public static final int SOURCE_CODEC_TYPE_SBC = 0; // 0x0
- }
-
- public static final class BluetoothCodecConfig.Builder {
- ctor public BluetoothCodecConfig.Builder();
- method @NonNull public android.bluetooth.BluetoothCodecConfig build();
- method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setBitsPerSample(int);
- method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setChannelMode(int);
- method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecPriority(int);
- method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecSpecific1(long);
- method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecSpecific2(long);
- method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecSpecific3(long);
- method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecSpecific4(long);
- method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setCodecType(int);
- method @NonNull public android.bluetooth.BluetoothCodecConfig.Builder setSampleRate(int);
- }
-
- public final class BluetoothCodecStatus implements android.os.Parcelable {
- ctor public BluetoothCodecStatus(@Nullable android.bluetooth.BluetoothCodecConfig, @Nullable java.util.List<android.bluetooth.BluetoothCodecConfig>, @Nullable java.util.List<android.bluetooth.BluetoothCodecConfig>);
- method public int describeContents();
- method @Nullable public android.bluetooth.BluetoothCodecConfig getCodecConfig();
- method @NonNull public java.util.List<android.bluetooth.BluetoothCodecConfig> getCodecsLocalCapabilities();
- method @NonNull public java.util.List<android.bluetooth.BluetoothCodecConfig> getCodecsSelectableCapabilities();
- method public boolean isCodecConfigSelectable(@Nullable android.bluetooth.BluetoothCodecConfig);
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothCodecStatus> CREATOR;
- field public static final String EXTRA_CODEC_STATUS = "android.bluetooth.extra.CODEC_STATUS";
- }
-
- public final class BluetoothCsipSetCoordinator implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
- method public void close();
- method protected void finalize();
- method @NonNull public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method public int getConnectionState(@Nullable android.bluetooth.BluetoothDevice);
- method @NonNull public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]);
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CSIS_CONNECTION_STATE_CHANGED = "android.bluetooth.action.CSIS_CONNECTION_STATE_CHANGED";
- }
-
- public final class BluetoothDevice implements android.os.Parcelable {
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int, android.os.Handler);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBond();
- method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothSocket createInsecureL2capChannel(int) throws java.io.IOException;
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
- method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothSocket createL2capChannel(int) throws java.io.IOException;
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
- method public int describeContents();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean fetchUuidsWithSdp();
- method public String getAddress();
- method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public String getAlias();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothClass getBluetoothClass();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getBondState();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public String getName();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getType();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.os.ParcelUuid[] getUuids();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int setAlias(@Nullable String);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setPairingConfirmation(boolean);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean setPin(byte[]);
- method public void writeToParcel(android.os.Parcel, int);
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_ACL_CONNECTED = "android.bluetooth.device.action.ACL_CONNECTED";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_ACL_DISCONNECTED = "android.bluetooth.device.action.ACL_DISCONNECTED";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_ACL_DISCONNECT_REQUESTED = "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_ALIAS_CHANGED = "android.bluetooth.device.action.ALIAS_CHANGED";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_BOND_STATE_CHANGED = "android.bluetooth.device.action.BOND_STATE_CHANGED";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CLASS_CHANGED = "android.bluetooth.device.action.CLASS_CHANGED";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public static final String ACTION_FOUND = "android.bluetooth.device.action.FOUND";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_NAME_CHANGED = "android.bluetooth.device.action.NAME_CHANGED";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_PAIRING_REQUEST = "android.bluetooth.device.action.PAIRING_REQUEST";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_UUID = "android.bluetooth.device.action.UUID";
- field public static final int ADDRESS_TYPE_PUBLIC = 0; // 0x0
- field public static final int ADDRESS_TYPE_RANDOM = 1; // 0x1
- field public static final int BOND_BONDED = 12; // 0xc
- field public static final int BOND_BONDING = 11; // 0xb
- field public static final int BOND_NONE = 10; // 0xa
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothDevice> CREATOR;
- field public static final int DEVICE_TYPE_CLASSIC = 1; // 0x1
- field public static final int DEVICE_TYPE_DUAL = 3; // 0x3
- field public static final int DEVICE_TYPE_LE = 2; // 0x2
- field public static final int DEVICE_TYPE_UNKNOWN = 0; // 0x0
- field public static final int ERROR = -2147483648; // 0x80000000
- field public static final String EXTRA_BOND_STATE = "android.bluetooth.device.extra.BOND_STATE";
- field public static final String EXTRA_CLASS = "android.bluetooth.device.extra.CLASS";
- field public static final String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE";
- field public static final String EXTRA_IS_COORDINATED_SET_MEMBER = "android.bluetooth.extra.IS_COORDINATED_SET_MEMBER";
- field public static final String EXTRA_NAME = "android.bluetooth.device.extra.NAME";
- field public static final String EXTRA_PAIRING_KEY = "android.bluetooth.device.extra.PAIRING_KEY";
- field public static final String EXTRA_PAIRING_VARIANT = "android.bluetooth.device.extra.PAIRING_VARIANT";
- field public static final String EXTRA_PREVIOUS_BOND_STATE = "android.bluetooth.device.extra.PREVIOUS_BOND_STATE";
- field public static final String EXTRA_RSSI = "android.bluetooth.device.extra.RSSI";
- field public static final String EXTRA_TRANSPORT = "android.bluetooth.device.extra.TRANSPORT";
- field public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
- field public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2; // 0x2
- field public static final int PAIRING_VARIANT_PIN = 0; // 0x0
- field public static final int PHY_LE_1M = 1; // 0x1
- field public static final int PHY_LE_1M_MASK = 1; // 0x1
- field public static final int PHY_LE_2M = 2; // 0x2
- field public static final int PHY_LE_2M_MASK = 2; // 0x2
- field public static final int PHY_LE_CODED = 3; // 0x3
- field public static final int PHY_LE_CODED_MASK = 4; // 0x4
- field public static final int PHY_OPTION_NO_PREFERRED = 0; // 0x0
- field public static final int PHY_OPTION_S2 = 1; // 0x1
- field public static final int PHY_OPTION_S8 = 2; // 0x2
- field public static final int TRANSPORT_AUTO = 0; // 0x0
- field public static final int TRANSPORT_BREDR = 1; // 0x1
- field public static final int TRANSPORT_LE = 2; // 0x2
- }
-
- public final class BluetoothGatt implements android.bluetooth.BluetoothProfile {
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void abortReliableWrite();
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void abortReliableWrite(android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean beginReliableWrite();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void close();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean connect();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void disconnect();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean discoverServices();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean executeReliableWrite();
- method @Deprecated public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method @Deprecated public int getConnectionState(android.bluetooth.BluetoothDevice);
- method public android.bluetooth.BluetoothDevice getDevice();
- method @Deprecated public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
- method public android.bluetooth.BluetoothGattService getService(java.util.UUID);
- method public java.util.List<android.bluetooth.BluetoothGattService> getServices();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean readCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean readDescriptor(android.bluetooth.BluetoothGattDescriptor);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void readPhy();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean readRemoteRssi();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean requestConnectionPriority(int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean requestMtu(int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean setCharacteristicNotification(android.bluetooth.BluetoothGattCharacteristic, boolean);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void setPreferredPhy(int, int, int);
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean writeCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int writeCharacteristic(@NonNull android.bluetooth.BluetoothGattCharacteristic, @NonNull byte[], int);
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean writeDescriptor(android.bluetooth.BluetoothGattDescriptor);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int writeDescriptor(@NonNull android.bluetooth.BluetoothGattDescriptor, @NonNull byte[]);
- field public static final int CONNECTION_PRIORITY_BALANCED = 0; // 0x0
- field public static final int CONNECTION_PRIORITY_HIGH = 1; // 0x1
- field public static final int CONNECTION_PRIORITY_LOW_POWER = 2; // 0x2
- field public static final int GATT_CONNECTION_CONGESTED = 143; // 0x8f
- field public static final int GATT_FAILURE = 257; // 0x101
- field public static final int GATT_INSUFFICIENT_AUTHENTICATION = 5; // 0x5
- field public static final int GATT_INSUFFICIENT_AUTHORIZATION = 8; // 0x8
- field public static final int GATT_INSUFFICIENT_ENCRYPTION = 15; // 0xf
- field public static final int GATT_INVALID_ATTRIBUTE_LENGTH = 13; // 0xd
- field public static final int GATT_INVALID_OFFSET = 7; // 0x7
- field public static final int GATT_READ_NOT_PERMITTED = 2; // 0x2
- field public static final int GATT_REQUEST_NOT_SUPPORTED = 6; // 0x6
- field public static final int GATT_SUCCESS = 0; // 0x0
- field public static final int GATT_WRITE_NOT_PERMITTED = 3; // 0x3
- }
-
- public abstract class BluetoothGattCallback {
- ctor public BluetoothGattCallback();
- method @Deprecated public void onCharacteristicChanged(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic);
- method public void onCharacteristicChanged(@NonNull android.bluetooth.BluetoothGatt, @NonNull android.bluetooth.BluetoothGattCharacteristic, @NonNull byte[]);
- method @Deprecated public void onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
- method public void onCharacteristicRead(@NonNull android.bluetooth.BluetoothGatt, @NonNull android.bluetooth.BluetoothGattCharacteristic, @NonNull byte[], int);
- method public void onCharacteristicWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
- method public void onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int);
- method @Deprecated public void onDescriptorRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int);
- method public void onDescriptorRead(@NonNull android.bluetooth.BluetoothGatt, @NonNull android.bluetooth.BluetoothGattDescriptor, int, @NonNull byte[]);
- method public void onDescriptorWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int);
- method public void onMtuChanged(android.bluetooth.BluetoothGatt, int, int);
- method public void onPhyRead(android.bluetooth.BluetoothGatt, int, int, int);
- method public void onPhyUpdate(android.bluetooth.BluetoothGatt, int, int, int);
- method public void onReadRemoteRssi(android.bluetooth.BluetoothGatt, int, int);
- method public void onReliableWriteCompleted(android.bluetooth.BluetoothGatt, int);
- method public void onServiceChanged(@NonNull android.bluetooth.BluetoothGatt);
- method public void onServicesDiscovered(android.bluetooth.BluetoothGatt, int);
- }
-
- public class BluetoothGattCharacteristic implements android.os.Parcelable {
- ctor public BluetoothGattCharacteristic(java.util.UUID, int, int);
- method public boolean addDescriptor(android.bluetooth.BluetoothGattDescriptor);
- method public int describeContents();
- method public android.bluetooth.BluetoothGattDescriptor getDescriptor(java.util.UUID);
- method public java.util.List<android.bluetooth.BluetoothGattDescriptor> getDescriptors();
- method @Deprecated public Float getFloatValue(int, int);
- method public int getInstanceId();
- method @Deprecated public Integer getIntValue(int, int);
- method public int getPermissions();
- method public int getProperties();
- method public android.bluetooth.BluetoothGattService getService();
- method @Deprecated public String getStringValue(int);
- method public java.util.UUID getUuid();
- method @Deprecated public byte[] getValue();
- method public int getWriteType();
- method @Deprecated public boolean setValue(byte[]);
- method @Deprecated public boolean setValue(int, int, int);
- method @Deprecated public boolean setValue(int, int, int, int);
- method @Deprecated public boolean setValue(String);
- method public void setWriteType(int);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattCharacteristic> CREATOR;
- field public static final int FORMAT_FLOAT = 52; // 0x34
- field public static final int FORMAT_SFLOAT = 50; // 0x32
- field public static final int FORMAT_SINT16 = 34; // 0x22
- field public static final int FORMAT_SINT32 = 36; // 0x24
- field public static final int FORMAT_SINT8 = 33; // 0x21
- field public static final int FORMAT_UINT16 = 18; // 0x12
- field public static final int FORMAT_UINT32 = 20; // 0x14
- field public static final int FORMAT_UINT8 = 17; // 0x11
- field public static final int PERMISSION_READ = 1; // 0x1
- field public static final int PERMISSION_READ_ENCRYPTED = 2; // 0x2
- field public static final int PERMISSION_READ_ENCRYPTED_MITM = 4; // 0x4
- field public static final int PERMISSION_WRITE = 16; // 0x10
- field public static final int PERMISSION_WRITE_ENCRYPTED = 32; // 0x20
- field public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 64; // 0x40
- field public static final int PERMISSION_WRITE_SIGNED = 128; // 0x80
- field public static final int PERMISSION_WRITE_SIGNED_MITM = 256; // 0x100
- field public static final int PROPERTY_BROADCAST = 1; // 0x1
- field public static final int PROPERTY_EXTENDED_PROPS = 128; // 0x80
- field public static final int PROPERTY_INDICATE = 32; // 0x20
- field public static final int PROPERTY_NOTIFY = 16; // 0x10
- field public static final int PROPERTY_READ = 2; // 0x2
- field public static final int PROPERTY_SIGNED_WRITE = 64; // 0x40
- field public static final int PROPERTY_WRITE = 8; // 0x8
- field public static final int PROPERTY_WRITE_NO_RESPONSE = 4; // 0x4
- field public static final int WRITE_TYPE_DEFAULT = 2; // 0x2
- field public static final int WRITE_TYPE_NO_RESPONSE = 1; // 0x1
- field public static final int WRITE_TYPE_SIGNED = 4; // 0x4
- field protected java.util.List<android.bluetooth.BluetoothGattDescriptor> mDescriptors;
- }
-
- public class BluetoothGattDescriptor implements android.os.Parcelable {
- ctor public BluetoothGattDescriptor(java.util.UUID, int);
- method public int describeContents();
- method public android.bluetooth.BluetoothGattCharacteristic getCharacteristic();
- method public int getPermissions();
- method public java.util.UUID getUuid();
- method @Deprecated public byte[] getValue();
- method @Deprecated public boolean setValue(byte[]);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattDescriptor> CREATOR;
- field public static final byte[] DISABLE_NOTIFICATION_VALUE;
- field public static final byte[] ENABLE_INDICATION_VALUE;
- field public static final byte[] ENABLE_NOTIFICATION_VALUE;
- field public static final int PERMISSION_READ = 1; // 0x1
- field public static final int PERMISSION_READ_ENCRYPTED = 2; // 0x2
- field public static final int PERMISSION_READ_ENCRYPTED_MITM = 4; // 0x4
- field public static final int PERMISSION_WRITE = 16; // 0x10
- field public static final int PERMISSION_WRITE_ENCRYPTED = 32; // 0x20
- field public static final int PERMISSION_WRITE_ENCRYPTED_MITM = 64; // 0x40
- field public static final int PERMISSION_WRITE_SIGNED = 128; // 0x80
- field public static final int PERMISSION_WRITE_SIGNED_MITM = 256; // 0x100
- }
-
- public final class BluetoothGattServer implements android.bluetooth.BluetoothProfile {
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean addService(android.bluetooth.BluetoothGattService);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void cancelConnection(android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void clearServices();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void close();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean connect(android.bluetooth.BluetoothDevice, boolean);
- method public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method public int getConnectionState(android.bluetooth.BluetoothDevice);
- method public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
- method public android.bluetooth.BluetoothGattService getService(java.util.UUID);
- method public java.util.List<android.bluetooth.BluetoothGattService> getServices();
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean notifyCharacteristicChanged(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothGattCharacteristic, boolean);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int notifyCharacteristicChanged(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothGattCharacteristic, boolean, @NonNull byte[]);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void readPhy(android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean removeService(android.bluetooth.BluetoothGattService);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean sendResponse(android.bluetooth.BluetoothDevice, int, int, int, byte[]);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void setPreferredPhy(android.bluetooth.BluetoothDevice, int, int, int);
- }
-
- public abstract class BluetoothGattServerCallback {
- ctor public BluetoothGattServerCallback();
- method public void onCharacteristicReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattCharacteristic);
- method public void onCharacteristicWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattCharacteristic, boolean, boolean, int, byte[]);
- method public void onConnectionStateChange(android.bluetooth.BluetoothDevice, int, int);
- method public void onDescriptorReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattDescriptor);
- method public void onDescriptorWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattDescriptor, boolean, boolean, int, byte[]);
- method public void onExecuteWrite(android.bluetooth.BluetoothDevice, int, boolean);
- method public void onMtuChanged(android.bluetooth.BluetoothDevice, int);
- method public void onNotificationSent(android.bluetooth.BluetoothDevice, int);
- method public void onPhyRead(android.bluetooth.BluetoothDevice, int, int, int);
- method public void onPhyUpdate(android.bluetooth.BluetoothDevice, int, int, int);
- method public void onServiceAdded(int, android.bluetooth.BluetoothGattService);
- }
-
- public class BluetoothGattService implements android.os.Parcelable {
- ctor public BluetoothGattService(java.util.UUID, int);
- method public boolean addCharacteristic(android.bluetooth.BluetoothGattCharacteristic);
- method public boolean addService(android.bluetooth.BluetoothGattService);
- method public int describeContents();
- method public android.bluetooth.BluetoothGattCharacteristic getCharacteristic(java.util.UUID);
- method public java.util.List<android.bluetooth.BluetoothGattCharacteristic> getCharacteristics();
- method public java.util.List<android.bluetooth.BluetoothGattService> getIncludedServices();
- method public int getInstanceId();
- method public int getType();
- method public java.util.UUID getUuid();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothGattService> CREATOR;
- field public static final int SERVICE_TYPE_PRIMARY = 0; // 0x0
- field public static final int SERVICE_TYPE_SECONDARY = 1; // 0x1
- field protected java.util.List<android.bluetooth.BluetoothGattCharacteristic> mCharacteristics;
- field protected java.util.List<android.bluetooth.BluetoothGattService> mIncludedServices;
- }
-
- public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile {
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isAudioConnected(android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isNoiseReductionSupported(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isVoiceRecognitionSupported(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean sendVendorSpecificResultCode(android.bluetooth.BluetoothDevice, String, String);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean startVoiceRecognition(android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean stopVoiceRecognition(android.bluetooth.BluetoothDevice);
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_AUDIO_STATE_CHANGED = "android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_VENDOR_SPECIFIC_HEADSET_EVENT = "android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT";
- field public static final int AT_CMD_TYPE_ACTION = 4; // 0x4
- field public static final int AT_CMD_TYPE_BASIC = 3; // 0x3
- field public static final int AT_CMD_TYPE_READ = 0; // 0x0
- field public static final int AT_CMD_TYPE_SET = 2; // 0x2
- field public static final int AT_CMD_TYPE_TEST = 1; // 0x1
- field public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_ARGS = "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_ARGS";
- field public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD = "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD";
- field public static final String EXTRA_VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE = "android.bluetooth.headset.extra.VENDOR_SPECIFIC_HEADSET_EVENT_CMD_TYPE";
- field public static final int STATE_AUDIO_CONNECTED = 12; // 0xc
- field public static final int STATE_AUDIO_CONNECTING = 11; // 0xb
- field public static final int STATE_AUDIO_DISCONNECTED = 10; // 0xa
- field public static final String VENDOR_RESULT_CODE_COMMAND_ANDROID = "+ANDROID";
- field public static final String VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY = "android.bluetooth.headset.intent.category.companyid";
- }
-
- @Deprecated public final class BluetoothHealth implements android.bluetooth.BluetoothProfile {
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean connectChannelToSource(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration);
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disconnectChannel(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration, int);
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice);
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.os.ParcelFileDescriptor getMainChannelFd(android.bluetooth.BluetoothDevice, android.bluetooth.BluetoothHealthAppConfiguration);
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean registerSinkAppConfiguration(String, int, android.bluetooth.BluetoothHealthCallback);
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean unregisterAppConfiguration(android.bluetooth.BluetoothHealthAppConfiguration);
- field @Deprecated public static final int APP_CONFIG_REGISTRATION_FAILURE = 1; // 0x1
- field @Deprecated public static final int APP_CONFIG_REGISTRATION_SUCCESS = 0; // 0x0
- field @Deprecated public static final int APP_CONFIG_UNREGISTRATION_FAILURE = 3; // 0x3
- field @Deprecated public static final int APP_CONFIG_UNREGISTRATION_SUCCESS = 2; // 0x2
- field @Deprecated public static final int CHANNEL_TYPE_RELIABLE = 10; // 0xa
- field @Deprecated public static final int CHANNEL_TYPE_STREAMING = 11; // 0xb
- field @Deprecated public static final int SINK_ROLE = 2; // 0x2
- field @Deprecated public static final int SOURCE_ROLE = 1; // 0x1
- field @Deprecated public static final int STATE_CHANNEL_CONNECTED = 2; // 0x2
- field @Deprecated public static final int STATE_CHANNEL_CONNECTING = 1; // 0x1
- field @Deprecated public static final int STATE_CHANNEL_DISCONNECTED = 0; // 0x0
- field @Deprecated public static final int STATE_CHANNEL_DISCONNECTING = 3; // 0x3
- }
-
- @Deprecated public final class BluetoothHealthAppConfiguration implements android.os.Parcelable {
- method @Deprecated public int describeContents();
- method @Deprecated public int getDataType();
- method @Deprecated public String getName();
- method @Deprecated public int getRole();
- method @Deprecated public void writeToParcel(android.os.Parcel, int);
- field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothHealthAppConfiguration> CREATOR;
- }
-
- @Deprecated public abstract class BluetoothHealthCallback {
- ctor @Deprecated public BluetoothHealthCallback();
- method @Deprecated @BinderThread public void onHealthAppConfigurationStatusChange(android.bluetooth.BluetoothHealthAppConfiguration, int);
- method @Deprecated @BinderThread public void onHealthChannelStateChange(android.bluetooth.BluetoothHealthAppConfiguration, android.bluetooth.BluetoothDevice, int, int, android.os.ParcelFileDescriptor, int);
- }
-
- public final class BluetoothHearingAid implements android.bluetooth.BluetoothProfile {
- method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
- method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]);
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.hearingaid.profile.action.CONNECTION_STATE_CHANGED";
- }
-
- public final class BluetoothHidDevice implements android.bluetooth.BluetoothProfile {
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean connect(android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disconnect(android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean registerApp(android.bluetooth.BluetoothHidDeviceAppSdpSettings, android.bluetooth.BluetoothHidDeviceAppQosSettings, android.bluetooth.BluetoothHidDeviceAppQosSettings, java.util.concurrent.Executor, android.bluetooth.BluetoothHidDevice.Callback);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean replyReport(android.bluetooth.BluetoothDevice, byte, byte, byte[]);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean reportError(android.bluetooth.BluetoothDevice, byte);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean sendReport(android.bluetooth.BluetoothDevice, int, byte[]);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean unregisterApp();
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.hiddevice.profile.action.CONNECTION_STATE_CHANGED";
- field public static final byte ERROR_RSP_INVALID_PARAM = 4; // 0x4
- field public static final byte ERROR_RSP_INVALID_RPT_ID = 2; // 0x2
- field public static final byte ERROR_RSP_NOT_READY = 1; // 0x1
- field public static final byte ERROR_RSP_SUCCESS = 0; // 0x0
- field public static final byte ERROR_RSP_UNKNOWN = 14; // 0xe
- field public static final byte ERROR_RSP_UNSUPPORTED_REQ = 3; // 0x3
- field public static final byte PROTOCOL_BOOT_MODE = 0; // 0x0
- field public static final byte PROTOCOL_REPORT_MODE = 1; // 0x1
- field public static final byte REPORT_TYPE_FEATURE = 3; // 0x3
- field public static final byte REPORT_TYPE_INPUT = 1; // 0x1
- field public static final byte REPORT_TYPE_OUTPUT = 2; // 0x2
- field public static final byte SUBCLASS1_COMBO = -64; // 0xffffffc0
- field public static final byte SUBCLASS1_KEYBOARD = 64; // 0x40
- field public static final byte SUBCLASS1_MOUSE = -128; // 0xffffff80
- field public static final byte SUBCLASS1_NONE = 0; // 0x0
- field public static final byte SUBCLASS2_CARD_READER = 6; // 0x6
- field public static final byte SUBCLASS2_DIGITIZER_TABLET = 5; // 0x5
- field public static final byte SUBCLASS2_GAMEPAD = 2; // 0x2
- field public static final byte SUBCLASS2_JOYSTICK = 1; // 0x1
- field public static final byte SUBCLASS2_REMOTE_CONTROL = 3; // 0x3
- field public static final byte SUBCLASS2_SENSING_DEVICE = 4; // 0x4
- field public static final byte SUBCLASS2_UNCATEGORIZED = 0; // 0x0
- }
-
- public abstract static class BluetoothHidDevice.Callback {
- ctor public BluetoothHidDevice.Callback();
- method public void onAppStatusChanged(android.bluetooth.BluetoothDevice, boolean);
- method public void onConnectionStateChanged(android.bluetooth.BluetoothDevice, int);
- method public void onGetReport(android.bluetooth.BluetoothDevice, byte, byte, int);
- method public void onInterruptData(android.bluetooth.BluetoothDevice, byte, byte[]);
- method public void onSetProtocol(android.bluetooth.BluetoothDevice, byte);
- method public void onSetReport(android.bluetooth.BluetoothDevice, byte, byte, byte[]);
- method public void onVirtualCableUnplug(android.bluetooth.BluetoothDevice);
- }
-
- public final class BluetoothHidDeviceAppQosSettings implements android.os.Parcelable {
- ctor public BluetoothHidDeviceAppQosSettings(int, int, int, int, int, int);
- method public int describeContents();
- method public int getDelayVariation();
- method public int getLatency();
- method public int getPeakBandwidth();
- method public int getServiceType();
- method public int getTokenBucketSize();
- method public int getTokenRate();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothHidDeviceAppQosSettings> CREATOR;
- field public static final int MAX = -1; // 0xffffffff
- field public static final int SERVICE_BEST_EFFORT = 1; // 0x1
- field public static final int SERVICE_GUARANTEED = 2; // 0x2
- field public static final int SERVICE_NO_TRAFFIC = 0; // 0x0
- }
-
- public final class BluetoothHidDeviceAppSdpSettings implements android.os.Parcelable {
- ctor public BluetoothHidDeviceAppSdpSettings(String, String, String, byte, byte[]);
- method public int describeContents();
- method public String getDescription();
- method public byte[] getDescriptors();
- method public String getName();
- method public String getProvider();
- method public byte getSubclass();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothHidDeviceAppSdpSettings> CREATOR;
- }
-
- public final class BluetoothLeAudio implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
- method public void close();
- method protected void finalize();
- method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothDevice getConnectedGroupLeadDevice(int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
- method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getGroupId(@NonNull android.bluetooth.BluetoothDevice);
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED = "android.bluetooth.action.LE_AUDIO_CONNECTION_STATE_CHANGED";
- }
-
- public final class BluetoothLeAudioCodecConfig implements android.os.Parcelable {
- method public int describeContents();
- method public int getBitsPerSample();
- method public int getChannelMode();
- method @NonNull public String getCodecName();
- method public int getCodecPriority();
- method public int getCodecType();
- method public int getFrameDuration();
- method public static int getMaxCodecType();
- method public int getOctetsPerFrame();
- method public int getSampleRate();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field public static final int BITS_PER_SAMPLE_16 = 1; // 0x1
- field public static final int BITS_PER_SAMPLE_24 = 2; // 0x2
- field public static final int BITS_PER_SAMPLE_32 = 3; // 0x3
- field public static final int BITS_PER_SAMPLE_NONE = 0; // 0x0
- field public static final int CHANNEL_MODE_MONO = 1; // 0x1
- field public static final int CHANNEL_MODE_NONE = 0; // 0x0
- field public static final int CHANNEL_MODE_STEREO = 2; // 0x2
- field public static final int CODEC_PRIORITY_DEFAULT = 0; // 0x0
- field public static final int CODEC_PRIORITY_DISABLED = -1; // 0xffffffff
- field public static final int CODEC_PRIORITY_HIGHEST = 1000000; // 0xf4240
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothLeAudioCodecConfig> CREATOR;
- field public static final int FRAME_DURATION_10000 = 2; // 0x2
- field public static final int FRAME_DURATION_7500 = 1; // 0x1
- field public static final int FRAME_DURATION_NONE = 0; // 0x0
- field public static final int SAMPLE_RATE_16000 = 2; // 0x2
- field public static final int SAMPLE_RATE_24000 = 3; // 0x3
- field public static final int SAMPLE_RATE_32000 = 4; // 0x4
- field public static final int SAMPLE_RATE_44100 = 5; // 0x5
- field public static final int SAMPLE_RATE_48000 = 6; // 0x6
- field public static final int SAMPLE_RATE_8000 = 1; // 0x1
- field public static final int SAMPLE_RATE_NONE = 0; // 0x0
- field public static final int SOURCE_CODEC_TYPE_INVALID = 1000000; // 0xf4240
- field public static final int SOURCE_CODEC_TYPE_LC3 = 0; // 0x0
- }
-
- public static final class BluetoothLeAudioCodecConfig.Builder {
- ctor public BluetoothLeAudioCodecConfig.Builder();
- ctor public BluetoothLeAudioCodecConfig.Builder(@NonNull android.bluetooth.BluetoothLeAudioCodecConfig);
- method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig build();
- method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setBitsPerSample(int);
- method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setChannelMode(int);
- method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setCodecPriority(int);
- method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setCodecType(int);
- method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setFrameDuration(int);
- method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setOctetsPerFrame(int);
- method @NonNull public android.bluetooth.BluetoothLeAudioCodecConfig.Builder setSampleRate(int);
- }
-
- public final class BluetoothManager {
- method public android.bluetooth.BluetoothAdapter getAdapter();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices(int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(android.bluetooth.BluetoothDevice, int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int, int[]);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothGattServer openGattServer(android.content.Context, android.bluetooth.BluetoothGattServerCallback);
- }
-
- public interface BluetoothProfile {
- method public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method public int getConnectionState(android.bluetooth.BluetoothDevice);
- method public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(int[]);
- field public static final int A2DP = 2; // 0x2
- field public static final int CSIP_SET_COORDINATOR = 25; // 0x19
- field public static final String EXTRA_PREVIOUS_STATE = "android.bluetooth.profile.extra.PREVIOUS_STATE";
- field public static final String EXTRA_STATE = "android.bluetooth.profile.extra.STATE";
- field public static final int GATT = 7; // 0x7
- field public static final int GATT_SERVER = 8; // 0x8
- field public static final int HAP_CLIENT = 28; // 0x1c
- field public static final int HEADSET = 1; // 0x1
- field @Deprecated public static final int HEALTH = 3; // 0x3
- field public static final int HEARING_AID = 21; // 0x15
- field public static final int HID_DEVICE = 19; // 0x13
- field public static final int LE_AUDIO = 22; // 0x16
- field public static final int SAP = 10; // 0xa
- field public static final int STATE_CONNECTED = 2; // 0x2
- field public static final int STATE_CONNECTING = 1; // 0x1
- field public static final int STATE_DISCONNECTED = 0; // 0x0
- field public static final int STATE_DISCONNECTING = 3; // 0x3
- }
-
- public static interface BluetoothProfile.ServiceListener {
- method public void onServiceConnected(int, android.bluetooth.BluetoothProfile);
- method public void onServiceDisconnected(int);
- }
-
- public final class BluetoothServerSocket implements java.io.Closeable {
- method public android.bluetooth.BluetoothSocket accept() throws java.io.IOException;
- method public android.bluetooth.BluetoothSocket accept(int) throws java.io.IOException;
- method public void close() throws java.io.IOException;
- method public int getPsm();
- }
-
- public final class BluetoothSocket implements java.io.Closeable {
- method public void close() throws java.io.IOException;
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void connect() throws java.io.IOException;
- method public int getConnectionType();
- method public java.io.InputStream getInputStream() throws java.io.IOException;
- method public int getMaxReceivePacketSize();
- method public int getMaxTransmitPacketSize();
- method public java.io.OutputStream getOutputStream() throws java.io.IOException;
- method public android.bluetooth.BluetoothDevice getRemoteDevice();
- method public boolean isConnected();
- field public static final int TYPE_L2CAP = 3; // 0x3
- field public static final int TYPE_RFCOMM = 1; // 0x1
- field public static final int TYPE_SCO = 2; // 0x2
- }
-
- public final class BluetoothStatusCodes {
- field public static final int ERROR_BLUETOOTH_NOT_ALLOWED = 2; // 0x2
- field public static final int ERROR_BLUETOOTH_NOT_ENABLED = 1; // 0x1
- field public static final int ERROR_DEVICE_NOT_BONDED = 3; // 0x3
- field public static final int ERROR_GATT_WRITE_NOT_ALLOWED = 200; // 0xc8
- field public static final int ERROR_GATT_WRITE_REQUEST_BUSY = 201; // 0xc9
- field public static final int ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION = 6; // 0x6
- field public static final int ERROR_MISSING_BLUETOOTH_PRIVILEGED_PERMISSION = 8; // 0x8
- field public static final int ERROR_PROFILE_SERVICE_NOT_BOUND = 9; // 0x9
- field public static final int ERROR_UNKNOWN = 2147483647; // 0x7fffffff
- field public static final int FEATURE_NOT_SUPPORTED = 11; // 0xb
- field public static final int FEATURE_SUPPORTED = 10; // 0xa
- field public static final int SUCCESS = 0; // 0x0
- }
-
-}
-
-package android.bluetooth.le {
-
- public abstract class AdvertiseCallback {
- ctor public AdvertiseCallback();
- method public void onStartFailure(int);
- method public void onStartSuccess(android.bluetooth.le.AdvertiseSettings);
- field public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3; // 0x3
- field public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1; // 0x1
- field public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5; // 0x5
- field public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4; // 0x4
- field public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2; // 0x2
- }
-
- public final class AdvertiseData implements android.os.Parcelable {
- method public int describeContents();
- method public boolean getIncludeDeviceName();
- method public boolean getIncludeTxPowerLevel();
- method public android.util.SparseArray<byte[]> getManufacturerSpecificData();
- method public java.util.Map<android.os.ParcelUuid,byte[]> getServiceData();
- method @NonNull public java.util.List<android.os.ParcelUuid> getServiceSolicitationUuids();
- method public java.util.List<android.os.ParcelUuid> getServiceUuids();
- method @NonNull public java.util.List<android.bluetooth.le.TransportDiscoveryData> getTransportDiscoveryData();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertiseData> CREATOR;
- }
-
- public static final class AdvertiseData.Builder {
- ctor public AdvertiseData.Builder();
- method public android.bluetooth.le.AdvertiseData.Builder addManufacturerData(int, byte[]);
- method public android.bluetooth.le.AdvertiseData.Builder addServiceData(android.os.ParcelUuid, byte[]);
- method @NonNull public android.bluetooth.le.AdvertiseData.Builder addServiceSolicitationUuid(@NonNull android.os.ParcelUuid);
- method public android.bluetooth.le.AdvertiseData.Builder addServiceUuid(android.os.ParcelUuid);
- method @NonNull public android.bluetooth.le.AdvertiseData.Builder addTransportDiscoveryData(@NonNull android.bluetooth.le.TransportDiscoveryData);
- method public android.bluetooth.le.AdvertiseData build();
- method public android.bluetooth.le.AdvertiseData.Builder setIncludeDeviceName(boolean);
- method public android.bluetooth.le.AdvertiseData.Builder setIncludeTxPowerLevel(boolean);
- }
-
- public final class AdvertiseSettings implements android.os.Parcelable {
- method public int describeContents();
- method public int getMode();
- method public int getTimeout();
- method public int getTxPowerLevel();
- method public boolean isConnectable();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int ADVERTISE_MODE_BALANCED = 1; // 0x1
- field public static final int ADVERTISE_MODE_LOW_LATENCY = 2; // 0x2
- field public static final int ADVERTISE_MODE_LOW_POWER = 0; // 0x0
- field public static final int ADVERTISE_TX_POWER_HIGH = 3; // 0x3
- field public static final int ADVERTISE_TX_POWER_LOW = 1; // 0x1
- field public static final int ADVERTISE_TX_POWER_MEDIUM = 2; // 0x2
- field public static final int ADVERTISE_TX_POWER_ULTRA_LOW = 0; // 0x0
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertiseSettings> CREATOR;
- }
-
- public static final class AdvertiseSettings.Builder {
- ctor public AdvertiseSettings.Builder();
- method public android.bluetooth.le.AdvertiseSettings build();
- method public android.bluetooth.le.AdvertiseSettings.Builder setAdvertiseMode(int);
- method public android.bluetooth.le.AdvertiseSettings.Builder setConnectable(boolean);
- method public android.bluetooth.le.AdvertiseSettings.Builder setTimeout(int);
- method public android.bluetooth.le.AdvertiseSettings.Builder setTxPowerLevel(int);
- }
-
- public final class AdvertisingSet {
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void enableAdvertising(boolean, int, int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setAdvertisingData(android.bluetooth.le.AdvertiseData);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setAdvertisingParameters(android.bluetooth.le.AdvertisingSetParameters);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setPeriodicAdvertisingData(android.bluetooth.le.AdvertiseData);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setPeriodicAdvertisingEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setPeriodicAdvertisingParameters(android.bluetooth.le.PeriodicAdvertisingParameters);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void setScanResponseData(android.bluetooth.le.AdvertiseData);
- }
-
- public abstract class AdvertisingSetCallback {
- ctor public AdvertisingSetCallback();
- method public void onAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
- method public void onAdvertisingEnabled(android.bluetooth.le.AdvertisingSet, boolean, int);
- method public void onAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int, int);
- method public void onAdvertisingSetStarted(android.bluetooth.le.AdvertisingSet, int, int);
- method public void onAdvertisingSetStopped(android.bluetooth.le.AdvertisingSet);
- method public void onPeriodicAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
- method public void onPeriodicAdvertisingEnabled(android.bluetooth.le.AdvertisingSet, boolean, int);
- method public void onPeriodicAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int);
- method public void onScanResponseDataSet(android.bluetooth.le.AdvertisingSet, int);
- field public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3; // 0x3
- field public static final int ADVERTISE_FAILED_DATA_TOO_LARGE = 1; // 0x1
- field public static final int ADVERTISE_FAILED_FEATURE_UNSUPPORTED = 5; // 0x5
- field public static final int ADVERTISE_FAILED_INTERNAL_ERROR = 4; // 0x4
- field public static final int ADVERTISE_FAILED_TOO_MANY_ADVERTISERS = 2; // 0x2
- field public static final int ADVERTISE_SUCCESS = 0; // 0x0
- }
-
- public final class AdvertisingSetParameters implements android.os.Parcelable {
- method public int describeContents();
- method public int getInterval();
- method public int getPrimaryPhy();
- method public int getSecondaryPhy();
- method public int getTxPowerLevel();
- method public boolean includeTxPower();
- method public boolean isAnonymous();
- method public boolean isConnectable();
- method public boolean isLegacy();
- method public boolean isScannable();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertisingSetParameters> CREATOR;
- field public static final int INTERVAL_HIGH = 1600; // 0x640
- field public static final int INTERVAL_LOW = 160; // 0xa0
- field public static final int INTERVAL_MAX = 16777215; // 0xffffff
- field public static final int INTERVAL_MEDIUM = 400; // 0x190
- field public static final int INTERVAL_MIN = 160; // 0xa0
- field public static final int TX_POWER_HIGH = 1; // 0x1
- field public static final int TX_POWER_LOW = -15; // 0xfffffff1
- field public static final int TX_POWER_MAX = 1; // 0x1
- field public static final int TX_POWER_MEDIUM = -7; // 0xfffffff9
- field public static final int TX_POWER_MIN = -127; // 0xffffff81
- field public static final int TX_POWER_ULTRA_LOW = -21; // 0xffffffeb
- }
-
- public static final class AdvertisingSetParameters.Builder {
- ctor public AdvertisingSetParameters.Builder();
- method public android.bluetooth.le.AdvertisingSetParameters build();
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymous(boolean);
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setConnectable(boolean);
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setIncludeTxPower(boolean);
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setInterval(int);
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setLegacyMode(boolean);
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setPrimaryPhy(int);
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setScannable(boolean);
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setSecondaryPhy(int);
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setTxPowerLevel(int);
- }
-
- public final class BluetoothLeAdvertiser {
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void stopAdvertising(android.bluetooth.le.AdvertiseCallback);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADVERTISE) public void stopAdvertisingSet(android.bluetooth.le.AdvertisingSetCallback);
- }
-
- public final class BluetoothLeScanner {
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void flushPendingScanResults(android.bluetooth.le.ScanCallback);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void startScan(android.bluetooth.le.ScanCallback);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void startScan(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public int startScan(@Nullable java.util.List<android.bluetooth.le.ScanFilter>, @Nullable android.bluetooth.le.ScanSettings, @NonNull android.app.PendingIntent);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void stopScan(android.bluetooth.le.ScanCallback);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void stopScan(android.app.PendingIntent);
- field public static final String EXTRA_CALLBACK_TYPE = "android.bluetooth.le.extra.CALLBACK_TYPE";
- field public static final String EXTRA_ERROR_CODE = "android.bluetooth.le.extra.ERROR_CODE";
- field public static final String EXTRA_LIST_SCAN_RESULT = "android.bluetooth.le.extra.LIST_SCAN_RESULT";
- }
-
- public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
- method public int describeContents();
- method public boolean getIncludeTxPower();
- method public int getInterval();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.bluetooth.le.PeriodicAdvertisingParameters> CREATOR;
- }
-
- public static final class PeriodicAdvertisingParameters.Builder {
- ctor public PeriodicAdvertisingParameters.Builder();
- method public android.bluetooth.le.PeriodicAdvertisingParameters build();
- method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setIncludeTxPower(boolean);
- method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setInterval(int);
- }
-
- public abstract class ScanCallback {
- ctor public ScanCallback();
- method public void onBatchScanResults(java.util.List<android.bluetooth.le.ScanResult>);
- method public void onScanFailed(int);
- method public void onScanResult(int, android.bluetooth.le.ScanResult);
- field public static final int SCAN_FAILED_ALREADY_STARTED = 1; // 0x1
- field public static final int SCAN_FAILED_APPLICATION_REGISTRATION_FAILED = 2; // 0x2
- field public static final int SCAN_FAILED_FEATURE_UNSUPPORTED = 4; // 0x4
- field public static final int SCAN_FAILED_INTERNAL_ERROR = 3; // 0x3
- }
-
- public final class ScanFilter implements android.os.Parcelable {
- method public int describeContents();
- method @Nullable public String getDeviceAddress();
- method @Nullable public String getDeviceName();
- method @Nullable public byte[] getManufacturerData();
- method @Nullable public byte[] getManufacturerDataMask();
- method public int getManufacturerId();
- method @Nullable public byte[] getServiceData();
- method @Nullable public byte[] getServiceDataMask();
- method @Nullable public android.os.ParcelUuid getServiceDataUuid();
- method @Nullable public android.os.ParcelUuid getServiceSolicitationUuid();
- method @Nullable public android.os.ParcelUuid getServiceSolicitationUuidMask();
- method @Nullable public android.os.ParcelUuid getServiceUuid();
- method @Nullable public android.os.ParcelUuid getServiceUuidMask();
- method public boolean matches(android.bluetooth.le.ScanResult);
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanFilter> CREATOR;
- }
-
- public static final class ScanFilter.Builder {
- ctor public ScanFilter.Builder();
- method public android.bluetooth.le.ScanFilter build();
- method public android.bluetooth.le.ScanFilter.Builder setDeviceAddress(String);
- method public android.bluetooth.le.ScanFilter.Builder setDeviceName(String);
- method public android.bluetooth.le.ScanFilter.Builder setManufacturerData(int, byte[]);
- method public android.bluetooth.le.ScanFilter.Builder setManufacturerData(int, byte[], byte[]);
- method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[]);
- method public android.bluetooth.le.ScanFilter.Builder setServiceData(android.os.ParcelUuid, byte[], byte[]);
- method @NonNull public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(@Nullable android.os.ParcelUuid);
- method @NonNull public android.bluetooth.le.ScanFilter.Builder setServiceSolicitationUuid(@Nullable android.os.ParcelUuid, @Nullable android.os.ParcelUuid);
- method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid);
- method public android.bluetooth.le.ScanFilter.Builder setServiceUuid(android.os.ParcelUuid, android.os.ParcelUuid);
- }
-
- public final class ScanRecord {
- method public int getAdvertiseFlags();
- method public byte[] getBytes();
- method @Nullable public String getDeviceName();
- method public android.util.SparseArray<byte[]> getManufacturerSpecificData();
- method @Nullable public byte[] getManufacturerSpecificData(int);
- method public java.util.Map<android.os.ParcelUuid,byte[]> getServiceData();
- method @Nullable public byte[] getServiceData(android.os.ParcelUuid);
- method @NonNull public java.util.List<android.os.ParcelUuid> getServiceSolicitationUuids();
- method public java.util.List<android.os.ParcelUuid> getServiceUuids();
- method public int getTxPowerLevel();
- }
-
- public final class ScanResult implements android.os.Parcelable {
- ctor @Deprecated public ScanResult(android.bluetooth.BluetoothDevice, android.bluetooth.le.ScanRecord, int, long);
- ctor public ScanResult(android.bluetooth.BluetoothDevice, int, int, int, int, int, int, int, android.bluetooth.le.ScanRecord, long);
- method public int describeContents();
- method public int getAdvertisingSid();
- method public int getDataStatus();
- method public android.bluetooth.BluetoothDevice getDevice();
- method public int getPeriodicAdvertisingInterval();
- method public int getPrimaryPhy();
- method public int getRssi();
- method @Nullable public android.bluetooth.le.ScanRecord getScanRecord();
- method public int getSecondaryPhy();
- method public long getTimestampNanos();
- method public int getTxPower();
- method public boolean isConnectable();
- method public boolean isLegacy();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanResult> CREATOR;
- field public static final int DATA_COMPLETE = 0; // 0x0
- field public static final int DATA_TRUNCATED = 2; // 0x2
- field public static final int PERIODIC_INTERVAL_NOT_PRESENT = 0; // 0x0
- field public static final int PHY_UNUSED = 0; // 0x0
- field public static final int SID_NOT_PRESENT = 255; // 0xff
- field public static final int TX_POWER_NOT_PRESENT = 127; // 0x7f
- }
-
- public final class ScanSettings implements android.os.Parcelable {
- method public int describeContents();
- method public int getCallbackType();
- method public boolean getLegacy();
- method public int getPhy();
- method public long getReportDelayMillis();
- method public int getScanMode();
- method public int getScanResultType();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final int CALLBACK_TYPE_ALL_MATCHES = 1; // 0x1
- field public static final int CALLBACK_TYPE_FIRST_MATCH = 2; // 0x2
- field public static final int CALLBACK_TYPE_MATCH_LOST = 4; // 0x4
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanSettings> CREATOR;
- field public static final int MATCH_MODE_AGGRESSIVE = 1; // 0x1
- field public static final int MATCH_MODE_STICKY = 2; // 0x2
- field public static final int MATCH_NUM_FEW_ADVERTISEMENT = 2; // 0x2
- field public static final int MATCH_NUM_MAX_ADVERTISEMENT = 3; // 0x3
- field public static final int MATCH_NUM_ONE_ADVERTISEMENT = 1; // 0x1
- field public static final int PHY_LE_ALL_SUPPORTED = 255; // 0xff
- field public static final int SCAN_MODE_BALANCED = 1; // 0x1
- field public static final int SCAN_MODE_LOW_LATENCY = 2; // 0x2
- field public static final int SCAN_MODE_LOW_POWER = 0; // 0x0
- field public static final int SCAN_MODE_OPPORTUNISTIC = -1; // 0xffffffff
- }
-
- public static final class ScanSettings.Builder {
- ctor public ScanSettings.Builder();
- method public android.bluetooth.le.ScanSettings build();
- method public android.bluetooth.le.ScanSettings.Builder setCallbackType(int);
- method public android.bluetooth.le.ScanSettings.Builder setLegacy(boolean);
- method public android.bluetooth.le.ScanSettings.Builder setMatchMode(int);
- method public android.bluetooth.le.ScanSettings.Builder setNumOfMatches(int);
- method public android.bluetooth.le.ScanSettings.Builder setPhy(int);
- method public android.bluetooth.le.ScanSettings.Builder setReportDelay(long);
- method public android.bluetooth.le.ScanSettings.Builder setScanMode(int);
- }
-
- public final class TransportBlock implements android.os.Parcelable {
- ctor public TransportBlock(int, int, int, @Nullable byte[]);
- method public int describeContents();
- method public int getOrgId();
- method public int getTdsFlags();
- method @Nullable public byte[] getTransportData();
- method public int getTransportDataLength();
- method @Nullable public byte[] toByteArray();
- method public int totalBytes();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.TransportBlock> CREATOR;
- }
-
- public final class TransportDiscoveryData implements android.os.Parcelable {
- ctor public TransportDiscoveryData(int, @NonNull java.util.List<android.bluetooth.le.TransportBlock>);
- ctor public TransportDiscoveryData(@NonNull byte[]);
- method public int describeContents();
- method @NonNull public java.util.List<android.bluetooth.le.TransportBlock> getTransportBlocks();
- method public int getTransportDataType();
- method @Nullable public byte[] toByteArray();
- method public int totalBytes();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.TransportDiscoveryData> CREATOR;
- }
-
-}
-
package android.companion {
public final class AssociationInfo implements android.os.Parcelable {
@@ -13575,6 +12216,7 @@
}
public final class ShortcutInfo implements android.os.Parcelable {
+ method @NonNull public static android.content.pm.ShortcutInfo createFromGenericDocument(@NonNull android.content.Context, @NonNull android.app.appsearch.GenericDocument);
method public int describeContents();
method @Nullable public android.content.ComponentName getActivity();
method @NonNull public java.util.List<java.lang.String> getCapabilityParameterValues(@NonNull String, @NonNull String);
@@ -19930,7 +18572,6 @@
public abstract class AbstractInputMethodService extends android.app.Service implements android.view.KeyEvent.Callback {
ctor public AbstractInputMethodService();
method public android.view.KeyEvent.DispatcherState getKeyDispatcherState();
- method public final boolean isUiContext();
method public final android.os.IBinder onBind(android.content.Intent);
method public abstract android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodImpl onCreateInputMethodInterface();
method public abstract android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface();
@@ -22615,12 +21256,14 @@
field @Deprecated public static final int COLOR_FormatYUV422SemiPlanar = 24; // 0x18
field public static final int COLOR_FormatYUV444Flexible = 2135181448; // 0x7f444888
field @Deprecated public static final int COLOR_FormatYUV444Interleaved = 29; // 0x1d
+ field public static final int COLOR_FormatYUVP010 = 54; // 0x36
field @Deprecated public static final int COLOR_QCOM_FormatYUV420SemiPlanar = 2141391872; // 0x7fa30c00
field @Deprecated public static final int COLOR_TI_FormatYUV420PackedSemiPlanar = 2130706688; // 0x7f000100
field public static final String FEATURE_AdaptivePlayback = "adaptive-playback";
field public static final String FEATURE_DynamicTimestamp = "dynamic-timestamp";
field public static final String FEATURE_EncodingStatistics = "encoding-statistics";
field public static final String FEATURE_FrameParsing = "frame-parsing";
+ field public static final String FEATURE_HdrEditing = "hdr-editing";
field public static final String FEATURE_IntraRefresh = "intra-refresh";
field public static final String FEATURE_LowLatency = "low-latency";
field public static final String FEATURE_MultipleFrames = "multiple-frames";
@@ -24574,6 +23217,7 @@
method public static android.net.Uri getValidRingtoneUri(android.content.Context);
method public boolean hasHapticChannels(int);
method public static boolean hasHapticChannels(@NonNull android.net.Uri);
+ method public static boolean hasHapticChannels(@NonNull android.content.Context, @NonNull android.net.Uri);
method public int inferStreamType();
method public static boolean isDefault(android.net.Uri);
method @Nullable public static android.content.res.AssetFileDescriptor openDefaultRingtoneUri(@NonNull android.content.Context, @NonNull android.net.Uri) throws java.io.FileNotFoundException;
@@ -26249,6 +24893,37 @@
package android.media.tv {
+ public final class AdRequest implements android.os.Parcelable {
+ ctor public AdRequest(int, int, @Nullable android.os.ParcelFileDescriptor, long, long, long, @Nullable String, @NonNull android.os.Bundle);
+ method public int describeContents();
+ method public long getEchoIntervalMillis();
+ method @Nullable public android.os.ParcelFileDescriptor getFileDescriptor();
+ method public int getId();
+ method @Nullable public String getMediaFileType();
+ method @NonNull public android.os.Bundle getMetadata();
+ method public int getRequestType();
+ method public long getStartTimeMillis();
+ method public long getStopTimeMillis();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.media.tv.AdRequest> CREATOR;
+ field public static final int REQUEST_TYPE_START = 1; // 0x1
+ field public static final int REQUEST_TYPE_STOP = 2; // 0x2
+ }
+
+ public final class AdResponse implements android.os.Parcelable {
+ ctor public AdResponse(int, int, long);
+ method public int describeContents();
+ method public long getElapsedTimeMillis();
+ method public int getId();
+ method public int getResponseType();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.media.tv.AdResponse> CREATOR;
+ field public static final int RESPONSE_TYPE_ERROR = 4; // 0x4
+ field public static final int RESPONSE_TYPE_FINISHED = 2; // 0x2
+ field public static final int RESPONSE_TYPE_PLAYING = 1; // 0x1
+ field public static final int RESPONSE_TYPE_STOPPED = 3; // 0x3
+ }
+
public final class AitInfo implements android.os.Parcelable {
ctor public AitInfo(int, int);
method public int describeContents();
@@ -26751,6 +25426,9 @@
field public static final int RECORDING_ERROR_INSUFFICIENT_SPACE = 1; // 0x1
field public static final int RECORDING_ERROR_RESOURCE_BUSY = 2; // 0x2
field public static final int RECORDING_ERROR_UNKNOWN = 0; // 0x0
+ field public static final int SIGNAL_STRENGTH_LOST = 1; // 0x1
+ field public static final int SIGNAL_STRENGTH_STRONG = 3; // 0x3
+ field public static final int SIGNAL_STRENGTH_WEAK = 2; // 0x2
field public static final long TIME_SHIFT_INVALID_TIME = -9223372036854775808L; // 0x8000000000000000L
field public static final int TIME_SHIFT_STATUS_AVAILABLE = 3; // 0x3
field public static final int TIME_SHIFT_STATUS_UNAVAILABLE = 2; // 0x2
@@ -26828,10 +25506,12 @@
public abstract static class TvInputService.Session implements android.view.KeyEvent.Callback {
ctor public TvInputService.Session(android.content.Context);
method public void layoutSurface(int, int, int, int);
+ method public void notifyAdResponse(@NonNull android.media.tv.AdResponse);
method public void notifyAitInfoUpdated(@NonNull android.media.tv.AitInfo);
method public void notifyChannelRetuned(android.net.Uri);
method public void notifyContentAllowed();
method public void notifyContentBlocked(@NonNull android.media.tv.TvContentRating);
+ method public void notifySignalStrength(int);
method public void notifyTimeShiftStatusChanged(int);
method public void notifyTrackSelected(int, String);
method public void notifyTracksChanged(java.util.List<android.media.tv.TvTrackInfo>);
@@ -26847,6 +25527,7 @@
method public boolean onKeyUp(int, android.view.KeyEvent);
method public void onOverlayViewSizeChanged(int, int);
method public abstract void onRelease();
+ method public void onRequestAd(@NonNull android.media.tv.AdRequest);
method public boolean onSelectTrack(int, @Nullable String);
method public abstract void onSetCaptionEnabled(boolean);
method public void onSetInteractiveAppNotificationEnabled(boolean);
@@ -26984,9 +25665,11 @@
method public void onContentAllowed(String);
method public void onContentBlocked(String, android.media.tv.TvContentRating);
method public void onDisconnected(String);
+ method public void onSignalStrength(@NonNull String, int);
method public void onTimeShiftStatusChanged(String, int);
method public void onTrackSelected(String, int, String);
method public void onTracksChanged(String, java.util.List<android.media.tv.TvTrackInfo>);
+ method public void onTuned(@NonNull String, @NonNull android.net.Uri);
method public void onVideoAvailable(String);
method public void onVideoSizeChanged(String, int, int);
method public void onVideoUnavailable(String, int);
@@ -27011,8 +25694,11 @@
public final class TvInteractiveAppManager {
method @NonNull public java.util.List<android.media.tv.interactive.TvInteractiveAppInfo> getTvInteractiveAppServiceList();
+ method public void prepare(@NonNull String, int);
method public void registerCallback(@NonNull android.media.tv.interactive.TvInteractiveAppManager.TvInteractiveAppCallback, @NonNull java.util.concurrent.Executor);
+ method public void sendAppLinkCommand(@NonNull String, @NonNull android.os.Bundle);
method public void unregisterCallback(@NonNull android.media.tv.interactive.TvInteractiveAppManager.TvInteractiveAppCallback);
+ field public static final String ACTION_APP_LINK_COMMAND = "android.media.tv.interactive.action.APP_LINK_COMMAND";
field public static final int ERROR_BLOCKED = 5; // 0x5
field public static final int ERROR_ENCRYPTED = 6; // 0x6
field public static final int ERROR_NONE = 0; // 0x0
@@ -27021,26 +25707,55 @@
field public static final int ERROR_UNKNOWN = 1; // 0x1
field public static final int ERROR_UNKNOWN_CHANNEL = 7; // 0x7
field public static final int ERROR_WEAK_SIGNAL = 3; // 0x3
+ field public static final String INTENT_KEY_BI_INTERACTIVE_APP_TYPE = "bi_interactive_app_type";
+ field public static final String INTENT_KEY_BI_INTERACTIVE_APP_URI = "bi_interactive_app_uri";
+ field public static final String INTENT_KEY_CHANNEL_URI = "channel_uri";
+ field public static final String INTENT_KEY_INTERACTIVE_APP_SERVICE_ID = "interactive_app_id";
+ field public static final String INTENT_KEY_TV_INPUT_ID = "tv_input_id";
field public static final int INTERACTIVE_APP_STATE_ERROR = 3; // 0x3
field public static final int INTERACTIVE_APP_STATE_RUNNING = 2; // 0x2
field public static final int INTERACTIVE_APP_STATE_STOPPED = 1; // 0x1
+ field public static final String KEY_BACK_URI = "back_uri";
+ field public static final String KEY_CLASS_NAME = "class_name";
+ field public static final String KEY_COMMAND_TYPE = "command_type";
+ field public static final String KEY_PACKAGE_NAME = "package_name";
+ field public static final String KEY_SERVICE_ID = "service_id";
field public static final int SERVICE_STATE_ERROR = 4; // 0x4
field public static final int SERVICE_STATE_PREPARING = 2; // 0x2
field public static final int SERVICE_STATE_READY = 3; // 0x3
field public static final int SERVICE_STATE_UNREALIZED = 1; // 0x1
+ field public static final int TELETEXT_APP_STATE_ERROR = 3; // 0x3
+ field public static final int TELETEXT_APP_STATE_HIDE = 2; // 0x2
+ field public static final int TELETEXT_APP_STATE_SHOW = 1; // 0x1
}
public abstract static class TvInteractiveAppManager.TvInteractiveAppCallback {
ctor public TvInteractiveAppManager.TvInteractiveAppCallback();
+ method public void onInteractiveAppServiceAdded(@NonNull String);
+ method public void onInteractiveAppServiceRemoved(@NonNull String);
+ method public void onInteractiveAppServiceUpdated(@NonNull String);
method public void onTvInteractiveAppServiceStateChanged(@NonNull String, int, int, int);
}
public abstract class TvInteractiveAppService extends android.app.Service {
ctor public TvInteractiveAppService();
method public final void notifyStateChanged(int, int, int);
- method public final android.os.IBinder onBind(android.content.Intent);
+ method public void onAppLinkCommand(@NonNull android.os.Bundle);
+ method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
method @Nullable public abstract android.media.tv.interactive.TvInteractiveAppService.Session onCreateSession(@NonNull String, int);
method public abstract void onPrepare(int);
+ field public static final String COMMAND_PARAMETER_KEY_CHANGE_CHANNEL_QUIETLY = "command_change_channel_quietly";
+ field public static final String COMMAND_PARAMETER_KEY_CHANNEL_URI = "command_channel_uri";
+ field public static final String COMMAND_PARAMETER_KEY_INPUT_ID = "command_input_id";
+ field public static final String COMMAND_PARAMETER_KEY_TRACK_ID = "command_track_id";
+ field public static final String COMMAND_PARAMETER_KEY_TRACK_TYPE = "command_track_type";
+ field public static final String COMMAND_PARAMETER_KEY_VOLUME = "command_volume";
+ field public static final String PLAYBACK_COMMAND_TYPE_SELECT_TRACK = "select_track";
+ field public static final String PLAYBACK_COMMAND_TYPE_SET_STREAM_VOLUME = "set_stream_volume";
+ field public static final String PLAYBACK_COMMAND_TYPE_STOP = "stop";
+ field public static final String PLAYBACK_COMMAND_TYPE_TUNE = "tune";
+ field public static final String PLAYBACK_COMMAND_TYPE_TUNE_NEXT = "tune_next";
+ field public static final String PLAYBACK_COMMAND_TYPE_TUNE_PREV = "tune_previous";
field public static final String SERVICE_INTERFACE = "android.media.tv.interactive.TvInteractiveAppService";
field public static final String SERVICE_META_DATA = "android.media.tv.interactive.app";
}
@@ -27050,17 +25765,48 @@
method public void layoutSurface(int, int, int, int);
method public final void notifyBiInteractiveAppCreated(@NonNull android.net.Uri, @Nullable String);
method public void notifySessionStateChanged(int, int);
+ method public final void notifyTeletextAppStateChanged(int);
+ method public void onAdResponse(@NonNull android.media.tv.AdResponse);
+ method public void onContentAllowed();
+ method public void onContentBlocked(@NonNull android.media.tv.TvContentRating);
method public void onCreateBiInteractiveApp(@NonNull android.net.Uri, @Nullable android.os.Bundle);
+ method @Nullable public android.view.View onCreateMediaView();
+ method public void onCurrentChannelLcn(int);
+ method public void onCurrentChannelUri(@Nullable android.net.Uri);
+ method public void onCurrentTvInputId(@Nullable String);
method public void onDestroyBiInteractiveApp(@NonNull String);
+ method public boolean onGenericMotionEvent(@NonNull android.view.MotionEvent);
method public boolean onKeyDown(int, @NonNull android.view.KeyEvent);
method public boolean onKeyLongPress(int, @NonNull android.view.KeyEvent);
method public boolean onKeyMultiple(int, int, @NonNull android.view.KeyEvent);
method public boolean onKeyUp(int, @NonNull android.view.KeyEvent);
+ method public void onMediaViewSizeChanged(int, int);
+ method public abstract void onRelease();
+ method public void onResetInteractiveApp();
method public abstract boolean onSetSurface(@Nullable android.view.Surface);
+ method public void onSetTeletextAppEnabled(boolean);
+ method public void onSignalStrength(int);
method public void onStartInteractiveApp();
method public void onStopInteractiveApp();
+ method public void onStreamVolume(float);
method public void onSurfaceChanged(int, int, int);
+ method public boolean onTouchEvent(@NonNull android.view.MotionEvent);
+ method public void onTrackInfoList(@NonNull java.util.List<android.media.tv.TvTrackInfo>);
+ method public void onTrackSelected(int, @NonNull String);
+ method public boolean onTrackballEvent(@NonNull android.view.MotionEvent);
+ method public void onTracksChanged(@NonNull java.util.List<android.media.tv.TvTrackInfo>);
method public void onTuned(@NonNull android.net.Uri);
+ method public void onVideoAvailable();
+ method public void onVideoUnavailable(int);
+ method public void requestAd(@NonNull android.media.tv.AdRequest);
+ method public void requestCurrentChannelLcn();
+ method public void requestCurrentChannelUri();
+ method public void requestCurrentTvInputId();
+ method public void requestStreamVolume();
+ method public void requestTrackInfoList();
+ method public void sendPlaybackCommandRequest(@NonNull String, @Nullable android.os.Bundle);
+ method public void setMediaViewEnabled(boolean);
+ method public void setVideoBounds(@NonNull android.graphics.Rect);
}
public class TvInteractiveAppView extends android.view.ViewGroup {
@@ -27068,19 +25814,48 @@
ctor public TvInteractiveAppView(@NonNull android.content.Context, @Nullable android.util.AttributeSet);
ctor public TvInteractiveAppView(@NonNull android.content.Context, @Nullable android.util.AttributeSet, int);
method public void clearCallback();
+ method public void clearOnUnhandledInputEventListener();
method public void createBiInteractiveApp(@NonNull android.net.Uri, @Nullable android.os.Bundle);
method public void destroyBiInteractiveApp(@NonNull String);
+ method public boolean dispatchUnhandledInputEvent(@NonNull android.view.InputEvent);
+ method public void onAttachedToWindow();
+ method public void onDetachedFromWindow();
+ method public void onLayout(boolean, int, int, int, int);
+ method public void onMeasure(int, int);
+ method public boolean onUnhandledInputEvent(@NonNull android.view.InputEvent);
+ method public void onVisibilityChanged(@NonNull android.view.View, int);
method public void prepareInteractiveApp(@NonNull String, int);
+ method public void reset();
+ method public void resetInteractiveApp();
+ method public void sendCurrentChannelLcn(int);
+ method public void sendCurrentChannelUri(@Nullable android.net.Uri);
+ method public void sendCurrentTvInputId(@Nullable String);
+ method public void sendStreamVolume(float);
+ method public void sendTrackInfoList(@Nullable java.util.List<android.media.tv.TvTrackInfo>);
method public void setCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.tv.interactive.TvInteractiveAppView.TvInteractiveAppCallback);
+ method public void setOnUnhandledInputEventListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.tv.interactive.TvInteractiveAppView.OnUnhandledInputEventListener);
+ method public void setTeletextAppEnabled(boolean);
method public int setTvView(@Nullable android.media.tv.TvView);
method public void startInteractiveApp();
method public void stopInteractiveApp();
}
+ public static interface TvInteractiveAppView.OnUnhandledInputEventListener {
+ method public boolean onUnhandledInputEvent(@NonNull android.view.InputEvent);
+ }
+
public abstract static class TvInteractiveAppView.TvInteractiveAppCallback {
ctor public TvInteractiveAppView.TvInteractiveAppCallback();
method public void onBiInteractiveAppCreated(@NonNull String, @NonNull android.net.Uri, @Nullable String);
+ method public void onPlaybackCommandRequest(@NonNull String, @NonNull String, @NonNull android.os.Bundle);
+ method public void onRequestCurrentChannelLcn(@NonNull String);
+ method public void onRequestCurrentChannelUri(@NonNull String);
+ method public void onRequestCurrentTvInputId(@NonNull String);
+ method public void onRequestStreamVolume(@NonNull String);
+ method public void onRequestTrackInfoList(@NonNull String);
+ method public void onSetVideoBounds(@NonNull String, @NonNull android.graphics.Rect);
method public void onStateChanged(@NonNull String, int, int);
+ method public void onTeletextAppStateChanged(@NonNull String, int);
}
}
@@ -31645,6 +30420,7 @@
field public static final int BATTERY_HEALTH_UNKNOWN = 1; // 0x1
field public static final int BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6; // 0x6
field public static final int BATTERY_PLUGGED_AC = 1; // 0x1
+ field public static final int BATTERY_PLUGGED_DOCK = 8; // 0x8
field public static final int BATTERY_PLUGGED_USB = 2; // 0x2
field public static final int BATTERY_PLUGGED_WIRELESS = 4; // 0x4
field public static final int BATTERY_PROPERTY_CAPACITY = 4; // 0x4
@@ -33152,6 +31928,9 @@
method public static android.os.VibrationEffect createWaveform(long[], int[], int);
method public int describeContents();
method @NonNull public static android.os.VibrationEffect.Composition startComposition();
+ method @NonNull public static android.os.VibrationEffect.WaveformBuilder startWaveform();
+ method @NonNull public static android.os.VibrationEffect.WaveformBuilder startWaveform(@NonNull android.os.VibrationEffect.VibrationParameter);
+ method @NonNull public static android.os.VibrationEffect.WaveformBuilder startWaveform(@NonNull android.os.VibrationEffect.VibrationParameter, @NonNull android.os.VibrationEffect.VibrationParameter);
field @NonNull public static final android.os.Parcelable.Creator<android.os.VibrationEffect> CREATOR;
field public static final int DEFAULT_AMPLITUDE = -1; // 0xffffffff
field public static final int EFFECT_CLICK = 0; // 0x0
@@ -33161,10 +31940,13 @@
}
public static final class VibrationEffect.Composition {
+ method @NonNull public android.os.VibrationEffect.Composition addEffect(@NonNull android.os.VibrationEffect);
+ method @NonNull public android.os.VibrationEffect.Composition addOffDuration(@NonNull java.time.Duration);
method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int);
method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int, @FloatRange(from=0.0f, to=1.0f) float);
method @NonNull public android.os.VibrationEffect.Composition addPrimitive(int, @FloatRange(from=0.0f, to=1.0f) float, @IntRange(from=0) int);
method @NonNull public android.os.VibrationEffect compose();
+ method @NonNull public android.os.VibrationEffect.Composition repeatEffectIndefinitely(@NonNull android.os.VibrationEffect);
field public static final int PRIMITIVE_CLICK = 1; // 0x1
field public static final int PRIMITIVE_LOW_TICK = 8; // 0x8
field public static final int PRIMITIVE_QUICK_FALL = 6; // 0x6
@@ -33175,6 +31957,21 @@
field public static final int PRIMITIVE_TICK = 7; // 0x7
}
+ public static final class VibrationEffect.Composition.UnreachableAfterRepeatingIndefinitelyException extends java.lang.IllegalStateException {
+ }
+
+ public static class VibrationEffect.VibrationParameter {
+ method @NonNull public static android.os.VibrationEffect.VibrationParameter targetAmplitude(@FloatRange(from=0, to=1) float);
+ method @NonNull public static android.os.VibrationEffect.VibrationParameter targetFrequency(@FloatRange(from=1) float);
+ }
+
+ public static final class VibrationEffect.WaveformBuilder {
+ method @NonNull public android.os.VibrationEffect.WaveformBuilder addSustain(@NonNull java.time.Duration);
+ method @NonNull public android.os.VibrationEffect.WaveformBuilder addTransition(@NonNull java.time.Duration, @NonNull android.os.VibrationEffect.VibrationParameter);
+ method @NonNull public android.os.VibrationEffect.WaveformBuilder addTransition(@NonNull java.time.Duration, @NonNull android.os.VibrationEffect.VibrationParameter, @NonNull android.os.VibrationEffect.VibrationParameter);
+ method @NonNull public android.os.VibrationEffect build();
+ }
+
public abstract class Vibrator {
method public final int areAllEffectsSupported(@NonNull int...);
method public final boolean areAllPrimitivesSupported(@NonNull int...);
@@ -41404,8 +40201,10 @@
field public static final int CAPABILITY_SELF_MANAGED = 2048; // 0x800
field public static final int CAPABILITY_SIM_SUBSCRIPTION = 4; // 0x4
field public static final int CAPABILITY_SUPPORTS_VIDEO_CALLING = 1024; // 0x400
+ field public static final int CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS = 65536; // 0x10000
field public static final int CAPABILITY_VIDEO_CALLING = 8; // 0x8
field public static final int CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE = 256; // 0x100
+ field public static final int CAPABILITY_VOICE_CALLING_AVAILABLE = 131072; // 0x20000
field @NonNull public static final android.os.Parcelable.Creator<android.telecom.PhoneAccount> CREATOR;
field public static final String EXTRA_ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE = "android.telecom.extra.ADD_SELF_MANAGED_CALLS_TO_INCALLSERVICE";
field public static final String EXTRA_ALWAYS_USE_VOIP_AUDIO_MODE = "android.telecom.extra.ALWAYS_USE_VOIP_AUDIO_MODE";
@@ -42345,6 +41144,7 @@
field public static final String KEY_SIP_TIMER_T1_MILLIS_INT = "ims.sip_timer_t1_millis_int";
field public static final String KEY_SIP_TIMER_T2_MILLIS_INT = "ims.sip_timer_t2_millis_int";
field public static final String KEY_SIP_TIMER_T4_MILLIS_INT = "ims.sip_timer_t4_millis_int";
+ field public static final String KEY_SUPPORTED_RATS_INT_ARRAY = "ims.supported_rats_int_array";
field public static final String KEY_WIFI_OFF_DEFERRING_TIME_MILLIS_INT = "ims.wifi_off_deferring_time_millis_int";
field public static final int NETWORK_TYPE_HOME = 0; // 0x0
field public static final int NETWORK_TYPE_ROAMING = 1; // 0x1
@@ -42365,6 +41165,7 @@
field public static final String KEY_EMERGENCY_QOS_PRECONDITION_SUPPORTED_BOOL = "imsemergency.emergency_qos_precondition_supported_bool";
field public static final String KEY_EMERGENCY_REGISTRATION_TIMER_MILLIS_INT = "imsemergency.emergency_registration_timer_millis_int";
field public static final String KEY_PREFIX = "imsemergency.";
+ field public static final String KEY_REFRESH_GEOLOCATION_TIMEOUT_MILLIS_INT = "imsemergency.refresh_geolocation_timeout_millis_int";
field public static final String KEY_RETRY_EMERGENCY_ON_IMS_PDN_BOOL = "imsemergency.retry_emergency_on_ims_pdn_bool";
}
@@ -42374,7 +41175,6 @@
field public static final String KEY_T140_PAYLOAD_TYPE_INT = "imsrtt.t140_payload_type_int";
field public static final String KEY_TEXT_AS_BANDWIDTH_KBPS_INT = "imsrtt.text_as_bandwidth_kbps_int";
field public static final String KEY_TEXT_CODEC_CAPABILITY_PAYLOAD_TYPES_BUNDLE = "imsrtt.text_codec_capability_payload_types_bundle";
- field public static final String KEY_TEXT_INACTIVITY_CALL_END_REASONS_INT_ARRAY = "imsrtt.text_inactivity_call_end_reasons_int_array";
field public static final String KEY_TEXT_ON_DEFAULT_BEARER_SUPPORTED_BOOL = "imsrtt.text_on_default_bearer_supported_bool";
field public static final String KEY_TEXT_QOS_PRECONDITION_SUPPORTED_BOOL = "imsrtt.text_qos_precondition_supported_bool";
field public static final String KEY_TEXT_RR_BANDWIDTH_BPS_INT = "imsrtt.text_rr_bandwidth_bps_int";
@@ -42410,6 +41210,7 @@
field public static final String KEY_UT_REQUIRES_IMS_REGISTRATION_BOOL = "imsss.ut_requires_ims_registration_bool";
field public static final String KEY_UT_SERVER_BASED_SERVICES_INT_ARRAY = "imsss.ut_server_based_services_int_array";
field public static final String KEY_UT_SUPPORTED_WHEN_PS_DATA_OFF_BOOL = "imsss.ut_supported_when_ps_data_off_bool";
+ field public static final String KEY_UT_SUPPORTED_WHEN_ROAMING_BOOL = "imsss.ut_supported_when_roaming_bool";
field public static final String KEY_UT_TERMINAL_BASED_SERVICES_INT_ARRAY = "imsss.ut_terminal_based_services_int_array";
field public static final String KEY_UT_TRANSPORT_TYPE_INT = "imsss.ut_transport_type_int";
field public static final String KEY_XCAP_OVER_UT_SUPPORTED_RATS_INT_ARRAY = "imsss.xcap_over_ut_supported_rats_int_array";
@@ -42509,6 +41310,7 @@
field public static final String KEY_RINGBACK_TIMER_MILLIS_INT = "imsvoice.ringback_timer_millis_int";
field public static final String KEY_RINGING_TIMER_MILLIS_INT = "imsvoice.ringing_timer_millis_int";
field public static final String KEY_SESSION_EXPIRES_TIMER_SEC_INT = "imsvoice.session_expires_timer_sec_int";
+ field public static final String KEY_SESSION_PRIVACY_TYPE_INT = "imsvoice.session_privacy_type_int";
field public static final String KEY_SESSION_REFRESHER_TYPE_INT = "imsvoice.session_refresher_type_int";
field public static final String KEY_SESSION_REFRESH_METHOD_INT = "imsvoice.session_refresh_method_int";
field public static final String KEY_SESSION_TIMER_SUPPORTED_BOOL = "imsvoice.session_timer_supported_bool";
@@ -42518,6 +41320,9 @@
field public static final int MIDCALL_SRVCC_SUPPORT = 3; // 0x3
field public static final int OCTET_ALIGNED = 1; // 0x1
field public static final int PREALERTING_SRVCC_SUPPORT = 2; // 0x2
+ field public static final int SESSION_PRIVACY_TYPE_HEADER = 0; // 0x0
+ field public static final int SESSION_PRIVACY_TYPE_ID = 2; // 0x2
+ field public static final int SESSION_PRIVACY_TYPE_NONE = 1; // 0x1
field public static final int SESSION_REFRESHER_TYPE_UAC = 1; // 0x1
field public static final int SESSION_REFRESHER_TYPE_UAS = 2; // 0x2
field public static final int SESSION_REFRESHER_TYPE_UNKNOWN = 0; // 0x0
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index ee31e13..6c2db43 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -63,8 +63,8 @@
public class DevicePolicyManager {
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void acknowledgeNewUserDisclaimer();
- method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void clearLogoutUser();
- method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.os.UserHandle getLogoutUser();
+ method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}) public android.os.UserHandle getLogoutUser();
+ method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public int logoutUser();
field public static final String ACTION_SHOW_NEW_USER_DISCLAIMER = "android.app.action.SHOW_NEW_USER_DISCLAIMER";
}
@@ -93,20 +93,6 @@
}
-package android.bluetooth {
-
- public class BluetoothFrameworkInitializer {
- method public static void registerServiceWrappers();
- method public static void setBinderCallsStatsInitializer(@NonNull java.util.function.Consumer<android.content.Context>);
- method public static void setBluetoothServiceManager(@NonNull android.os.BluetoothServiceManager);
- }
-
- public final class BluetoothPan implements android.bluetooth.BluetoothProfile {
- method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.TETHER_PRIVILEGED}) public android.net.TetheringManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.TetheredInterfaceCallback);
- }
-
-}
-
package android.content {
public abstract class ContentProvider implements android.content.ComponentCallbacks2 {
@@ -384,6 +370,7 @@
method public int getRoaming();
method @NonNull public java.util.Set<java.lang.String> getSubscriberIds();
method @NonNull public java.util.Set<java.lang.String> getWifiNetworkKeys();
+ method public boolean matches(@NonNull android.net.NetworkIdentity);
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkTemplate> CREATOR;
field public static final int MATCH_BLUETOOTH = 8; // 0x8
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 5e23229..55a6df2 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -744,6 +744,7 @@
method public void clearRequireCompatChange();
method public boolean isPendingIntentBackgroundActivityLaunchAllowed();
method public static android.app.BroadcastOptions makeBasic();
+ method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void recordResponseEventWhileInBackground(@IntRange(from=0) long);
method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean);
method public void setDontSendToRestrictedApps(boolean);
method public void setPendingIntentBackgroundActivityLaunchAllowed(boolean);
@@ -2257,475 +2258,6 @@
}
-package android.bluetooth {
-
- public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile {
- method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BufferConstraints getBufferConstraints();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getDynamicBufferSupport();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setBufferLengthMillis(int, int);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- field public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD = 1; // 0x1
- field public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING = 2; // 0x2
- field public static final int DYNAMIC_BUFFER_SUPPORT_NONE = 0; // 0x0
- field public static final int OPTIONAL_CODECS_NOT_SUPPORTED = 0; // 0x0
- field public static final int OPTIONAL_CODECS_PREF_DISABLED = 0; // 0x0
- field public static final int OPTIONAL_CODECS_PREF_ENABLED = 1; // 0x1
- field public static final int OPTIONAL_CODECS_PREF_UNKNOWN = -1; // 0xffffffff
- field public static final int OPTIONAL_CODECS_SUPPORTED = 1; // 0x1
- field public static final int OPTIONAL_CODECS_SUPPORT_UNKNOWN = -1; // 0xffffffff
- }
-
- public final class BluetoothA2dpSink implements android.bluetooth.BluetoothProfile {
- method public void finalize();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean isAudioPlaying(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED";
- }
-
- public final class BluetoothActivityEnergyInfo implements android.os.Parcelable {
- method public int getBluetoothStackState();
- method public long getControllerEnergyUsed();
- method public long getControllerIdleTimeMillis();
- method public long getControllerRxTimeMillis();
- method public long getControllerTxTimeMillis();
- method public long getTimestampMillis();
- method @NonNull public java.util.List<android.bluetooth.UidTraffic> getUidTraffic();
- method public boolean isValid();
- field public static final int BT_STACK_STATE_INVALID = 0; // 0x0
- field public static final int BT_STACK_STATE_STATE_ACTIVE = 1; // 0x1
- field public static final int BT_STACK_STATE_STATE_IDLE = 3; // 0x3
- field public static final int BT_STACK_STATE_STATE_SCANNING = 2; // 0x2
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothActivityEnergyInfo> CREATOR;
- }
-
- public final class BluetoothAdapter {
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean addOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean disable(boolean);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disableBLE();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean enableBLE();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean enableNoAutoConnect();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void generateLocalOobData(int, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OobDataCallback);
- method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getActiveDevices(int);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public long getDiscoveryEndMillis();
- method public boolean isBleScanAlwaysAvailable();
- method public boolean isLeEnabled();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean removeActiveDevice(int);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean removeOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean setActiveDevice(@NonNull android.bluetooth.BluetoothDevice, int);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int setDiscoverableTimeout(@NonNull java.time.Duration);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int 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 {
- method public void onMetadataChanged(@NonNull android.bluetooth.BluetoothDevice, int, @Nullable byte[]);
- }
-
- public static interface BluetoothAdapter.OobDataCallback {
- method public void onError(int);
- method public void onOobData(int, @NonNull android.bluetooth.OobData);
- }
-
- public final class BluetoothClass implements android.os.Parcelable {
- field public static final int PROFILE_A2DP_SINK = 6; // 0x6
- field public static final int PROFILE_NAP = 5; // 0x5
- field public static final int PROFILE_OPP = 2; // 0x2
- field public static final int PROFILE_PANU = 4; // 0x4
- }
-
- public final class BluetoothCsipSetCoordinator implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
- method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.List<java.lang.Integer> getAllGroupIds(@Nullable android.os.ParcelUuid);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice);
- method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.Map getGroupUuidMapByDevice(@Nullable android.bluetooth.BluetoothDevice);
- method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.UUID groupLock(int, @Nullable java.util.concurrent.Executor, @Nullable android.bluetooth.BluetoothCsipSetCoordinator.ClientLockCallback);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean groupUnlock(@NonNull java.util.UUID);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@Nullable android.bluetooth.BluetoothDevice, int);
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static final String ACTION_CSIS_DEVICE_AVAILABLE = "android.bluetooth.action.CSIS_DEVICE_AVAILABLE";
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public static final String ACTION_CSIS_SET_MEMBER_AVAILABLE = "android.bluetooth.action.CSIS_SET_MEMBER_AVAILABLE";
- }
-
- public static interface BluetoothCsipSetCoordinator.ClientLockCallback {
- method public void onGroupLockSet(int, int, boolean);
- }
-
- public final class BluetoothDevice implements android.os.Parcelable {
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean canBondWithoutDialog();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean cancelBondProcess();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public int connect();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBond(int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean createBondOutOfBand(int, @Nullable android.bluetooth.OobData, @Nullable android.bluetooth.OobData);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int disconnect();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean fetchUuidsWithSdp(int);
- method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public byte[] getMetadata(int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getSimAccessPermission();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isConnected();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isEncrypted();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean isInSilenceMode();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean removeBond();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setLowLatencyAudioAllowed(boolean);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setMessageAccessPermission(int);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setMetadata(int, @NonNull byte[]);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setPhonebookAccessPermission(int);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setSilenceMode(boolean);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setSimAccessPermission(int);
- field public static final int ACCESS_ALLOWED = 1; // 0x1
- field public static final int ACCESS_REJECTED = 2; // 0x2
- field public static final int ACCESS_UNKNOWN = 0; // 0x0
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_SILENCE_MODE_CHANGED = "android.bluetooth.device.action.SILENCE_MODE_CHANGED";
- field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_SWITCH_BUFFER_SIZE = "android.bluetooth.device.action.SWITCH_BUFFER_SIZE";
- field public static final String DEVICE_TYPE_DEFAULT = "Default";
- field public static final String DEVICE_TYPE_UNTETHERED_HEADSET = "Untethered Headset";
- field public static final String DEVICE_TYPE_WATCH = "Watch";
- field public static final String EXTRA_LOW_LATENCY_BUFFER_SIZE = "android.bluetooth.device.extra.LOW_LATENCY_BUFFER_SIZE";
- field public static final int METADATA_COMPANION_APP = 4; // 0x4
- field public static final int METADATA_DEVICE_TYPE = 17; // 0x11
- field public static final int METADATA_ENHANCED_SETTINGS_UI_URI = 16; // 0x10
- field public static final int METADATA_HARDWARE_VERSION = 3; // 0x3
- field public static final int METADATA_IS_UNTETHERED_HEADSET = 6; // 0x6
- field public static final int METADATA_MAIN_BATTERY = 18; // 0x12
- field public static final int METADATA_MAIN_CHARGING = 19; // 0x13
- field public static final int METADATA_MAIN_ICON = 5; // 0x5
- field public static final int METADATA_MAIN_LOW_BATTERY_THRESHOLD = 20; // 0x14
- field public static final int METADATA_MANUFACTURER_NAME = 0; // 0x0
- field public static final int METADATA_MAX_LENGTH = 2048; // 0x800
- field public static final int METADATA_MODEL_NAME = 1; // 0x1
- field public static final int METADATA_SOFTWARE_VERSION = 2; // 0x2
- field public static final int METADATA_UNTETHERED_CASE_BATTERY = 12; // 0xc
- field public static final int METADATA_UNTETHERED_CASE_CHARGING = 15; // 0xf
- field public static final int METADATA_UNTETHERED_CASE_ICON = 9; // 0x9
- field public static final int METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD = 23; // 0x17
- field public static final int METADATA_UNTETHERED_LEFT_BATTERY = 10; // 0xa
- field public static final int METADATA_UNTETHERED_LEFT_CHARGING = 13; // 0xd
- field public static final int METADATA_UNTETHERED_LEFT_ICON = 7; // 0x7
- field public static final int METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD = 21; // 0x15
- field public static final int METADATA_UNTETHERED_RIGHT_BATTERY = 11; // 0xb
- field public static final int METADATA_UNTETHERED_RIGHT_CHARGING = 14; // 0xe
- field public static final int METADATA_UNTETHERED_RIGHT_ICON = 8; // 0x8
- field public static final int METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD = 22; // 0x16
- }
-
- public final class BluetoothHeadset implements android.bluetooth.BluetoothProfile {
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean connect(android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int connectAudio();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean disconnect(android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int disconnectAudio();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getAudioState(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean isInbandRingingEnabled();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean startScoUsingVirtualVoiceCall();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.MODIFY_PHONE_STATE}) public boolean stopScoUsingVirtualVoiceCall();
- }
-
- public final class BluetoothHeadsetClient implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
- method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
- method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.headsetprofile.action.CONNECTION_STATE_CHANGED";
- }
-
- public final class BluetoothHearingAid implements android.bluetooth.BluetoothProfile {
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public long getHiSyncId(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- }
-
- public final class BluetoothHidDevice implements android.bluetooth.BluetoothProfile {
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- }
-
- public final class BluetoothHidHost implements android.bluetooth.BluetoothProfile {
- method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
- }
-
- public final class BluetoothLeAudio implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getAudioLocation(@NonNull android.bluetooth.BluetoothDevice);
- }
-
- public final class BluetoothMap implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
- method public void close();
- method protected void finalize();
- method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED";
- }
-
- public final class BluetoothMapClient implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
- method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
- method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.SEND_SMS}) public boolean sendMessage(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.Collection<android.net.Uri>, @NonNull String, @Nullable android.app.PendingIntent, @Nullable android.app.PendingIntent);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.mapmce.profile.action.CONNECTION_STATE_CHANGED";
- }
-
- public final class BluetoothPan implements android.bluetooth.BluetoothProfile {
- method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean isTetheringOn();
- method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED, android.Manifest.permission.TETHER_PRIVILEGED}) public void setBluetoothTethering(boolean);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED";
- field public static final String ACTION_TETHERING_STATE_CHANGED = "android.bluetooth.action.TETHERING_STATE_CHANGED";
- field public static final String EXTRA_LOCAL_ROLE = "android.bluetooth.pan.extra.LOCAL_ROLE";
- field public static final String EXTRA_TETHERING_STATE = "android.bluetooth.extra.TETHERING_STATE";
- field public static final int LOCAL_NAP_ROLE = 1; // 0x1
- field public static final int LOCAL_PANU_ROLE = 2; // 0x2
- field public static final int PAN_ROLE_NONE = 0; // 0x0
- field public static final int REMOTE_NAP_ROLE = 1; // 0x1
- field public static final int REMOTE_PANU_ROLE = 2; // 0x2
- field public static final int TETHERING_STATE_OFF = 1; // 0x1
- field public static final int TETHERING_STATE_ON = 2; // 0x2
- }
-
- public class BluetoothPbap implements android.bluetooth.BluetoothProfile {
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED";
- }
-
- public final class BluetoothPbapClient implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
- method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
- method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getDevicesMatchingConnectionStates(@NonNull int[]);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- field @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.pbapclient.profile.action.CONNECTION_STATE_CHANGED";
- }
-
- public interface BluetoothProfile {
- field public static final int A2DP_SINK = 11; // 0xb
- field public static final int AVRCP_CONTROLLER = 12; // 0xc
- 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 HEADSET_CLIENT = 16; // 0x10
- field public static final int MAP_CLIENT = 18; // 0x12
- field public static final int PAN = 5; // 0x5
- field public static final int PBAP_CLIENT = 17; // 0x11
- field @Deprecated public static final int PRIORITY_OFF = 0; // 0x0
- field @Deprecated public static final int PRIORITY_ON = 100; // 0x64
- field public static final int VOLUME_CONTROL = 23; // 0x17
- }
-
- public final class BluetoothStatusCodes {
- field public static final int ERROR_ANOTHER_ACTIVE_OOB_REQUEST = 1000; // 0x3e8
- field public static final int ERROR_AUDIO_DEVICE_ALREADY_CONNECTED = 1116; // 0x45c
- field public static final int ERROR_AUDIO_DEVICE_ALREADY_DISCONNECTED = 1117; // 0x45d
- field public static final int ERROR_AUDIO_ROUTE_BLOCKED = 1118; // 0x45e
- field public static final int ERROR_CALL_ACTIVE = 1119; // 0x45f
- field public static final int ERROR_NOT_ACTIVE_DEVICE = 12; // 0xc
- field public static final int ERROR_NO_ACTIVE_DEVICES = 13; // 0xd
- field public static final int ERROR_PROFILE_NOT_CONNECTED = 14; // 0xe
- field public static final int ERROR_TIMEOUT = 15; // 0xf
- }
-
- public final class BluetoothUuid {
- method public static boolean containsAnyUuid(@Nullable android.os.ParcelUuid[], @Nullable android.os.ParcelUuid[]);
- method @NonNull public static android.os.ParcelUuid parseUuidFrom(@Nullable byte[]);
- field @NonNull public static final android.os.ParcelUuid A2DP_SINK;
- field @NonNull public static final android.os.ParcelUuid A2DP_SOURCE;
- field @NonNull public static final android.os.ParcelUuid ADV_AUDIO_DIST;
- field @NonNull public static final android.os.ParcelUuid AVRCP_CONTROLLER;
- field @NonNull public static final android.os.ParcelUuid AVRCP_TARGET;
- field @NonNull public static final android.os.ParcelUuid BASE_UUID;
- field @NonNull public static final android.os.ParcelUuid BNEP;
- field @NonNull public static final android.os.ParcelUuid CAP;
- field @NonNull public static final android.os.ParcelUuid COORDINATED_SET;
- field @NonNull public static final android.os.ParcelUuid DIP;
- field @NonNull public static final android.os.ParcelUuid GENERIC_MEDIA_CONTROL;
- field @NonNull public static final android.os.ParcelUuid HAS;
- field @NonNull public static final android.os.ParcelUuid HEARING_AID;
- field @NonNull public static final android.os.ParcelUuid HFP;
- field @NonNull public static final android.os.ParcelUuid HFP_AG;
- field @NonNull public static final android.os.ParcelUuid HID;
- field @NonNull public static final android.os.ParcelUuid HOGP;
- field @NonNull public static final android.os.ParcelUuid HSP;
- field @NonNull public static final android.os.ParcelUuid HSP_AG;
- field @NonNull public static final android.os.ParcelUuid LE_AUDIO;
- field @NonNull public static final android.os.ParcelUuid MAP;
- field @NonNull public static final android.os.ParcelUuid MAS;
- field @NonNull public static final android.os.ParcelUuid MEDIA_CONTROL;
- field @NonNull public static final android.os.ParcelUuid MNS;
- field @NonNull public static final android.os.ParcelUuid NAP;
- field @NonNull public static final android.os.ParcelUuid OBEX_OBJECT_PUSH;
- field @NonNull public static final android.os.ParcelUuid PANU;
- field @NonNull public static final android.os.ParcelUuid PBAP_PCE;
- field @NonNull public static final android.os.ParcelUuid PBAP_PSE;
- field @NonNull public static final android.os.ParcelUuid SAP;
- field public static final int UUID_BYTES_128_BIT = 16; // 0x10
- field public static final int UUID_BYTES_16_BIT = 2; // 0x2
- field public static final int UUID_BYTES_32_BIT = 4; // 0x4
- field @NonNull public static final android.os.ParcelUuid VOLUME_CONTROL;
- }
-
- public final class BluetoothVolumeControl implements java.lang.AutoCloseable android.bluetooth.BluetoothProfile {
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void close();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) protected void finalize();
- method @NonNull @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void setVolume(@Nullable android.bluetooth.BluetoothDevice, @IntRange(from=0, to=255) int);
- field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.volume-control.profile.action.CONNECTION_STATE_CHANGED";
- }
-
- public final class BufferConstraint implements android.os.Parcelable {
- ctor public BufferConstraint(int, int, int);
- method public int describeContents();
- method public int getDefaultMillis();
- method public int getMaxMillis();
- method public int getMinMillis();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BufferConstraint> CREATOR;
- }
-
- public final class BufferConstraints implements android.os.Parcelable {
- ctor public BufferConstraints(@NonNull java.util.List<android.bluetooth.BufferConstraint>);
- method public int describeContents();
- method @Nullable public android.bluetooth.BufferConstraint forCodec(int);
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field public static final int BUFFER_CODEC_MAX_NUM = 32; // 0x20
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BufferConstraints> CREATOR;
- }
-
- public final class OobData implements android.os.Parcelable {
- method @NonNull public byte[] getClassOfDevice();
- method @NonNull public byte[] getClassicLength();
- method @NonNull public byte[] getConfirmationHash();
- method @NonNull public byte[] getDeviceAddressWithType();
- method @Nullable public byte[] getDeviceName();
- method @Nullable public byte[] getLeAppearance();
- method @NonNull public int getLeDeviceRole();
- method @NonNull public int getLeFlags();
- method @Nullable public byte[] getLeTemporaryKey();
- method @NonNull public byte[] getRandomizerHash();
- field public static final int CLASS_OF_DEVICE_OCTETS = 3; // 0x3
- field public static final int CONFIRMATION_OCTETS = 16; // 0x10
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.OobData> CREATOR;
- field public static final int DEVICE_ADDRESS_OCTETS = 7; // 0x7
- field public static final int LE_APPEARANCE_OCTETS = 2; // 0x2
- field public static final int LE_DEVICE_FLAG_OCTETS = 1; // 0x1
- field public static final int LE_DEVICE_ROLE_BOTH_PREFER_CENTRAL = 3; // 0x3
- field public static final int LE_DEVICE_ROLE_BOTH_PREFER_PERIPHERAL = 2; // 0x2
- field public static final int LE_DEVICE_ROLE_CENTRAL_ONLY = 1; // 0x1
- field public static final int LE_DEVICE_ROLE_OCTETS = 1; // 0x1
- field public static final int LE_DEVICE_ROLE_PERIPHERAL_ONLY = 0; // 0x0
- field public static final int LE_FLAG_BREDR_NOT_SUPPORTED = 2; // 0x2
- field public static final int LE_FLAG_GENERAL_DISCOVERY_MODE = 1; // 0x1
- field public static final int LE_FLAG_LIMITED_DISCOVERY_MODE = 0; // 0x0
- field public static final int LE_FLAG_SIMULTANEOUS_CONTROLLER = 3; // 0x3
- field public static final int LE_FLAG_SIMULTANEOUS_HOST = 4; // 0x4
- field public static final int LE_TK_OCTETS = 16; // 0x10
- field public static final int OOB_LENGTH_OCTETS = 2; // 0x2
- field public static final int RANDOMIZER_OCTETS = 16; // 0x10
- }
-
- public static final class OobData.ClassicBuilder {
- ctor public OobData.ClassicBuilder(@NonNull byte[], @NonNull byte[], @NonNull byte[]);
- method @NonNull public android.bluetooth.OobData build();
- method @NonNull public android.bluetooth.OobData.ClassicBuilder setClassOfDevice(@NonNull byte[]);
- method @NonNull public android.bluetooth.OobData.ClassicBuilder setDeviceName(@NonNull byte[]);
- method @NonNull public android.bluetooth.OobData.ClassicBuilder setRandomizerHash(@NonNull byte[]);
- }
-
- public static final class OobData.LeBuilder {
- ctor public OobData.LeBuilder(@NonNull byte[], @NonNull byte[], int);
- method @NonNull public android.bluetooth.OobData build();
- method @NonNull public android.bluetooth.OobData.LeBuilder setDeviceName(@NonNull byte[]);
- method @NonNull public android.bluetooth.OobData.LeBuilder setLeFlags(int);
- method @NonNull public android.bluetooth.OobData.LeBuilder setLeTemporaryKey(@NonNull byte[]);
- method @NonNull public android.bluetooth.OobData.LeBuilder setRandomizerHash(@NonNull byte[]);
- }
-
- public final class UidTraffic implements java.lang.Cloneable android.os.Parcelable {
- method public long getRxBytes();
- method public long getTxBytes();
- method public int getUid();
- field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.UidTraffic> CREATOR;
- }
-
-}
-
-package android.bluetooth.le {
-
- public final class AdvertiseSettings implements android.os.Parcelable {
- method public int getOwnAddressType();
- }
-
- public static final class AdvertiseSettings.Builder {
- method @NonNull public android.bluetooth.le.AdvertiseSettings.Builder setOwnAddressType(int);
- }
-
- public final class AdvertisingSetParameters implements android.os.Parcelable {
- method public int getOwnAddressType();
- field public static final int ADDRESS_TYPE_DEFAULT = -1; // 0xffffffff
- field public static final int ADDRESS_TYPE_PUBLIC = 0; // 0x0
- field public static final int ADDRESS_TYPE_RANDOM = 1; // 0x1
- }
-
- public static final class AdvertisingSetParameters.Builder {
- method @NonNull public android.bluetooth.le.AdvertisingSetParameters.Builder setOwnAddressType(int);
- }
-
- public final class BluetoothLeScanner {
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.UPDATE_DEVICE_STATS}) public void startScanFromSource(android.os.WorkSource, android.bluetooth.le.ScanCallback);
- method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.UPDATE_DEVICE_STATS}) public void startScanFromSource(java.util.List<android.bluetooth.le.ScanFilter>, android.bluetooth.le.ScanSettings, android.os.WorkSource, android.bluetooth.le.ScanCallback);
- method @Deprecated @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public void startTruncatedScan(java.util.List<android.bluetooth.le.TruncatedFilter>, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback);
- }
-
- @Deprecated public final class ResultStorageDescriptor implements android.os.Parcelable {
- ctor @Deprecated public ResultStorageDescriptor(int, int, int);
- method @Deprecated public int describeContents();
- method @Deprecated public int getLength();
- method @Deprecated public int getOffset();
- method @Deprecated public int getType();
- method @Deprecated public void writeToParcel(android.os.Parcel, int);
- field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.le.ResultStorageDescriptor> CREATOR;
- }
-
- public final class ScanFilter implements android.os.Parcelable {
- method public int getAddressType();
- method @Nullable public byte[] getIrk();
- }
-
- public static final class ScanFilter.Builder {
- method @NonNull public android.bluetooth.le.ScanFilter.Builder setDeviceAddress(@NonNull String, int);
- method @NonNull public android.bluetooth.le.ScanFilter.Builder setDeviceAddress(@NonNull String, int, @NonNull byte[]);
- field public static final int LEN_IRK_OCTETS = 16; // 0x10
- }
-
- public final class ScanSettings implements android.os.Parcelable {
- field public static final int SCAN_MODE_AMBIENT_DISCOVERY = 3; // 0x3
- field public static final int SCAN_RESULT_TYPE_ABBREVIATED = 1; // 0x1
- field public static final int SCAN_RESULT_TYPE_FULL = 0; // 0x0
- }
-
- public static final class ScanSettings.Builder {
- method public android.bluetooth.le.ScanSettings.Builder setScanResultType(int);
- }
-
- @Deprecated public final class TruncatedFilter {
- ctor @Deprecated public TruncatedFilter(android.bluetooth.le.ScanFilter, java.util.List<android.bluetooth.le.ResultStorageDescriptor>);
- method @Deprecated public android.bluetooth.le.ScanFilter getFilter();
- method @Deprecated public java.util.List<android.bluetooth.le.ResultStorageDescriptor> getStorageDescriptors();
- }
-
-}
-
package android.companion {
public final class AssociationInfo implements android.os.Parcelable {
@@ -2768,12 +2300,26 @@
method @Nullable @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.companion.virtual.VirtualDeviceManager.VirtualDevice createVirtualDevice(int, @NonNull android.companion.virtual.VirtualDeviceParams);
}
+ public static interface VirtualDeviceManager.ActivityListener {
+ method public void onDisplayEmpty(int);
+ method public void onTopActivityChanged(int, @NonNull android.content.ComponentName);
+ }
+
+ public static interface VirtualDeviceManager.LaunchCallback {
+ method public void onLaunchFailed();
+ method public void onLaunchSuccess();
+ }
+
public static class VirtualDeviceManager.VirtualDevice implements java.lang.AutoCloseable {
+ method public void addActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener);
+ method public void addActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener, @NonNull java.util.concurrent.Executor);
method public void close();
method @Nullable public android.hardware.display.VirtualDisplay createVirtualDisplay(int, int, int, @Nullable android.view.Surface, int, @Nullable android.os.Handler, @Nullable android.hardware.display.VirtualDisplay.Callback);
method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualKeyboard createVirtualKeyboard(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualMouse createVirtualMouse(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
+ method public void launchPendingIntent(int, @NonNull android.app.PendingIntent, @NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.LaunchCallback);
+ method public void removeActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener);
}
public final class VirtualDeviceParams implements android.os.Parcelable {
@@ -5245,6 +4791,7 @@
method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int enableUsbData(boolean);
method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int enableUsbDataWhileDocked();
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USB) public android.hardware.usb.UsbPortStatus getStatus();
+ method @CheckResult @RequiresPermission(android.Manifest.permission.MANAGE_USB) public int resetUsbPort();
method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setRoles(int, int);
field public static final int ENABLE_LIMIT_POWER_TRANSFER_ERROR_INTERNAL = 1; // 0x1
field public static final int ENABLE_LIMIT_POWER_TRANSFER_ERROR_NOT_SUPPORTED = 2; // 0x2
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index ff26ae8..169346b 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -617,14 +617,6 @@
}
-package android.bluetooth {
-
- public final class BluetoothClass implements android.os.Parcelable {
- method public int getClassOfDevice();
- }
-
-}
-
package android.companion {
public abstract class CompanionDeviceService extends android.app.Service {
@@ -1801,7 +1793,6 @@
method public static android.os.VibrationEffect get(int, boolean);
method @Nullable public static android.os.VibrationEffect get(android.net.Uri, android.content.Context);
method public abstract long getDuration();
- method @NonNull public static android.os.VibrationEffect.WaveformBuilder startWaveform();
field public static final int EFFECT_POP = 4; // 0x4
field public static final int EFFECT_STRENGTH_LIGHT = 0; // 0x0
field public static final int EFFECT_STRENGTH_MEDIUM = 1; // 0x1
@@ -1819,20 +1810,6 @@
field @NonNull public static final android.os.Parcelable.Creator<android.os.VibrationEffect.Composed> CREATOR;
}
- public static final class VibrationEffect.Composition {
- method @NonNull public android.os.VibrationEffect.Composition addEffect(@NonNull android.os.VibrationEffect);
- method @NonNull public android.os.VibrationEffect.Composition addEffect(@NonNull android.os.VibrationEffect, @IntRange(from=0) int);
- }
-
- public static final class VibrationEffect.WaveformBuilder {
- method @NonNull public android.os.VibrationEffect.WaveformBuilder addRamp(@FloatRange(from=0.0f, to=1.0f) float, @IntRange(from=0) int);
- method @NonNull public android.os.VibrationEffect.WaveformBuilder addRamp(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=1.0f) float, @IntRange(from=0) int);
- method @NonNull public android.os.VibrationEffect.WaveformBuilder addStep(@FloatRange(from=0.0f, to=1.0f) float, @IntRange(from=0) int);
- method @NonNull public android.os.VibrationEffect.WaveformBuilder addStep(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=1.0f) float, @IntRange(from=0) int);
- method @NonNull public android.os.VibrationEffect build();
- method @NonNull public android.os.VibrationEffect build(int);
- }
-
public abstract class Vibrator {
method public int getDefaultVibrationIntensity(int);
field public static final int VIBRATION_INTENSITY_HIGH = 3; // 0x3
@@ -2507,6 +2484,7 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void refreshUiccProfile();
method @Deprecated public void setCarrierTestOverride(String, String, String, String, String, String, String);
method public void setCarrierTestOverride(String, String, String, String, String, String, String, String, String);
+ method @RequiresPermission(android.Manifest.permission.BIND_TELECOM_CONNECTION_SERVICE) public void setVoiceServiceStateOverride(boolean);
field public static final int UNKNOWN_CARRIER_ID_LIST_VERSION = -1; // 0xffffffff
}
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index 7812aba..e31a566 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -16,6 +16,7 @@
package android.app;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -52,6 +53,7 @@
private String[] mRequireNoneOfPermissions;
private long mRequireCompatChangeId = CHANGE_INVALID;
private boolean mRequireCompatChangeEnabled = true;
+ private long mIdForResponseEvent;
/**
* Change ID which is invalid.
@@ -164,6 +166,12 @@
public static final int TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED =
PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED;
+ /**
+ * Corresponds to {@link #recordResponseEventWhileInBackground(long)}.
+ */
+ private static final String KEY_ID_FOR_RESPONSE_EVENT =
+ "android:broadcast.idForResponseEvent";
+
public static BroadcastOptions makeBasic() {
BroadcastOptions opts = new BroadcastOptions();
return opts;
@@ -198,6 +206,7 @@
mRequireNoneOfPermissions = opts.getStringArray(KEY_REQUIRE_NONE_OF_PERMISSIONS);
mRequireCompatChangeId = opts.getLong(KEY_REQUIRE_COMPAT_CHANGE_ID, CHANGE_INVALID);
mRequireCompatChangeEnabled = opts.getBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, true);
+ mIdForResponseEvent = opts.getLong(KEY_ID_FOR_RESPONSE_EVENT);
}
/**
@@ -511,6 +520,28 @@
}
/**
+ * Sets whether events (such as posting a notification) originating from an app after it
+ * receives the broadcast while in background should be recorded as responses to the broadcast.
+ *
+ * @param id ID to be used for the response events corresponding to this broadcast. If the
+ * value is {@code 0} (default), then response events will not be recorded. Otherwise,
+ * they will be recorded with the ID provided.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
+ public void recordResponseEventWhileInBackground(@IntRange(from = 0) long id) {
+ mIdForResponseEvent = id;
+ }
+
+ /** @hide */
+ @IntRange(from = 0)
+ public long getIdForResponseEvent() {
+ return mIdForResponseEvent;
+ }
+
+ /**
* Returns the created options as a Bundle, which can be passed to
* {@link android.content.Context#sendBroadcast(android.content.Intent)
* Context.sendBroadcast(Intent)} and related methods.
@@ -549,6 +580,9 @@
b.putLong(KEY_REQUIRE_COMPAT_CHANGE_ID, mRequireCompatChangeId);
b.putBoolean(KEY_REQUIRE_COMPAT_CHANGE_ENABLED, mRequireCompatChangeEnabled);
}
+ if (mIdForResponseEvent != 0) {
+ b.putLong(KEY_ID_FOR_RESPONSE_EVENT, mIdForResponseEvent);
+ }
return b.isEmpty() ? null : b;
}
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 779552f1..d57c288 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -6712,6 +6712,18 @@
return;
}
boolean isLowRam = ActivityManager.isLowRamDeviceStatic();
+
+ if (mSmallIcon != null
+ // Only bitmap icons can be downscaled.
+ && (mSmallIcon.getType() == Icon.TYPE_BITMAP
+ || mSmallIcon.getType() == Icon.TYPE_ADAPTIVE_BITMAP)) {
+ Resources resources = context.getResources();
+ int maxSize = resources.getDimensionPixelSize(
+ isLowRam ? R.dimen.notification_small_icon_size_low_ram
+ : R.dimen.notification_small_icon_size);
+ mSmallIcon.scaleDownIfNecessary(maxSize, maxSize);
+ }
+
if (mLargeIcon != null || largeIcon != null) {
Resources resources = context.getResources();
Class<? extends Style> style = getNotificationStyle();
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index cbce8ac..3960f4e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -10091,12 +10091,29 @@
}
/**
+ * Same as {@link #logoutUser(ComponentName)}, but called by system (like Settings), not admin.
+ *
+ * @hide
+ */
+ @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+ android.Manifest.permission.CREATE_USERS})
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public @UserOperationResult int logoutUser() {
+ // TODO(b/214336184): add CTS test
+ try {
+ return mService.logoutUserInternal();
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+ /**
* Gets the user a {@link #logoutUser(ComponentName)} call would switch to,
* or {@code null} if the current user is not in a session.
*
* @hide
*/
- @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
+ @RequiresPermission(anyOf = {android.Manifest.permission.MANAGE_USERS,
+ android.Manifest.permission.INTERACT_ACROSS_USERS})
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public @Nullable UserHandle getLogoutUser() {
// TODO(b/214336184): add CTS test
@@ -10109,24 +10126,6 @@
}
/**
- * Clears the user that {@link #logoutUser(ComponentName)} would switch to.
- *
- * <p>Typically used by system UI after it logout a session.
- *
- * @hide
- */
- @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
- @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
- public void clearLogoutUser() {
- // TODO(b/214336184): add CTS test
- try {
- mService.clearLogoutUser();
- } catch (RemoteException re) {
- throw re.rethrowFromSystemServer();
- }
- }
-
- /**
* Called by a device owner to list all secondary users on the device. Managed profiles are not
* considered as secondary users.
* <p> Used for various user management APIs, including {@link #switchUser}, {@link #removeUser}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 7525d54..927ee0c 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -268,8 +268,8 @@
int startUserInBackground(in ComponentName who, in UserHandle userHandle);
int stopUser(in ComponentName who, in UserHandle userHandle);
int logoutUser(in ComponentName who);
+ int logoutUserInternal(); // AIDL doesn't allow overloading name (logoutUser())
int getLogoutUserId();
- void clearLogoutUser();
List<UserHandle> getSecondaryUsers(in ComponentName who);
void acknowledgeNewUserDisclaimer();
diff --git a/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl b/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
index 53af4c5..a46dc53 100644
--- a/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
+++ b/core/java/android/companion/virtual/IVirtualDeviceActivityListener.aidl
@@ -23,7 +23,7 @@
*
* @hide
*/
-interface IVirtualDeviceActivityListener {
+oneway interface IVirtualDeviceActivityListener {
/**
* Called when the top activity is changed.
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index 64f16ac..bb9bb09 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -164,8 +164,6 @@
* @param executor The executor to run {@code launchCallback} on.
* @param launchCallback Callback that is called when the pending intent launching is
* complete.
- *
- * @hide
*/
public void launchPendingIntent(
int displayId,
@@ -196,9 +194,7 @@
/**
* Creates a virtual display for this virtual device. All displays created on the same
- * device belongs to the same display group. Requires the ADD_TRUSTED_DISPLAY permission
- * to create a virtual display which is not in the default DisplayGroup, and to create
- * trusted displays.
+ * device belongs to the same display group.
*
* @param width The width of the virtual display in pixels, must be greater than 0.
* @param height The height of the virtual display in pixels, must be greater than 0.
@@ -369,9 +365,7 @@
*
* @param listener The listener to add.
* @see #removeActivityListener(ActivityListener)
- * @hide
*/
- // TODO(b/194949534): Unhide this API
public void addActivityListener(@NonNull ActivityListener listener) {
addActivityListener(listener, mContext.getMainExecutor());
}
@@ -383,9 +377,7 @@
* @param listener The listener to add.
* @param executor The executor where the callback is executed on.
* @see #removeActivityListener(ActivityListener)
- * @hide
*/
- // TODO(b/194949534): Unhide this API
public void addActivityListener(
@NonNull ActivityListener listener, @NonNull Executor executor) {
mActivityListeners.put(listener, new ActivityListenerDelegate(listener, executor));
@@ -397,9 +389,7 @@
*
* @param listener The listener to remove.
* @see #addActivityListener(ActivityListener, Executor)
- * @hide
*/
- // TODO(b/194949534): Unhide this API
public void removeActivityListener(@NonNull ActivityListener listener) {
mActivityListeners.remove(listener);
}
@@ -407,10 +397,7 @@
/**
* Callback for launching pending intents on the virtual device.
- *
- * @hide
*/
- // TODO(b/194949534): Unhide this API
public interface LaunchCallback {
/**
* Called when the pending intent launched successfully.
@@ -425,10 +412,7 @@
/**
* Listener for activity changes in this virtual device.
- *
- * @hide
*/
- // TODO(b/194949534): Unhide this API
public interface ActivityListener {
/**
diff --git a/core/java/android/content/pm/AppSearchShortcutInfo.java b/core/java/android/content/pm/AppSearchShortcutInfo.java
index 8d9ef853..f20d1e6 100644
--- a/core/java/android/content/pm/AppSearchShortcutInfo.java
+++ b/core/java/android/content/pm/AppSearchShortcutInfo.java
@@ -29,6 +29,7 @@
import android.os.Bundle;
import android.os.PersistableBundle;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.ArraySet;
import com.android.internal.annotations.VisibleForTesting;
@@ -42,43 +43,125 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
/**
+ * A {@link GenericDocument} representation of {@link ShortcutInfo} object.
* @hide
*/
public class AppSearchShortcutInfo extends GenericDocument {
+ /** The TTL (time-to-live) of the shortcut, in milli-second. */
+ public static final long SHORTCUT_TTL = TimeUnit.DAYS.toMillis(90);
+
/** The name of the schema type for {@link ShortcutInfo} documents.*/
public static final String SCHEMA_TYPE = "Shortcut";
- public static final int SCHEMA_VERSION = 2;
+ /** @hide */
+ public static final int SCHEMA_VERSION = 3;
+
+ /**
+ * Property name of the activity this {@link ShortcutInfo} is associated with.
+ * See {@link ShortcutInfo#getActivity()}.
+ */
public static final String KEY_ACTIVITY = "activity";
+
+ /**
+ * Property name of the short description of this {@link ShortcutInfo}.
+ * See {@link ShortcutInfo#getShortLabel()}.
+ */
public static final String KEY_SHORT_LABEL = "shortLabel";
- public static final String KEY_SHORT_LABEL_RES_ID = "shortLabelResId";
- public static final String KEY_SHORT_LABEL_RES_NAME = "shortLabelResName";
+
+ /**
+ * Property name of the long description of this {@link ShortcutInfo}.
+ * See {@link ShortcutInfo#getLongLabel()}.
+ */
public static final String KEY_LONG_LABEL = "longLabel";
- public static final String KEY_LONG_LABEL_RES_ID = "longLabelResId";
- public static final String KEY_LONG_LABEL_RES_NAME = "longLabelResName";
+
+ /**
+ * @hide
+ */
public static final String KEY_DISABLED_MESSAGE = "disabledMessage";
- public static final String KEY_DISABLED_MESSAGE_RES_ID = "disabledMessageResId";
- public static final String KEY_DISABLED_MESSAGE_RES_NAME = "disabledMessageResName";
+
+ /**
+ * Property name of the categories this {@link ShortcutInfo} is associated with.
+ * See {@link ShortcutInfo#getCategories()}.
+ */
public static final String KEY_CATEGORIES = "categories";
+
+ /**
+ * Property name of the intents this {@link ShortcutInfo} is associated with.
+ * See {@link ShortcutInfo#getIntents()}.
+ */
public static final String KEY_INTENTS = "intents";
+
+ /**
+ * @hide
+ */
public static final String KEY_INTENT_PERSISTABLE_EXTRAS = "intentPersistableExtras";
+
+ /**
+ * Property name of {@link Person} objects this {@link ShortcutInfo} is associated with.
+ * See {@link ShortcutInfo#getPersons()}.
+ */
public static final String KEY_PERSON = "person";
+
+ /**
+ * Property name of {@link LocusId} this {@link ShortcutInfo} is associated with.
+ * See {@link ShortcutInfo#getLocusId()}.
+ */
public static final String KEY_LOCUS_ID = "locusId";
- public static final String KEY_RANK = "rank";
- public static final String KEY_IMPLICIT_RANK = "implicitRank";
+
+ /**
+ * @hide
+ */
public static final String KEY_EXTRAS = "extras";
+
+ /**
+ * Property name of the states this {@link ShortcutInfo} is currently in.
+ * Possible values are one or more of the following:
+ * {@link #IS_DYNAMIC}, {@link #NOT_DYNAMIC}, {@link #IS_MANIFEST}, {@link #NOT_MANIFEST},
+ * {@link #IS_DISABLED}, {@link #NOT_DISABLED}, {@link #IS_IMMUTABLE},
+ * {@link #NOT_IMMUTABLE}
+ *
+ */
public static final String KEY_FLAGS = "flags";
+
+ /**
+ * @hide
+ */
public static final String KEY_ICON_RES_ID = "iconResId";
+
+ /**
+ * @hide
+ */
public static final String KEY_ICON_RES_NAME = "iconResName";
+
+ /**
+ * @hide
+ */
public static final String KEY_ICON_URI = "iconUri";
- public static final String KEY_BITMAP_PATH = "bitmapPath";
+
+ /**
+ * @hide
+ */
public static final String KEY_DISABLED_REASON = "disabledReason";
+ /**
+ * Property name of capability this {@link ShortcutInfo} is associated with.
+ * See {@link ShortcutInfo#hasCapability(String)}.
+ */
+ public static final String KEY_CAPABILITY = "capability";
+
+ /**
+ * Property name of capability binding this {@link ShortcutInfo} is associated with.
+ * See {@link ShortcutInfo#getCapabilityParameters(String, String)}.
+ */
+ public static final String KEY_CAPABILITY_BINDINGS = "capabilityBindings";
+
public static final AppSearchSchema SCHEMA = new AppSearchSchema.Builder(SCHEMA_TYPE)
.addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_ACTIVITY)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
@@ -92,50 +175,18 @@
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.build()
- ).addProperty(new AppSearchSchema.LongPropertyConfig.Builder(KEY_SHORT_LABEL_RES_ID)
- .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
- .build()
-
- ).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_SHORT_LABEL_RES_NAME)
- .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
- .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
- .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
- .build()
-
).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_LONG_LABEL)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
.build()
- ).addProperty(new AppSearchSchema.LongPropertyConfig.Builder(KEY_LONG_LABEL_RES_ID)
- .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
- .build()
-
- ).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_LONG_LABEL_RES_NAME)
- .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
- .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
- .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
- .build()
-
).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_DISABLED_MESSAGE)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
.build()
- ).addProperty(new AppSearchSchema.LongPropertyConfig.Builder(
- KEY_DISABLED_MESSAGE_RES_ID)
- .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
- .build()
-
- ).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(
- KEY_DISABLED_MESSAGE_RES_NAME)
- .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
- .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
- .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
- .build()
-
).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_CATEGORIES)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
@@ -154,7 +205,7 @@
.build()
).addProperty(new AppSearchSchema.DocumentPropertyConfig.Builder(
- KEY_PERSON, AppSearchPerson.SCHEMA_TYPE)
+ KEY_PERSON, AppSearchShortcutPerson.SCHEMA_TYPE)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
.build()
@@ -164,16 +215,6 @@
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
.build()
- ).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_RANK)
- .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
- .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
- .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
- .build()
-
- ).addProperty(new AppSearchSchema.LongPropertyConfig.Builder(KEY_IMPLICIT_RANK)
- .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
- .build()
-
).addProperty(new AppSearchSchema.BytesPropertyConfig.Builder(KEY_EXTRAS)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
.build()
@@ -200,18 +241,24 @@
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
.build()
- ).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_BITMAP_PATH)
- .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
- .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_NONE)
- .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_NONE)
- .build()
-
).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_DISABLED_REASON)
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
.setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
.setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
.build()
+ ).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_CAPABILITY)
+ .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+ .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+ .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_EXACT_TERMS)
+ .build()
+
+ ).addProperty(new AppSearchSchema.StringPropertyConfig.Builder(KEY_CAPABILITY_BINDINGS)
+ .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REPEATED)
+ .setTokenizerType(AppSearchSchema.StringPropertyConfig.TOKENIZER_TYPE_PLAIN)
+ .setIndexingType(AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
+ .build()
+
).build();
/**
@@ -219,97 +266,62 @@
* needs to be camelCase since AppSearch's tokenizer will break the word when it sees
* underscore.
*/
- private static final String IS_DYNAMIC = "Dyn";
- private static final String NOT_DYNAMIC = "nDyn";
- private static final String IS_PINNED = "Pin";
- private static final String NOT_PINNED = "nPin";
- private static final String HAS_ICON_RES = "IcR";
- private static final String NO_ICON_RES = "nIcR";
- private static final String HAS_ICON_FILE = "IcF";
- private static final String NO_ICON_FILE = "nIcF";
- private static final String IS_KEY_FIELD_ONLY = "Key";
- private static final String NOT_KEY_FIELD_ONLY = "nKey";
- private static final String IS_MANIFEST = "Man";
- private static final String NOT_MANIFEST = "nMan";
- private static final String IS_DISABLED = "Dis";
- private static final String NOT_DISABLED = "nDis";
- private static final String ARE_STRINGS_RESOLVED = "Str";
- private static final String NOT_STRINGS_RESOLVED = "nStr";
- private static final String IS_IMMUTABLE = "Im";
- private static final String NOT_IMMUTABLE = "nIm";
- private static final String HAS_ADAPTIVE_BITMAP = "IcA";
- private static final String NO_ADAPTIVE_BITMAP = "nIcA";
- private static final String IS_RETURNED_BY_SERVICE = "Rets";
- private static final String NOT_RETURNED_BY_SERVICE = "nRets";
- private static final String HAS_ICON_FILE_PENDING_SAVE = "Pens";
- private static final String NO_ICON_FILE_PENDING_SAVE = "nPens";
- private static final String IS_SHADOW = "Sdw";
- private static final String NOT_SHADOW = "nSdw";
- private static final String IS_LONG_LIVED = "Liv";
- private static final String NOT_LONG_LIVED = "nLiv";
- private static final String HAS_ICON_URI = "IcU";
- private static final String NO_ICON_URI = "nIcU";
- private static final String IS_CACHED_NOTIFICATION = "CaN";
- private static final String NOT_CACHED_NOTIFICATION = "nCaN";
- private static final String IS_CACHED_BUBBLE = "CaB";
- private static final String NOT_CACHED_BUBBLE = "nCaB";
- private static final String IS_CACHED_PEOPLE_TITLE = "CaPT";
- private static final String NOT_CACHED_PEOPLE_TITLE = "nCaPT";
/**
- * Following flags are not store within ShortcutInfo, but book-keeping states to reduce search
- * space when performing queries against AppSearch.
+ * Indicates the {@link ShortcutInfo} is dynamic shortcut.
+ * See {@link #KEY_FLAGS}
+ * See {@link ShortcutInfo#isDynamic()}.
*/
- private static final String HAS_BITMAP_PATH = "hBiP";
- private static final String HAS_STRING_RESOURCE = "hStr";
- private static final String HAS_NON_ZERO_RANK = "hRan";
+ public static final String IS_DYNAMIC = "Dyn";
- public static final String QUERY_IS_DYNAMIC = KEY_FLAGS + ":" + IS_DYNAMIC;
- public static final String QUERY_IS_NOT_DYNAMIC = KEY_FLAGS + ":" + NOT_DYNAMIC;
- public static final String QUERY_IS_PINNED = KEY_FLAGS + ":" + IS_PINNED;
- public static final String QUERY_IS_NOT_PINNED = KEY_FLAGS + ":" + NOT_PINNED;
- public static final String QUERY_IS_MANIFEST = KEY_FLAGS + ":" + IS_MANIFEST;
- public static final String QUERY_IS_NOT_MANIFEST = KEY_FLAGS + ":" + NOT_MANIFEST;
- public static final String QUERY_IS_PINNED_AND_ENABLED =
- "(" + KEY_FLAGS + ":" + IS_PINNED + " " + KEY_FLAGS + ":" + NOT_DISABLED + ")";
- public static final String QUERY_IS_CACHED =
- "(" + KEY_FLAGS + ":" + IS_CACHED_NOTIFICATION + " OR "
- + KEY_FLAGS + ":" + IS_CACHED_BUBBLE + " OR "
- + KEY_FLAGS + ":" + IS_CACHED_PEOPLE_TITLE + ")";
- public static final String QUERY_IS_NOT_CACHED =
- "(" + KEY_FLAGS + ":" + NOT_CACHED_NOTIFICATION + " "
- + KEY_FLAGS + ":" + NOT_CACHED_BUBBLE + " "
- + KEY_FLAGS + ":" + NOT_CACHED_PEOPLE_TITLE + ")";
- public static final String QUERY_IS_FLOATING =
- "((" + IS_PINNED + " OR " + QUERY_IS_CACHED + ") "
- + QUERY_IS_NOT_DYNAMIC + " " + QUERY_IS_NOT_MANIFEST + ")";
- public static final String QUERY_IS_NOT_FLOATING =
- "((" + QUERY_IS_NOT_PINNED + " " + QUERY_IS_NOT_CACHED + ") OR "
- + QUERY_IS_DYNAMIC + " OR " + QUERY_IS_MANIFEST + ")";
- public static final String QUERY_IS_VISIBLE_TO_PUBLISHER =
- "(" + KEY_DISABLED_REASON + ":" + ShortcutInfo.DISABLED_REASON_NOT_DISABLED
- + " OR " + KEY_DISABLED_REASON + ":"
- + ShortcutInfo.DISABLED_REASON_BY_APP
- + " OR " + KEY_DISABLED_REASON + ":"
- + ShortcutInfo.DISABLED_REASON_APP_CHANGED
- + " OR " + KEY_DISABLED_REASON + ":"
- + ShortcutInfo.DISABLED_REASON_UNKNOWN + ")";
- public static final String QUERY_DISABLED_REASON_VERSION_LOWER =
- KEY_DISABLED_REASON + ":" + ShortcutInfo.DISABLED_REASON_VERSION_LOWER;
- public static final String QUERY_IS_NON_MANIFEST_VISIBLE =
- "(" + QUERY_IS_NOT_MANIFEST + " " + QUERY_IS_VISIBLE_TO_PUBLISHER + " ("
- + QUERY_IS_PINNED + " OR " + QUERY_IS_CACHED + " OR " + QUERY_IS_DYNAMIC + "))";
- public static final String QUERY_IS_VISIBLE_CACHED_OR_PINNED =
- "(" + QUERY_IS_VISIBLE_TO_PUBLISHER + " " + QUERY_IS_DYNAMIC
- + " (" + QUERY_IS_CACHED + " OR " + QUERY_IS_PINNED + "))";
- public static final String QUERY_IS_VISIBLE_PINNED_ONLY =
- "(" + QUERY_IS_VISIBLE_TO_PUBLISHER + " " + QUERY_IS_PINNED + " " + QUERY_IS_NOT_CACHED
- + " " + QUERY_IS_NOT_DYNAMIC + " " + QUERY_IS_NOT_MANIFEST + ")";
- public static final String QUERY_HAS_BITMAP_PATH = KEY_FLAGS + ":" + HAS_BITMAP_PATH;
- public static final String QUERY_HAS_STRING_RESOURCE = KEY_FLAGS + ":" + HAS_STRING_RESOURCE;
- public static final String QUERY_HAS_NON_ZERO_RANK = KEY_FLAGS + ":" + HAS_NON_ZERO_RANK;
- public static final String QUERY_IS_FLOATING_AND_HAS_RANK =
- "(" + QUERY_IS_FLOATING + " " + QUERY_HAS_NON_ZERO_RANK + ")";
+ /**
+ * Indicates the {@link ShortcutInfo} is not a dynamic shortcut.
+ * See {@link #KEY_FLAGS}
+ * See {@link ShortcutInfo#isDynamic()}.
+ */
+ public static final String NOT_DYNAMIC = "nDyn";
+
+ /**
+ * Indicates the {@link ShortcutInfo} is manifest shortcut.
+ * See {@link #KEY_FLAGS}
+ * See {@link ShortcutInfo#isDeclaredInManifest()}.
+ */
+ public static final String IS_MANIFEST = "Man";
+
+ /**
+ * Indicates the {@link ShortcutInfo} is manifest shortcut.
+ * See {@link #KEY_FLAGS}
+ * See {@link ShortcutInfo#isDeclaredInManifest()}.
+ */
+ public static final String NOT_MANIFEST = "nMan";
+
+ /**
+ * Indicates the {@link ShortcutInfo} is disabled.
+ * See {@link #KEY_FLAGS}
+ * See {@link ShortcutInfo#isEnabled()}.
+ */
+ public static final String IS_DISABLED = "Dis";
+
+ /**
+ * Indicates the {@link ShortcutInfo} is enabled.
+ * See {@link #KEY_FLAGS}
+ * See {@link ShortcutInfo#isEnabled()}.
+ */
+ public static final String NOT_DISABLED = "nDis";
+
+ /**
+ * Indicates the {@link ShortcutInfo} was originally from manifest, but currently disabled.
+ * See {@link #KEY_FLAGS}
+ * See {@link ShortcutInfo#isOriginallyFromManifest()}.
+ */
+ public static final String IS_IMMUTABLE = "Im";
+
+ /**
+ * Indicates the {@link ShortcutInfo} was not originally from manifest.
+ * See {@link #KEY_FLAGS}
+ * See {@link ShortcutInfo#isOriginallyFromManifest()}.
+ */
+ public static final String NOT_IMMUTABLE = "nIm";
public AppSearchShortcutInfo(@NonNull GenericDocument document) {
super(document);
@@ -324,34 +336,27 @@
return new Builder(shortcutInfo.getPackage(), shortcutInfo.getId())
.setActivity(shortcutInfo.getActivity())
.setShortLabel(shortcutInfo.getShortLabel())
- .setShortLabelResId(shortcutInfo.getShortLabelResourceId())
- .setShortLabelResName(shortcutInfo.getTitleResName())
.setLongLabel(shortcutInfo.getLongLabel())
- .setLongLabelResId(shortcutInfo.getLongLabelResourceId())
- .setLongLabelResName(shortcutInfo.getTextResName())
.setDisabledMessage(shortcutInfo.getDisabledMessage())
- .setDisabledMessageResId(shortcutInfo.getDisabledMessageResourceId())
- .setDisabledMessageResName(shortcutInfo.getDisabledMessageResName())
.setCategories(shortcutInfo.getCategories())
.setIntents(shortcutInfo.getIntents())
- .setRank(shortcutInfo.getRank())
- .setImplicitRank(shortcutInfo.getImplicitRank()
- | (shortcutInfo.isRankChanged() ? ShortcutInfo.RANK_CHANGED_BIT : 0))
.setExtras(shortcutInfo.getExtras())
.setCreationTimestampMillis(shortcutInfo.getLastChangedTimestamp())
.setFlags(shortcutInfo.getFlags())
.setIconResId(shortcutInfo.getIconResourceId())
.setIconResName(shortcutInfo.getIconResName())
- .setBitmapPath(shortcutInfo.getBitmapPath())
.setIconUri(shortcutInfo.getIconUri())
.setDisabledReason(shortcutInfo.getDisabledReason())
.setPersons(shortcutInfo.getPersons())
.setLocusId(shortcutInfo.getLocusId())
+ .setCapabilityBindings(shortcutInfo.getCapabilityBindings())
+ .setTtlMillis(SHORTCUT_TTL)
.build();
}
/**
- * @hide
+ * Converts this {@link GenericDocument} object into {@link ShortcutInfo} to read the
+ * information.
*/
@NonNull
public ShortcutInfo toShortcutInfo(@UserIdInt int userId) {
@@ -367,14 +372,8 @@
// LauncherApps#getShortcutIconDrawable instead.
final Icon icon = null;
final String shortLabel = getPropertyString(KEY_SHORT_LABEL);
- final int shortLabelResId = (int) getPropertyLong(KEY_SHORT_LABEL_RES_ID);
- final String shortLabelResName = getPropertyString(KEY_SHORT_LABEL_RES_NAME);
final String longLabel = getPropertyString(KEY_LONG_LABEL);
- final int longLabelResId = (int) getPropertyLong(KEY_LONG_LABEL_RES_ID);
- final String longLabelResName = getPropertyString(KEY_LONG_LABEL_RES_NAME);
final String disabledMessage = getPropertyString(KEY_DISABLED_MESSAGE);
- final int disabledMessageResId = (int) getPropertyLong(KEY_DISABLED_MESSAGE_RES_ID);
- final String disabledMessageResName = getPropertyString(KEY_DISABLED_MESSAGE_RES_NAME);
final String[] categories = getPropertyStringArray(KEY_CATEGORIES);
final Set<String> categoriesSet = categories == null
? null : new ArraySet<>(Arrays.asList(categories));
@@ -408,27 +407,22 @@
final Person[] persons = parsePerson(getPropertyDocumentArray(KEY_PERSON));
final String locusIdString = getPropertyString(KEY_LOCUS_ID);
final LocusId locusId = locusIdString == null ? null : new LocusId(locusIdString);
- final int rank = Integer.parseInt(getPropertyString(KEY_RANK));
- final int implicitRank = (int) getPropertyLong(KEY_IMPLICIT_RANK);
final byte[] extrasByte = getPropertyBytes(KEY_EXTRAS);
final PersistableBundle extras = transformToPersistableBundle(extrasByte);
final int flags = parseFlags(getPropertyStringArray(KEY_FLAGS));
final int iconResId = (int) getPropertyLong(KEY_ICON_RES_ID);
final String iconResName = getPropertyString(KEY_ICON_RES_NAME);
final String iconUri = getPropertyString(KEY_ICON_URI);
- final String bitmapPath = getPropertyString(KEY_BITMAP_PATH);
final int disabledReason = Integer.parseInt(getPropertyString(KEY_DISABLED_REASON));
- final ShortcutInfo si = new ShortcutInfo(
- userId, getId(), packageName, activity, icon, shortLabel, shortLabelResId,
- shortLabelResName, longLabel, longLabelResId, longLabelResName, disabledMessage,
- disabledMessageResId, disabledMessageResName, categoriesSet, intents, rank, extras,
- getCreationTimestampMillis(), flags, iconResId, iconResName, bitmapPath, iconUri,
- disabledReason, persons, locusId, null, null);
- si.setImplicitRank(implicitRank);
- if ((implicitRank & ShortcutInfo.RANK_CHANGED_BIT) != 0) {
- si.setRankChanged();
- }
- return si;
+ final Map<String, Map<String, List<String>>> capabilityBindings =
+ parseCapabilityBindings(getPropertyStringArray(KEY_CAPABILITY_BINDINGS));
+ return new ShortcutInfo(
+ userId, getId(), packageName, activity, icon, shortLabel, 0,
+ null, longLabel, 0, null, disabledMessage,
+ 0, null, categoriesSet, intents,
+ ShortcutInfo.RANK_NOT_SET, extras, getCreationTimestampMillis(), flags, iconResId,
+ iconResName, null, iconUri, disabledReason, persons, locusId,
+ null, capabilityBindings);
}
/**
@@ -449,7 +443,6 @@
public static class Builder extends GenericDocument.Builder<Builder> {
private List<String> mFlags = new ArrayList<>(1);
- private boolean mHasStringResource = false;
public Builder(String packageName, String id) {
super(/*namespace=*/ packageName, id, SCHEMA_TYPE);
@@ -493,28 +486,6 @@
* @hide
*/
@NonNull
- public Builder setShortLabelResId(final int shortLabelResId) {
- setPropertyLong(KEY_SHORT_LABEL_RES_ID, shortLabelResId);
- if (shortLabelResId != 0) {
- mHasStringResource = true;
- }
- return this;
- }
-
- /**
- * @hide
- */
- public Builder setShortLabelResName(@Nullable final String shortLabelResName) {
- if (!TextUtils.isEmpty(shortLabelResName)) {
- setPropertyString(KEY_SHORT_LABEL_RES_NAME, shortLabelResName);
- }
- return this;
- }
-
- /**
- * @hide
- */
- @NonNull
public Builder setLongLabel(@Nullable final CharSequence longLabel) {
if (!TextUtils.isEmpty(longLabel)) {
setPropertyString(KEY_LONG_LABEL, Preconditions.checkStringNotEmpty(
@@ -527,28 +498,6 @@
* @hide
*/
@NonNull
- public Builder setLongLabelResId(final int longLabelResId) {
- setPropertyLong(KEY_LONG_LABEL_RES_ID, longLabelResId);
- if (longLabelResId != 0) {
- mHasStringResource = true;
- }
- return this;
- }
-
- /**
- * @hide
- */
- public Builder setLongLabelResName(@Nullable final String longLabelResName) {
- if (!TextUtils.isEmpty(longLabelResName)) {
- setPropertyString(KEY_LONG_LABEL_RES_NAME, longLabelResName);
- }
- return this;
- }
-
- /**
- * @hide
- */
- @NonNull
public Builder setDisabledMessage(@Nullable final CharSequence disabledMessage) {
if (!TextUtils.isEmpty(disabledMessage)) {
setPropertyString(KEY_DISABLED_MESSAGE, Preconditions.checkStringNotEmpty(
@@ -561,28 +510,6 @@
* @hide
*/
@NonNull
- public Builder setDisabledMessageResId(final int disabledMessageResId) {
- setPropertyLong(KEY_DISABLED_MESSAGE_RES_ID, disabledMessageResId);
- if (disabledMessageResId != 0) {
- mHasStringResource = true;
- }
- return this;
- }
-
- /**
- * @hide
- */
- public Builder setDisabledMessageResName(@Nullable final String disabledMessageResName) {
- if (!TextUtils.isEmpty(disabledMessageResName)) {
- setPropertyString(KEY_DISABLED_MESSAGE_RES_NAME, disabledMessageResName);
- }
- return this;
- }
-
- /**
- * @hide
- */
- @NonNull
public Builder setCategories(@Nullable final Set<String> categories) {
if (categories != null && !categories.isEmpty()) {
setPropertyString(KEY_CATEGORIES, categories.stream().toArray(String[]::new));
@@ -649,8 +576,9 @@
for (int i = 0; i < persons.length; i++) {
final Person person = persons[i];
if (person == null) continue;
- final AppSearchPerson appSearchPerson = AppSearchPerson.instance(person);
- documents[i] = appSearchPerson;
+ final AppSearchShortcutPerson personEntity =
+ AppSearchShortcutPerson.instance(person);
+ documents[i] = personEntity;
}
setPropertyDocument(KEY_PERSON, documents);
return this;
@@ -660,28 +588,6 @@
* @hide
*/
@NonNull
- public Builder setRank(final int rank) {
- Preconditions.checkArgument((0 <= rank), "Rank cannot be negative");
- setPropertyString(KEY_RANK, String.valueOf(rank));
- if (rank != 0) {
- mFlags.add(HAS_NON_ZERO_RANK);
- }
- return this;
- }
-
- /**
- * @hide
- */
- @NonNull
- public Builder setImplicitRank(final int rank) {
- setPropertyLong(KEY_IMPLICIT_RANK, rank);
- return this;
- }
-
- /**
- * @hide
- */
- @NonNull
public Builder setExtras(@Nullable final PersistableBundle extras) {
if (extras != null) {
setPropertyBytes(KEY_EXTRAS, transformToByteArray(extras));
@@ -722,17 +628,6 @@
/**
* @hide
*/
- public Builder setBitmapPath(@Nullable final String bitmapPath) {
- if (!TextUtils.isEmpty(bitmapPath)) {
- setPropertyString(KEY_BITMAP_PATH, bitmapPath);
- mFlags.add(HAS_BITMAP_PATH);
- }
- return this;
- }
-
- /**
- * @hide
- */
public Builder setIconUri(@Nullable final String iconUri) {
if (!TextUtils.isEmpty(iconUri)) {
setPropertyString(KEY_ICON_URI, iconUri);
@@ -751,12 +646,33 @@
/**
* @hide
*/
+ public Builder setCapabilityBindings(
+ @Nullable final Map<String, Map<String, List<String>>> bindings) {
+ if (bindings != null && !bindings.isEmpty()) {
+ final Set<String> capabilityNames = bindings.keySet();
+ final Set<String> capabilityBindings = new ArraySet<>(1);
+ for (String capabilityName: capabilityNames) {
+ final Map<String, List<String>> params =
+ bindings.get(capabilityName);
+ for (String paramName: params.keySet()) {
+ params.get(paramName).stream()
+ .map(v -> capabilityName + "/" + paramName + "/" + v)
+ .forEach(capabilityBindings::add);
+ }
+ }
+ setPropertyString(KEY_CAPABILITY, capabilityNames.toArray(new String[0]));
+ setPropertyString(KEY_CAPABILITY_BINDINGS,
+ capabilityBindings.toArray(new String[0]));
+ }
+ return this;
+ }
+
+ /**
+ * @hide
+ */
@NonNull
@Override
public AppSearchShortcutInfo build() {
- if (mHasStringResource) {
- mFlags.add(HAS_STRING_RESOURCE);
- }
setPropertyString(KEY_FLAGS, mFlags.toArray(new String[0]));
return new AppSearchShortcutInfo(super.build());
}
@@ -827,40 +743,12 @@
switch (mask) {
case ShortcutInfo.FLAG_DYNAMIC:
return (flags & mask) != 0 ? IS_DYNAMIC : NOT_DYNAMIC;
- case ShortcutInfo.FLAG_PINNED:
- return (flags & mask) != 0 ? IS_PINNED : NOT_PINNED;
- case ShortcutInfo.FLAG_HAS_ICON_RES:
- return (flags & mask) != 0 ? HAS_ICON_RES : NO_ICON_RES;
- case ShortcutInfo.FLAG_HAS_ICON_FILE:
- return (flags & mask) != 0 ? HAS_ICON_FILE : NO_ICON_FILE;
- case ShortcutInfo.FLAG_KEY_FIELDS_ONLY:
- return (flags & mask) != 0 ? IS_KEY_FIELD_ONLY : NOT_KEY_FIELD_ONLY;
case ShortcutInfo.FLAG_MANIFEST:
return (flags & mask) != 0 ? IS_MANIFEST : NOT_MANIFEST;
case ShortcutInfo.FLAG_DISABLED:
return (flags & mask) != 0 ? IS_DISABLED : NOT_DISABLED;
- case ShortcutInfo.FLAG_STRINGS_RESOLVED:
- return (flags & mask) != 0 ? ARE_STRINGS_RESOLVED : NOT_STRINGS_RESOLVED;
case ShortcutInfo.FLAG_IMMUTABLE:
return (flags & mask) != 0 ? IS_IMMUTABLE : NOT_IMMUTABLE;
- case ShortcutInfo.FLAG_ADAPTIVE_BITMAP:
- return (flags & mask) != 0 ? HAS_ADAPTIVE_BITMAP : NO_ADAPTIVE_BITMAP;
- case ShortcutInfo.FLAG_RETURNED_BY_SERVICE:
- return (flags & mask) != 0 ? IS_RETURNED_BY_SERVICE : NOT_RETURNED_BY_SERVICE;
- case ShortcutInfo.FLAG_ICON_FILE_PENDING_SAVE:
- return (flags & mask) != 0 ? HAS_ICON_FILE_PENDING_SAVE : NO_ICON_FILE_PENDING_SAVE;
- case ShortcutInfo.FLAG_SHADOW:
- return (flags & mask) != 0 ? IS_SHADOW : NOT_SHADOW;
- case ShortcutInfo.FLAG_LONG_LIVED:
- return (flags & mask) != 0 ? IS_LONG_LIVED : NOT_LONG_LIVED;
- case ShortcutInfo.FLAG_HAS_ICON_URI:
- return (flags & mask) != 0 ? HAS_ICON_URI : NO_ICON_URI;
- case ShortcutInfo.FLAG_CACHED_NOTIFICATIONS:
- return (flags & mask) != 0 ? IS_CACHED_NOTIFICATION : NOT_CACHED_NOTIFICATION;
- case ShortcutInfo.FLAG_CACHED_BUBBLES:
- return (flags & mask) != 0 ? IS_CACHED_BUBBLE : NOT_CACHED_BUBBLE;
- case ShortcutInfo.FLAG_CACHED_PEOPLE_TILE:
- return (flags & mask) != 0 ? IS_CACHED_PEOPLE_TITLE : NOT_CACHED_PEOPLE_TITLE;
default:
return null;
}
@@ -881,40 +769,12 @@
switch (value) {
case IS_DYNAMIC:
return ShortcutInfo.FLAG_DYNAMIC;
- case IS_PINNED:
- return ShortcutInfo.FLAG_PINNED;
- case HAS_ICON_RES:
- return ShortcutInfo.FLAG_HAS_ICON_RES;
- case HAS_ICON_FILE:
- return ShortcutInfo.FLAG_HAS_ICON_FILE;
- case IS_KEY_FIELD_ONLY:
- return ShortcutInfo.FLAG_KEY_FIELDS_ONLY;
case IS_MANIFEST:
return ShortcutInfo.FLAG_MANIFEST;
case IS_DISABLED:
return ShortcutInfo.FLAG_DISABLED;
- case ARE_STRINGS_RESOLVED:
- return ShortcutInfo.FLAG_STRINGS_RESOLVED;
case IS_IMMUTABLE:
return ShortcutInfo.FLAG_IMMUTABLE;
- case HAS_ADAPTIVE_BITMAP:
- return ShortcutInfo.FLAG_ADAPTIVE_BITMAP;
- case IS_RETURNED_BY_SERVICE:
- return ShortcutInfo.FLAG_RETURNED_BY_SERVICE;
- case HAS_ICON_FILE_PENDING_SAVE:
- return ShortcutInfo.FLAG_ICON_FILE_PENDING_SAVE;
- case IS_SHADOW:
- return ShortcutInfo.FLAG_SHADOW;
- case IS_LONG_LIVED:
- return ShortcutInfo.FLAG_LONG_LIVED;
- case HAS_ICON_URI:
- return ShortcutInfo.FLAG_HAS_ICON_URI;
- case IS_CACHED_NOTIFICATION:
- return ShortcutInfo.FLAG_CACHED_NOTIFICATIONS;
- case IS_CACHED_BUBBLE:
- return ShortcutInfo.FLAG_CACHED_BUBBLES;
- case IS_CACHED_PEOPLE_TITLE:
- return ShortcutInfo.FLAG_CACHED_PEOPLE_TILE;
default:
return 0;
}
@@ -927,9 +787,43 @@
for (int i = 0; i < persons.length; i++) {
final GenericDocument document = persons[i];
if (document == null) continue;
- final AppSearchPerson person = new AppSearchPerson(document);
+ final AppSearchShortcutPerson person = new AppSearchShortcutPerson(document);
ret[i] = person.toPerson();
}
return ret;
}
+
+ @Nullable
+ private static Map<String, Map<String, List<String>>> parseCapabilityBindings(
+ @Nullable final String[] capabilityBindings) {
+ if (capabilityBindings == null || capabilityBindings.length == 0) {
+ return null;
+ }
+ final Map<String, Map<String, List<String>>> ret = new ArrayMap<>(1);
+ Arrays.stream(capabilityBindings).forEach(binding -> {
+ if (TextUtils.isEmpty(binding)) {
+ return;
+ }
+ final int capabilityStopIndex = binding.indexOf("/");
+ if (capabilityStopIndex == -1 || capabilityStopIndex == binding.length() - 1) {
+ return;
+ }
+ final String capabilityName = binding.substring(0, capabilityStopIndex);
+ final int paramStopIndex = binding.indexOf("/", capabilityStopIndex + 1);
+ if (paramStopIndex == -1 || paramStopIndex == binding.length() - 1) {
+ return;
+ }
+ final String paramName = binding.substring(capabilityStopIndex + 1, paramStopIndex);
+ final String paramValue = binding.substring(paramStopIndex + 1);
+ if (!ret.containsKey(capabilityName)) {
+ ret.put(capabilityName, new ArrayMap<>(1));
+ }
+ final Map<String, List<String>> params = ret.get(capabilityName);
+ if (!params.containsKey(paramName)) {
+ params.put(paramName, new ArrayList<>(1));
+ }
+ params.get(paramName).add(paramValue);
+ });
+ return ret;
+ }
}
diff --git a/core/java/android/content/pm/AppSearchPerson.java b/core/java/android/content/pm/AppSearchShortcutPerson.java
similarity index 63%
rename from core/java/android/content/pm/AppSearchPerson.java
rename to core/java/android/content/pm/AppSearchShortcutPerson.java
index 98d150b..ff8a3b6 100644
--- a/core/java/android/content/pm/AppSearchPerson.java
+++ b/core/java/android/content/pm/AppSearchShortcutPerson.java
@@ -21,28 +21,38 @@
import android.app.Person;
import android.app.appsearch.AppSearchSchema;
import android.app.appsearch.GenericDocument;
+import android.graphics.drawable.Icon;
import android.net.UriCodec;
import com.android.internal.annotations.VisibleForTesting;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.UUID;
/**
+ * A {@link GenericDocument} representation of {@link Person} object.
+ *
* @hide
*/
-public class AppSearchPerson extends GenericDocument {
+public class AppSearchShortcutPerson extends GenericDocument {
- /** The name of the schema type for {@link Person} documents.*/
- public static final String SCHEMA_TYPE = "Person";
+ /**
+ * The name of the schema type for {@link Person} documents.
+ * @hide
+ */
+ public static final String SCHEMA_TYPE = "ShortcutPerson";
- public static final String KEY_NAME = "name";
- public static final String KEY_KEY = "key";
- public static final String KEY_IS_BOT = "isBot";
- public static final String KEY_IS_IMPORTANT = "isImportant";
+ private static final String KEY_NAME = "name";
+ private static final String KEY_KEY = "key";
+ private static final String KEY_IS_BOT = "isBot";
+ private static final String KEY_IS_IMPORTANT = "isImportant";
+ private static final String KEY_ICON = "icon";
- public AppSearchPerson(@NonNull GenericDocument document) {
+ public AppSearchShortcutPerson(@NonNull GenericDocument document) {
super(document);
}
@@ -67,11 +77,15 @@
.setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_REQUIRED)
.build()
+ ).addProperty(new AppSearchSchema.BytesPropertyConfig.Builder(KEY_ICON)
+ .setCardinality(AppSearchSchema.PropertyConfig.CARDINALITY_OPTIONAL)
+ .build()
+
).build();
- /** hide */
+ /** @hide */
@NonNull
- public static AppSearchPerson instance(@NonNull final Person person) {
+ public static AppSearchShortcutPerson instance(@NonNull final Person person) {
Objects.requireNonNull(person);
final String id;
if (person.getUri() != null) {
@@ -82,10 +96,13 @@
}
return new Builder(id).setName(person.getName())
.setKey(person.getKey()).setIsBot(person.isBot())
- .setIsImportant(person.isImportant()).build();
+ .setIsImportant(person.isImportant())
+ .setIcon(transformToByteArray(person.getIcon())).build();
}
- /** hide */
+ /**
+ * Convert this {@link GenericDocument} into {@link Person}.
+ */
@NonNull
public Person toPerson() {
String uri;
@@ -99,7 +116,9 @@
return new Person.Builder().setName(getPropertyString(KEY_NAME))
.setUri(uri).setKey(getPropertyString(KEY_KEY))
.setBot(getPropertyBoolean(KEY_IS_BOT))
- .setImportant(getPropertyBoolean(KEY_IS_IMPORTANT)).build();
+ .setImportant(getPropertyBoolean(KEY_IS_IMPORTANT))
+ .setIcon(transformToIcon(getPropertyBytes(KEY_ICON)))
+ .build();
}
/** @hide */
@@ -142,10 +161,51 @@
return this;
}
+ /** @hide */
+ @NonNull
+ public Builder setIcon(@Nullable final byte[] icon) {
+ if (icon != null) {
+ setPropertyBytes(KEY_ICON, icon);
+ }
+ return this;
+ }
+
+ /** @hide */
@NonNull
@Override
- public AppSearchPerson build() {
- return new AppSearchPerson(super.build());
+ public AppSearchShortcutPerson build() {
+ return new AppSearchShortcutPerson(super.build());
+ }
+ }
+
+ /**
+ * Convert {@link Icon} into byte[].
+ */
+ @Nullable
+ private static byte[] transformToByteArray(@Nullable final Icon icon) {
+ if (icon == null) {
+ return null;
+ }
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+ icon.writeToStream(baos);
+ return baos.toByteArray();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Convert byte[] into {@link Icon}.
+ */
+ @Nullable
+ private Icon transformToIcon(@Nullable final byte[] icon) {
+ if (icon == null) {
+ return null;
+ }
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(icon)) {
+ return Icon.createFromStream(bais);
+ } catch (IOException e) {
+ return null;
}
}
}
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index ab827aa..41dd5bb3 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -24,6 +24,7 @@
import android.app.Notification;
import android.app.Person;
import android.app.TaskStackBuilder;
+import android.app.appsearch.GenericDocument;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
@@ -656,6 +657,28 @@
}
/**
+ * Convert a {@link GenericDocument} into a ShortcutInfo.
+ *
+ * @param context Client context
+ * @param document An instance of {@link GenericDocument} that represents the shortcut.
+ */
+ @NonNull
+ public static ShortcutInfo createFromGenericDocument(@NonNull final Context context,
+ @NonNull final GenericDocument document) {
+ Objects.requireNonNull(context);
+ Objects.requireNonNull(document);
+ return createFromGenericDocument(context.getUserId(), document);
+ }
+
+ /**
+ * @hide
+ */
+ public static ShortcutInfo createFromGenericDocument(
+ final int userId, @NonNull final GenericDocument document) {
+ return new AppSearchShortcutInfo(document).toShortcutInfo(userId);
+ }
+
+ /**
* Load a string resource from the publisher app.
*
* @param resId resource ID
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 459dab1..b617e05 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -136,6 +136,9 @@
/* Resets the USB gadget. */
void resetUsbGadget();
+ /* Resets the USB port. */
+ boolean resetUsbPort(in String portId, int operationId, in IUsbOperationInternal callback);
+
/* Set USB data on or off */
boolean enableUsbData(in String portId, boolean enable, int operationId, in IUsbOperationInternal callback);
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index f0e040e..60f5135 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -1324,6 +1324,43 @@
}
/**
+ * Should only be called by {@link UsbPort#resetUsbPort}.
+ * <p>
+ * Disable and then re-enable USB data signaling.
+ *
+ * Reset USB first port..
+ * It will force to stop and restart USB data signaling.
+ * Call UsbPort API if the device has more than one UsbPort.
+ * </p>
+ *
+ * @param port reset the USB Port
+ * @return true enable or disable USB data successfully
+ * false if something wrong
+ *
+ * Should only be called by {@link UsbPort#resetUsbPort}.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.MANAGE_USB)
+ boolean resetUsbPort(@NonNull UsbPort port, int operationId,
+ IUsbOperationInternal callback) {
+ Objects.requireNonNull(port, "resetUsbPort: port must not be null. opId:" + operationId);
+ try {
+ return mService.resetUsbPort(port.getId(), operationId, callback);
+ } catch (RemoteException e) {
+ Log.e(TAG, "resetUsbPort: failed. ", e);
+ try {
+ callback.onOperationComplete(UsbOperationInternal.USB_OPERATION_ERROR_INTERNAL);
+ } catch (RemoteException r) {
+ Log.e(TAG, "resetUsbPort: failed to call onOperationComplete. opId:"
+ + operationId, r);
+ }
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Should only be called by {@link UsbPort#enableUsbData}.
* <p>
* Enables or disables USB data on the specific port.
diff --git a/core/java/android/hardware/usb/UsbPort.java b/core/java/android/hardware/usb/UsbPort.java
index bef4dea..a979725 100644
--- a/core/java/android/hardware/usb/UsbPort.java
+++ b/core/java/android/hardware/usb/UsbPort.java
@@ -128,6 +128,9 @@
@Retention(RetentionPolicy.SOURCE)
@interface EnableUsbDataStatus{}
+ @Retention(RetentionPolicy.SOURCE)
+ @interface ResetUsbPortStatus{}
+
/**
* The {@link #enableLimitPowerTransfer} request was successfully completed.
*/
@@ -319,6 +322,43 @@
}
/**
+ * Reset Usb data on the port.
+ *
+ * @return {@link #ENABLE_USB_DATA_SUCCESS} when request completes successfully or
+ * {@link #ENABLE_USB_DATA_ERROR_INTERNAL} when request fails due to internal
+ * error or
+ * {@link ENABLE_USB_DATA_ERROR_NOT_SUPPORTED} when not supported or
+ * {@link ENABLE_USB_DATA_ERROR_PORT_MISMATCH} when request fails due to port id
+ * mismatch or
+ * {@link ENABLE_USB_DATA_ERROR_OTHER} when fails due to other reasons.
+ */
+ @CheckResult
+ @RequiresPermission(Manifest.permission.MANAGE_USB)
+ public @ResetUsbPortStatus int resetUsbPort() {
+ // UID is added To minimize operationID overlap between two different packages.
+ int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
+ Log.i(TAG, "resetUsbData opId:" + operationId);
+ UsbOperationInternal opCallback =
+ new UsbOperationInternal(operationId, mId);
+ if (mUsbManager.resetUsbPort(this, operationId, opCallback) == true) {
+ opCallback.waitForOperationComplete();
+ }
+ int result = opCallback.getStatus();
+ switch (result) {
+ case USB_OPERATION_SUCCESS:
+ return ENABLE_USB_DATA_SUCCESS;
+ case USB_OPERATION_ERROR_INTERNAL:
+ return ENABLE_USB_DATA_ERROR_INTERNAL;
+ case USB_OPERATION_ERROR_NOT_SUPPORTED:
+ return ENABLE_USB_DATA_ERROR_NOT_SUPPORTED;
+ case USB_OPERATION_ERROR_PORT_MISMATCH:
+ return ENABLE_USB_DATA_ERROR_PORT_MISMATCH;
+ default:
+ return ENABLE_USB_DATA_ERROR_OTHER;
+ }
+ }
+
+ /**
* Enables/Disables Usb data on the port.
*
* @param enable When true enables USB data if disabled.
diff --git a/core/java/android/inputmethodservice/AbstractInputMethodService.java b/core/java/android/inputmethodservice/AbstractInputMethodService.java
index 75beacf..f16e243 100644
--- a/core/java/android/inputmethodservice/AbstractInputMethodService.java
+++ b/core/java/android/inputmethodservice/AbstractInputMethodService.java
@@ -300,13 +300,6 @@
return false;
}
- // TODO(b/149463653): remove it in T. We missed the API deadline in S.
- /** @hide */
- @Override
- public final boolean isUiContext() {
- return true;
- }
-
/** @hide */
@Override
public final int getWindowType() {
diff --git a/core/java/android/nfc/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl
index 539fd4a..e1ccc4f 100644
--- a/core/java/android/nfc/INfcTag.aidl
+++ b/core/java/android/nfc/INfcTag.aidl
@@ -45,4 +45,7 @@
boolean canMakeReadOnly(int ndefType);
int getMaxTransceiveLength(int technology);
boolean getExtendedLengthApdusSupported();
+
+ void setTagUpToDate(long cookie);
+ boolean isTagUpToDate(long cookie);
}
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 398ec63a..0ce9c70 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -34,6 +34,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
+import android.os.SystemClock;
import java.io.IOException;
import java.util.Arrays;
@@ -121,6 +122,7 @@
final INfcTag mTagService; // interface to NFC service, will be null if mock tag
int mConnectedTechnology;
+ long mCookie;
/**
* Hidden constructor to be used by NFC service and internal classes.
@@ -140,6 +142,13 @@
mTagService = tagService;
mConnectedTechnology = -1;
+
+ try {
+ mCookie = SystemClock.elapsedRealtime();
+ tagService.setTagUpToDate(mCookie);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
}
/**
@@ -361,6 +370,18 @@
/** @hide */
@UnsupportedAppUsage
public INfcTag getTagService() {
+ try {
+ if (!mTagService.isTagUpToDate(mCookie)) {
+ String id_str = "";
+ for (int i = 0; i < mId.length; i++) {
+ id_str = id_str + String.format("%02X ", mId[i]);
+ }
+ String msg = "Permission Denial: Tag ( ID: " + id_str + ") is out of date";
+ throw new SecurityException(msg);
+ }
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
return mTagService;
}
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 6d4593a..76f857b 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -187,10 +187,13 @@
public static final int BATTERY_PLUGGED_USB = OsProtoEnums.BATTERY_PLUGGED_USB; // = 2
/** Power source is wireless. */
public static final int BATTERY_PLUGGED_WIRELESS = OsProtoEnums.BATTERY_PLUGGED_WIRELESS; // = 4
+ /** Power source is dock. */
+ public static final int BATTERY_PLUGGED_DOCK = OsProtoEnums.BATTERY_PLUGGED_DOCK; // = 8
/** @hide */
public static final int BATTERY_PLUGGED_ANY =
- BATTERY_PLUGGED_AC | BATTERY_PLUGGED_USB | BATTERY_PLUGGED_WIRELESS;
+ BATTERY_PLUGGED_AC | BATTERY_PLUGGED_USB | BATTERY_PLUGGED_WIRELESS
+ | BATTERY_PLUGGED_DOCK;
/**
* Sent when the device's battery has started charging (or has reached full charge
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 1810904..b754598 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -704,6 +704,21 @@
public long wakeTime;
public @WakeReason int wakeReason;
public long sleepDuration;
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (o instanceof WakeData) {
+ final WakeData other = (WakeData) o;
+ return wakeTime == other.wakeTime && wakeReason == other.wakeReason
+ && sleepDuration == other.sleepDuration;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(wakeTime, wakeReason, sleepDuration);
+ }
}
/**
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index ae37a71..f490587 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -21,7 +21,6 @@
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SuppressLint;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ContentResolver;
@@ -40,6 +39,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -196,20 +196,20 @@
/**
* Create a waveform vibration.
*
- * Waveform vibrations are a potentially repeating series of timing and amplitude pairs. For
+ * <p>Waveform vibrations are a potentially repeating series of timing and amplitude pairs. For
* each pair, the value in the amplitude array determines the strength of the vibration and the
* value in the timing array determines how long it vibrates for. An amplitude of 0 implies no
* vibration (i.e. off), and any pairs with a timing value of 0 will be ignored.
- * <p>
- * The amplitude array of the generated waveform will be the same size as the given
+ *
+ * <p>The amplitude array of the generated waveform will be the same size as the given
* timing array with alternating values of 0 (i.e. off) and {@link #DEFAULT_AMPLITUDE},
* starting with 0. Therefore the first timing value will be the period to wait before turning
* the vibrator on, the second value will be how long to vibrate at {@link #DEFAULT_AMPLITUDE}
* strength, etc.
- * </p><p>
- * To cause the pattern to repeat, pass the index into the timings array at which to start the
- * repetition, or -1 to disable repeating.
- * </p>
+ *
+ * <p>To cause the pattern to repeat, pass the index into the timings array at which to start
+ * the repetition, or -1 to disable repeating. Repeating effects will be played indefinitely
+ * and should be cancelled via {@link Vibrator#cancel()}.
*
* @param timings The pattern of alternating on-off timings, starting with off. Timing values
* of 0 will cause the timing / amplitude pair to be ignored.
@@ -229,15 +229,15 @@
/**
* Create a waveform vibration.
*
- * Waveform vibrations are a potentially repeating series of timing and amplitude pairs. For
+ * <p>Waveform vibrations are a potentially repeating series of timing and amplitude pairs. For
* each pair, the value in the amplitude array determines the strength of the vibration and the
* value in the timing array determines how long it vibrates for, in milliseconds. Amplitude
* values must be between 0 and 255, and an amplitude of 0 implies no vibration (i.e. off). Any
* pairs with a timing value of 0 will be ignored.
- * </p><p>
- * To cause the pattern to repeat, pass the index into the timings array at which to start the
- * repetition, or -1 to disable repeating.
- * </p>
+ *
+ * <p>To cause the pattern to repeat, pass the index into the timings array at which to start
+ * the repetition, or -1 to disable repeating. Repeating effects will be played indefinitely
+ * and should be cancelled via {@link Vibrator#cancel()}.
*
* @param timings The timing values, in milliseconds, of the timing / amplitude pairs. Timing
* values of 0 will cause the pair to be ignored.
@@ -407,20 +407,59 @@
* Start building a waveform vibration.
*
* <p>The waveform builder offers more flexibility for creating waveform vibrations, allowing
- * control over vibration frequency and ramping up or down the vibration amplitude, frequency or
- * both.
+ * control over vibration amplitude and frequency via smooth transitions between values.
*
- * <p>For simpler waveform patterns see {@link #createWaveform} methods.
+ * <p>The waveform will start the first transition from the vibrator off state, with the
+ * resonant frequency by default. To provide an initial state, use
+ * {@link #startWaveform(VibrationParameter)}.
*
- * @hide
- * @see VibrationEffect.WaveformBuilder
+ * @return The {@link VibrationEffect.WaveformBuilder} started with the initial parameters.
*/
- @TestApi
@NonNull
public static WaveformBuilder startWaveform() {
return new WaveformBuilder();
}
+ /**
+ * Start building a waveform vibration with an initial state specified by a
+ * {@link VibrationParameter}.
+ *
+ * <p>The waveform builder offers more flexibility for creating waveform vibrations, allowing
+ * control over vibration amplitude and frequency via smooth transitions between values.
+ *
+ * @param initialParameter The initial {@link VibrationParameter} value to be applied at the
+ * beginning of the vibration.
+ * @return The {@link VibrationEffect.WaveformBuilder} started with the initial parameters.
+ */
+ @NonNull
+ public static WaveformBuilder startWaveform(@NonNull VibrationParameter initialParameter) {
+ WaveformBuilder builder = startWaveform();
+ builder.addTransition(Duration.ZERO, initialParameter);
+ return builder;
+ }
+
+ /**
+ * Start building a waveform vibration with an initial state specified by two
+ * {@link VibrationParameter VibrationParameters}.
+ *
+ * <p>The waveform builder offers more flexibility for creating waveform vibrations, allowing
+ * control over vibration amplitude and frequency via smooth transitions between values.
+ *
+ * @param initialParameter1 The initial {@link VibrationParameter} value to be applied at the
+ * beginning of the vibration.
+ * @param initialParameter2 The initial {@link VibrationParameter} value to be applied at the
+ * beginning of the vibration, must be a different type of parameter
+ * than the one specified by the first argument.
+ * @return The {@link VibrationEffect.WaveformBuilder} started with the initial parameters.
+ */
+ @NonNull
+ public static WaveformBuilder startWaveform(@NonNull VibrationParameter initialParameter1,
+ @NonNull VibrationParameter initialParameter2) {
+ WaveformBuilder builder = startWaveform();
+ builder.addTransition(Duration.ZERO, initialParameter1, initialParameter2);
+ return builder;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -784,10 +823,23 @@
PRIMITIVE_LOW_TICK,
})
@Retention(RetentionPolicy.SOURCE)
- public @interface PrimitiveType {}
+ public @interface PrimitiveType {
+ }
+
+ /**
+ * Exception thrown when adding an element to a {@link Composition} that already ends in an
+ * indefinitely repeating effect.
+ */
+ public static final class UnreachableAfterRepeatingIndefinitelyException
+ extends IllegalStateException {
+ UnreachableAfterRepeatingIndefinitelyException() {
+ super("Compositions ending in an indefinitely repeating effect can't be extended");
+ }
+ }
/**
* No haptic effect. Used to generate extended delays between primitives.
+ *
* @hide
*/
public static final int PRIMITIVE_NOOP = 0;
@@ -837,50 +889,87 @@
Composition() {}
/**
- * Add a haptic effect to the end of the current composition.
+ * Adds a time duration to the current composition, during which the vibrator will be
+ * turned off
*
- * <p>Similar to {@link #addEffect(VibrationEffect, int)} , but with no delay applied.
+ * @param duration The length of time the vibrator should be off. Value must be non-negative
+ * and will be truncated to milliseconds.
+ * @return This {@link Composition} object to enable adding multiple elements in one chain.
*
- * @param effect The effect to add to this composition as a primitive
- * @return The {@link Composition} object to enable adding multiple primitives in one chain.
- * @hide
+ * @throws UnreachableAfterRepeatingIndefinitelyException if the composition is currently
+ * ending with a repeating effect.
*/
- @TestApi
@NonNull
- public Composition addEffect(@NonNull VibrationEffect effect) {
- return addEffect(effect, /* delay= */ 0);
+ public Composition addOffDuration(@NonNull Duration duration) {
+ int durationMs = (int) duration.toMillis();
+ Preconditions.checkArgumentNonnegative(durationMs, "Off period must be non-negative");
+ if (durationMs > 0) {
+ // Created a segment sustaining the zero amplitude to represent the delay.
+ addSegment(new StepSegment(/* amplitude= */ 0, /* frequencyHz= */ 0,
+ (int) duration.toMillis()));
+ }
+ return this;
}
/**
* Add a haptic effect to the end of the current composition.
*
- * @param effect The effect to add to this composition as a primitive
- * @param delay The amount of time in milliseconds to wait before playing this primitive
- * @return The {@link Composition} object to enable adding multiple primitives in one chain.
- * @hide
+ * <p>If this effect is repeating (e.g. created by {@link VibrationEffect#createWaveform}
+ * with a non-negative repeat index, or created by another composition that has effects
+ * repeating indefinitely), then no more effects or primitives will be accepted by this
+ * composition after this method. Such effects should be cancelled via
+ * {@link Vibrator#cancel()}.
+ *
+ * @param effect The effect to add to the end of this composition.
+ * @return This {@link Composition} object to enable adding multiple elements in one chain.
+ *
+ * @throws UnreachableAfterRepeatingIndefinitelyException if the composition is currently
+ * ending with a repeating effect.
*/
- @TestApi
@NonNull
- public Composition addEffect(@NonNull VibrationEffect effect,
- @IntRange(from = 0) int delay) {
- Preconditions.checkArgumentNonnegative(delay);
- if (delay > 0) {
- // Created a segment sustaining the zero amplitude to represent the delay.
- addSegment(new StepSegment(/* amplitude= */ 0, /* frequencyHz= */ 0,
- /* duration= */ delay));
- }
+ public Composition addEffect(@NonNull VibrationEffect effect) {
return addSegments(effect);
}
/**
+ * Add a haptic effect to the end of the current composition and play it on repeat,
+ * indefinitely.
+ *
+ * <p>The entire effect will be played on repeat, indefinitely, after all other elements
+ * already added to this composition are played. No more effects or primitives will be
+ * accepted by this composition after this method. Such effects should be cancelled via
+ * {@link Vibrator#cancel()}.
+ *
+ * @param effect The effect to add to the end of this composition, must be finite.
+ * @return This {@link Composition} object to enable adding multiple elements in one chain,
+ * although only {@link #compose()} can follow this call.
+ *
+ * @throws IllegalArgumentException if the given effect is already repeating indefinitely.
+ * @throws UnreachableAfterRepeatingIndefinitelyException if the composition is currently
+ * ending with a repeating effect.
+ */
+ @NonNull
+ public Composition repeatEffectIndefinitely(@NonNull VibrationEffect effect) {
+ Preconditions.checkArgument(effect.getDuration() < Long.MAX_VALUE,
+ "Can't repeat an indefinitely repeating effect. Consider addEffect instead.");
+ int previousSegmentCount = mSegments.size();
+ addSegments(effect);
+ // Set repeat after segments were added, since addSegments checks this index.
+ mRepeatIndex = previousSegmentCount;
+ return this;
+ }
+
+ /**
* Add a haptic primitive to the end of the current composition.
*
* Similar to {@link #addPrimitive(int, float, int)}, but with no delay and a
* default scale applied.
*
* @param primitiveId The primitive to add
+ * @return This {@link Composition} object to enable adding multiple elements in one chain.
*
- * @return The {@link Composition} object to enable adding multiple primitives in one chain.
+ * @throws UnreachableAfterRepeatingIndefinitelyException if the composition is currently
+ * ending with a repeating effect.
*/
@NonNull
public Composition addPrimitive(@PrimitiveType int primitiveId) {
@@ -894,8 +983,10 @@
*
* @param primitiveId The primitive to add
* @param scale The scale to apply to the intensity of the primitive.
+ * @return This {@link Composition} object to enable adding multiple elements in one chain.
*
- * @return The {@link Composition} object to enable adding multiple primitives in one chain.
+ * @throws UnreachableAfterRepeatingIndefinitelyException if the composition is currently
+ * ending with a repeating effect.
*/
@NonNull
public Composition addPrimitive(@PrimitiveType int primitiveId,
@@ -910,7 +1001,10 @@
* @param scale The scale to apply to the intensity of the primitive.
* @param delay The amount of time in milliseconds to wait before playing this primitive,
* starting at the time the previous element in this composition is finished.
- * @return The {@link Composition} object to enable adding multiple primitives in one chain.
+ * @return This {@link Composition} object to enable adding multiple elements in one chain.
+ *
+ * @throws UnreachableAfterRepeatingIndefinitelyException if the composition is currently
+ * ending with a repeating effect.
*/
@NonNull
public Composition addPrimitive(@PrimitiveType int primitiveId,
@@ -923,9 +1017,7 @@
private Composition addSegment(VibrationEffectSegment segment) {
if (mRepeatIndex >= 0) {
- throw new IllegalStateException(
- "Composition already have a repeating effect so any new primitive would be"
- + " unreachable.");
+ throw new UnreachableAfterRepeatingIndefinitelyException();
}
mSegments.add(segment);
return this;
@@ -933,9 +1025,7 @@
private Composition addSegments(VibrationEffect effect) {
if (mRepeatIndex >= 0) {
- throw new IllegalStateException(
- "Composition already have a repeating effect so any new primitive would be"
- + " unreachable.");
+ throw new UnreachableAfterRepeatingIndefinitelyException();
}
Composed composed = (Composed) effect;
if (composed.getRepeatIndex() >= 0) {
@@ -1001,162 +1091,251 @@
/**
* A builder for waveform haptic effects.
*
- * <p>Waveform vibrations constitute of one or more timed segments where the vibration
- * amplitude, frequency or both can linearly ramp to new values.
+ * <p>Waveform vibrations constitute of one or more timed transitions to new sets of vibration
+ * parameters. These parameters can be the vibration amplitude or frequency, for example.
*
- * <p>Waveform segments may have zero duration, which represent a jump to new vibration
- * amplitude and/or frequency values.
+ * <p>Note that physical vibration actuators have different reaction times for changing
+ * amplitude and frequency. Durations specified here represent a timeline for the target
+ * parameters, and quality of effects may be improved if the durations allow time for a
+ * transition to be smoothly applied.
*
- * <p>Waveform segments may have the same start and end vibration amplitude and frequency,
- * which represent a step where the amplitude and frequency are maintained for that duration.
+ * <p>Repeating waveforms can be built by constructing the repeating block separately and adding
+ * it to the end of a composition using
+ * {@link Composition#repeatEffectIndefinitely(VibrationEffect)}.
*
- * @hide
- * @see VibrationEffect#startWaveform()
+ * @see VibrationEffect#startWaveform
*/
- @TestApi
public static final class WaveformBuilder {
+ // Epsilon used for float comparison of amplitude and frequency values on transitions.
+ private static final float EPSILON = 1e-5f;
+
private ArrayList<VibrationEffectSegment> mSegments = new ArrayList<>();
+ private float mLastAmplitude = 0f;
+ private float mLastFrequencyHz = 0f;
WaveformBuilder() {}
/**
- * Vibrate with given amplitude for the given duration, in millis, keeping the previous
- * frequency the same.
+ * Add a transition to new vibration parameter value to the end of this waveform.
*
- * <p>If the duration is zero the vibrator will jump to new amplitude.
+ * <p>The duration represents how long the vibrator should take to smoothly transition to
+ * the new vibration parameter. If the duration is zero then the vibrator will jump to the
+ * new value as fast as possible.
*
- * @param amplitude The amplitude for this step
- * @param duration The duration of this step in milliseconds
- * @return The {@link WaveformBuilder} object to enable adding multiple steps in chain.
+ * <p>Vibration parameter values will be truncated to conform to the device capabilities
+ * according to the {@link android.os.vibrator.VibratorFrequencyProfile}.
+ *
+ * @param duration The length of time this transition should take. Value must be
+ * non-negative and will be truncated to milliseconds.
+ * @param targetParameter The new target {@link VibrationParameter} value to be reached
+ * after the given duration.
+ * @return This {@link WaveformBuilder} object to enable adding multiple transitions in
+ * chain.
*/
- @SuppressLint("MissingGetterMatchingBuilder")
+ @SuppressWarnings("MissingGetterMatchingBuilder") // No getters to segments once created.
@NonNull
- public WaveformBuilder addStep(@FloatRange(from = 0f, to = 1f) float amplitude,
- @IntRange(from = 0) int duration) {
- mSegments.add(new StepSegment(amplitude, getPreviousFrequencyHz(), duration));
+ public WaveformBuilder addTransition(@NonNull Duration duration,
+ @NonNull VibrationParameter targetParameter) {
+ Preconditions.checkNotNull(duration, "Duration is null");
+ checkVibrationParameter(targetParameter, "targetParameter");
+ float amplitude = extractTargetAmplitude(targetParameter, /* target2= */ null);
+ float frequencyHz = extractTargetFrequency(targetParameter, /* target2= */ null);
+ addTransitionSegment(duration, amplitude, frequencyHz);
return this;
}
/**
- * Vibrate with given amplitude and frequency for the given duration, in millis.
+ * Add a transition to new vibration parameters to the end of this waveform.
*
- * <p>If the duration is zero the vibrator will jump to new amplitude.
+ * <p>The duration represents how long the vibrator should take to smoothly transition to
+ * the new vibration parameters. If the duration is zero then the vibrator will jump to the
+ * new values as fast as possible.
*
- * @param amplitude The amplitude for this step
- * @param frequencyHz The frequency for this step, in hertz
- * @param duration The duration of this step in milliseconds
- * @return The {@link WaveformBuilder} object to enable adding multiple steps in chain.
+ * <p>Vibration parameters values will be truncated to conform to the device capabilities
+ * according to the {@link android.os.vibrator.VibratorFrequencyProfile}.
+ *
+ * @param duration The length of time this transition should take. Value must be
+ * non-negative and will be truncated to milliseconds.
+ * @param targetParameter1 The first target {@link VibrationParameter} value to be reached
+ * after the given duration.
+ * @param targetParameter2 The second target {@link VibrationParameter} value to be reached
+ * after the given duration, must be a different type of parameter
+ * than the one specified by the first argument.
+ * @return This {@link WaveformBuilder} object to enable adding multiple transitions in
+ * chain.
*/
- @SuppressLint("MissingGetterMatchingBuilder")
+ @SuppressWarnings("MissingGetterMatchingBuilder") // No getters to segments once created.
@NonNull
- public WaveformBuilder addStep(@FloatRange(from = 0f, to = 1f) float amplitude,
- @FloatRange(from = 1f) float frequencyHz,
- @IntRange(from = 0) int duration) {
- Preconditions.checkArgument(frequencyHz >= 1, "Frequency must be >= 1");
- mSegments.add(new StepSegment(amplitude, frequencyHz, duration));
+ public WaveformBuilder addTransition(@NonNull Duration duration,
+ @NonNull VibrationParameter targetParameter1,
+ @NonNull VibrationParameter targetParameter2) {
+ Preconditions.checkNotNull(duration, "Duration is null");
+ checkVibrationParameter(targetParameter1, "targetParameter1");
+ checkVibrationParameter(targetParameter2, "targetParameter2");
+ Preconditions.checkArgument(
+ !Objects.equals(targetParameter1.getClass(), targetParameter2.getClass()),
+ "Parameter arguments must specify different parameter types");
+ float amplitude = extractTargetAmplitude(targetParameter1, targetParameter2);
+ float frequencyHz = extractTargetFrequency(targetParameter1, targetParameter2);
+ addTransitionSegment(duration, amplitude, frequencyHz);
return this;
}
/**
- * Ramp vibration linearly for the given duration, in millis, from previous amplitude value
- * to the given one, keeping previous frequency.
+ * Add a duration to sustain the last vibration parameters of this waveform.
*
- * <p>If the duration is zero the vibrator will jump to new amplitude.
+ * <p>The duration represents how long the vibrator should sustain the last set of
+ * parameters provided to this builder.
*
- * @param amplitude The final amplitude this ramp should reach
- * @param duration The duration of this ramp in milliseconds
- * @return The {@link WaveformBuilder} object to enable adding multiple steps in chain.
+ * @param duration The length of time the last values should be sustained by the vibrator.
+ * Value must be >= 1ms.
+ * @return This {@link WaveformBuilder} object to enable adding multiple transitions in
+ * chain.
*/
- @SuppressLint("MissingGetterMatchingBuilder")
+ @SuppressWarnings("MissingGetterMatchingBuilder") // No getters to segments once created.
@NonNull
- public WaveformBuilder addRamp(@FloatRange(from = 0f, to = 1f) float amplitude,
- @IntRange(from = 0) int duration) {
- mSegments.add(new RampSegment(getPreviousAmplitude(), amplitude,
- getPreviousFrequencyHz(), getPreviousFrequencyHz(), duration));
+ public WaveformBuilder addSustain(@NonNull Duration duration) {
+ int durationMs = (int) duration.toMillis();
+ Preconditions.checkArgument(durationMs >= 1, "Sustain duration must be >= 1ms");
+ mSegments.add(new StepSegment(mLastAmplitude, mLastFrequencyHz, durationMs));
return this;
}
/**
- * Ramp vibration linearly for the given duration, in millis, from previous amplitude and
- * frequency values to the given ones.
- *
- * <p>If the duration is zero the vibrator will jump to new amplitude and frequency.
- *
- * @param amplitude The final amplitude this ramp should reach
- * @param frequencyHz The final frequency this ramp should reach, in hertz
- * @param duration The duration of this ramp in milliseconds
- * @return The {@link WaveformBuilder} object to enable adding multiple steps in chain.
- */
- @SuppressLint("MissingGetterMatchingBuilder")
- @NonNull
- public WaveformBuilder addRamp(@FloatRange(from = 0f, to = 1f) float amplitude,
- @FloatRange(from = 1f) float frequencyHz,
- @IntRange(from = 0) int duration) {
- Preconditions.checkArgument(frequencyHz >= 1, "Frequency must be >= 1");
- mSegments.add(new RampSegment(getPreviousAmplitude(), amplitude,
- getPreviousFrequencyHz(), frequencyHz, duration));
- return this;
- }
-
- /**
- * Compose all the steps together into a single {@link VibrationEffect}.
+ * Build the waveform as a single {@link VibrationEffect}.
*
* The {@link WaveformBuilder} object is still valid after this call, so you can
* continue adding more primitives to it and generating more {@link VibrationEffect}s by
* calling this method again.
*
- * @return The {@link VibrationEffect} resulting from the composition of the steps.
+ * @return The {@link VibrationEffect} resulting from the list of transitions.
*/
@NonNull
public VibrationEffect build() {
- return build(/* repeat= */ -1);
- }
-
- /**
- * Compose all the steps together into a single {@link VibrationEffect}.
- *
- * <p>To cause the pattern to repeat, pass the index at which to start the repetition
- * (starting at 0), or -1 to disable repeating.
- *
- * <p>The {@link WaveformBuilder} object is still valid after this call, so you can
- * continue adding more primitives to it and generating more {@link VibrationEffect}s by
- * calling this method again.
- *
- * @return The {@link VibrationEffect} resulting from the composition of the steps.
- */
- @NonNull
- public VibrationEffect build(int repeat) {
if (mSegments.isEmpty()) {
throw new IllegalStateException(
- "WaveformBuilder must have at least one element to build.");
+ "WaveformBuilder must have at least one transition to build.");
}
- VibrationEffect effect = new Composed(mSegments, repeat);
+ VibrationEffect effect = new Composed(mSegments, /* repeatIndex= */ -1);
effect.validate();
return effect;
}
- private float getPreviousFrequencyHz() {
- if (!mSegments.isEmpty()) {
- VibrationEffectSegment segment = mSegments.get(mSegments.size() - 1);
- if (segment instanceof StepSegment) {
- return ((StepSegment) segment).getFrequencyHz();
- } else if (segment instanceof RampSegment) {
- return ((RampSegment) segment).getEndFrequencyHz();
- }
- }
- return 0;
+ private void checkVibrationParameter(@NonNull VibrationParameter vibrationParameter,
+ String paramName) {
+ Preconditions.checkNotNull(vibrationParameter, "%s is null", paramName);
+ Preconditions.checkArgument(
+ (vibrationParameter instanceof AmplitudeVibrationParameter)
+ || (vibrationParameter instanceof FrequencyVibrationParameter),
+ "%s is a unknown parameter", paramName);
}
- private float getPreviousAmplitude() {
- if (!mSegments.isEmpty()) {
- VibrationEffectSegment segment = mSegments.get(mSegments.size() - 1);
- if (segment instanceof StepSegment) {
- return ((StepSegment) segment).getAmplitude();
- } else if (segment instanceof RampSegment) {
- return ((RampSegment) segment).getEndAmplitude();
+ private float extractTargetAmplitude(@Nullable VibrationParameter target1,
+ @Nullable VibrationParameter target2) {
+ if (target2 instanceof AmplitudeVibrationParameter) {
+ return ((AmplitudeVibrationParameter) target2).amplitude;
+ }
+ if (target1 instanceof AmplitudeVibrationParameter) {
+ return ((AmplitudeVibrationParameter) target1).amplitude;
+ }
+ return mLastAmplitude;
+ }
+
+ private float extractTargetFrequency(@Nullable VibrationParameter target1,
+ @Nullable VibrationParameter target2) {
+ if (target2 instanceof FrequencyVibrationParameter) {
+ return ((FrequencyVibrationParameter) target2).frequencyHz;
+ }
+ if (target1 instanceof FrequencyVibrationParameter) {
+ return ((FrequencyVibrationParameter) target1).frequencyHz;
+ }
+ return mLastFrequencyHz;
+ }
+
+ private void addTransitionSegment(Duration duration, float targetAmplitude,
+ float targetFrequency) {
+ Preconditions.checkNotNull(duration, "Duration is null");
+ Preconditions.checkArgument(!duration.isNegative(),
+ "Transition duration must be non-negative");
+ int durationMs = (int) duration.toMillis();
+
+ // Ignore transitions with zero duration, but keep values for next additions.
+ if (durationMs > 0) {
+ if ((Math.abs(mLastAmplitude - targetAmplitude) < EPSILON)
+ && (Math.abs(mLastFrequencyHz - targetFrequency) < EPSILON)) {
+ // No value is changing, this can be best represented by a step segment.
+ mSegments.add(new StepSegment(targetAmplitude, targetFrequency, durationMs));
+ } else {
+ mSegments.add(new RampSegment(mLastAmplitude, targetAmplitude,
+ mLastFrequencyHz, targetFrequency, durationMs));
}
}
- return 0;
+
+ mLastAmplitude = targetAmplitude;
+ mLastFrequencyHz = targetFrequency;
+ }
+ }
+
+ /**
+ * A representation of a single vibration parameter.
+ *
+ * <p>This is to describe a waveform haptic effect, which consists of one or more timed
+ * transitions to a new set of {@link VibrationParameter}s.
+ *
+ * <p>Examples of concrete parameters are the vibration amplitude or frequency.
+ *
+ * @see VibrationEffect.WaveformBuilder
+ */
+ @SuppressWarnings("UserHandleName") // This is not a regular set of parameters, no *Params.
+ public static class VibrationParameter {
+ VibrationParameter() {
+ }
+
+ /**
+ * The target vibration amplitude.
+ *
+ * @param amplitude The amplitude value, between 0 and 1, inclusive, where 0 represents the
+ * vibrator turned off and 1 represents the maximum amplitude the vibrator
+ * can reach across all supported frequencies.
+ * @return The {@link VibrationParameter} instance that represents given amplitude.
+ */
+ @NonNull
+ public static VibrationParameter targetAmplitude(
+ @FloatRange(from = 0, to = 1) float amplitude) {
+ return new AmplitudeVibrationParameter(amplitude);
+ }
+
+ /**
+ * The target vibration frequency.
+ *
+ * @param frequencyHz The frequency value, in hertz.
+ * @return The {@link VibrationParameter} instance that represents given frequency.
+ */
+ @NonNull
+ public static VibrationParameter targetFrequency(@FloatRange(from = 1) float frequencyHz) {
+ return new FrequencyVibrationParameter(frequencyHz);
+ }
+ }
+
+ /** The vibration amplitude, represented by a value in [0,1]. */
+ private static final class AmplitudeVibrationParameter extends VibrationParameter {
+ public final float amplitude;
+
+ AmplitudeVibrationParameter(float amplitude) {
+ Preconditions.checkArgument((amplitude >= 0) && (amplitude <= 1),
+ "Amplitude must be within [0,1]");
+ this.amplitude = amplitude;
+ }
+ }
+
+ /** The vibration frequency, in hertz, or zero to represent undefined frequency. */
+ private static final class FrequencyVibrationParameter extends VibrationParameter {
+ public final float frequencyHz;
+
+ FrequencyVibrationParameter(float frequencyHz) {
+ Preconditions.checkArgument(frequencyHz >= 1, "Frequency must be >= 1");
+ Preconditions.checkArgument(Float.isFinite(frequencyHz), "Frequency must be finite");
+ this.frequencyHz = frequencyHz;
}
}
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 32054b1..ccf1e44 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -298,7 +298,7 @@
*/
void grantInputChannel(int displayId, in SurfaceControl surface, in IWindow window,
in IBinder hostInputToken, int flags, int privateFlags, int type,
- in IBinder focusGrantToken, out InputChannel outInputChannel);
+ out InputChannel outInputChannel);
/**
* Update the flags on an input channel associated with a particular surface.
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index 22baa69..85a9dbd 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -274,7 +274,7 @@
public @Nullable SurfacePackage getSurfacePackage() {
if (mSurfaceControl != null && mAccessibilityEmbeddedConnection != null) {
return new SurfacePackage(mSurfaceControl, mAccessibilityEmbeddedConnection,
- mWm.getFocusGrantToken(), mRemoteInterface);
+ mViewRoot.getInputToken(), mRemoteInterface);
} else {
return null;
}
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 5ec9654..3392edc 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -21,7 +21,6 @@
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Region;
-import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteCallback;
import android.os.RemoteException;
@@ -76,7 +75,6 @@
private final Configuration mConfiguration;
private final IWindowSession mRealWm;
private final IBinder mHostInputToken;
- private final IBinder mFocusGrantToken = new Binder();
private int mForceHeight = -1;
private int mForceWidth = -1;
@@ -93,10 +91,6 @@
mConfiguration.setTo(configuration);
}
- IBinder getFocusGrantToken() {
- return mFocusGrantToken;
- }
-
/**
* Utility API.
*/
@@ -159,10 +153,10 @@
mRealWm.grantInputChannel(displayId,
new SurfaceControl(sc, "WindowlessWindowManager.addToDisplay"),
window, mHostInputToken, attrs.flags, attrs.privateFlags, attrs.type,
- mFocusGrantToken, outInputChannel);
+ outInputChannel);
} else {
mRealWm.grantInputChannel(displayId, sc, window, mHostInputToken, attrs.flags,
- attrs.privateFlags, attrs.type, mFocusGrantToken, outInputChannel);
+ attrs.privateFlags, attrs.type, outInputChannel);
}
} catch (RemoteException e) {
Log.e(TAG, "Failed to grant input to surface: ", e);
@@ -475,7 +469,7 @@
@Override
public void grantInputChannel(int displayId, SurfaceControl surface, IWindow window,
- IBinder hostInputToken, int flags, int privateFlags, int type, IBinder focusGrantToken,
+ IBinder hostInputToken, int flags, int privateFlags, int type,
InputChannel outInputChannel) {
}
diff --git a/core/java/android/window/SplashScreenView.java b/core/java/android/window/SplashScreenView.java
index f04155d..b90e628 100644
--- a/core/java/android/window/SplashScreenView.java
+++ b/core/java/android/window/SplashScreenView.java
@@ -151,6 +151,7 @@
private Instant mIconAnimationStart;
private Duration mIconAnimationDuration;
private Consumer<Runnable> mUiThreadInitTask;
+ private boolean mAllowHandleEmpty = true;
public Builder(@NonNull Context context) {
mContext = context;
@@ -258,6 +259,15 @@
}
/**
+ * Sets whether this view can be copied and transferred to the client if the view is
+ * empty style splash screen.
+ */
+ public Builder setAllowHandleEmpty(boolean allowHandleEmpty) {
+ mAllowHandleEmpty = allowHandleEmpty;
+ return this;
+ }
+
+ /**
* Create SplashScreenWindowView object from materials.
*/
public SplashScreenView build() {
@@ -303,7 +313,7 @@
}
view.mIconView = imageView;
}
- if (mOverlayDrawable != null || mIconDrawable == null) {
+ if (mOverlayDrawable != null || (view.mIconView == null && !mAllowHandleEmpty)) {
view.setNotCopyable();
}
@@ -720,13 +730,15 @@
private RemoteCallback mClientCallback;
public SplashScreenViewParcelable(SplashScreenView view) {
- mIconSize = view.mIconView.getWidth();
+ final View iconView = view.getIconView();
+ mIconSize = iconView != null ? iconView.getWidth() : 0;
mBackgroundColor = view.getInitBackgroundColor();
- mIconBackground = copyDrawable(view.getIconView().getBackground());
+ mIconBackground = iconView != null ? copyDrawable(iconView.getBackground()) : null;
mSurfacePackage = view.mSurfacePackageCopy;
if (mSurfacePackage == null) {
// We only need to copy the drawable if we are not using a SurfaceView
- mIconBitmap = copyDrawable(((ImageView) view.getIconView()).getDrawable());
+ mIconBitmap = iconView != null
+ ? copyDrawable(((ImageView) view.getIconView()).getDrawable()) : null;
}
mBrandingBitmap = copyDrawable(view.getBrandingView().getBackground());
diff --git a/core/java/android/window/StartingWindowInfo.java b/core/java/android/window/StartingWindowInfo.java
index aec910b..24899a4 100644
--- a/core/java/android/window/StartingWindowInfo.java
+++ b/core/java/android/window/StartingWindowInfo.java
@@ -116,6 +116,7 @@
TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT,
TYPE_PARAMETER_ACTIVITY_CREATED,
TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN,
+ TYPE_PARAMETER_ALLOW_HANDLE_EMPTY_SCREEN,
TYPE_PARAMETER_LEGACY_SPLASH_SCREEN
})
public @interface StartingTypeParams {}
@@ -141,6 +142,11 @@
*/
public static final int TYPE_PARAMETER_ACTIVITY_DRAWN = 0x00000040;
/**
+ * Application is allowed to handle empty splash screen.
+ * @hide
+ */
+ public static final int TYPE_PARAMETER_ALLOW_HANDLE_EMPTY_SCREEN = 0x00000080;
+ /**
* Application is allowed to use the legacy splash screen
* @hide
*/
@@ -185,6 +191,13 @@
readFromParcel(source);
}
+ /**
+ * Return whether the application allow to handle the empty style splash screen.
+ */
+ public boolean allowHandleEmptySplashScreen() {
+ return (startingWindowTypeParameter & TYPE_PARAMETER_ALLOW_HANDLE_EMPTY_SCREEN) != 0;
+ }
+
@Override
public int describeContents() {
return 0;
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 8213c86..25ee2d0 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -13223,59 +13223,57 @@
long totalRxPackets = 0;
long totalTxPackets = 0;
if (delta != null) {
- NetworkStats.Entry entry = new NetworkStats.Entry();
- final int size = delta.size();
- for (int i = 0; i < size; i++) {
- entry = delta.getValues(i, entry);
- if (entry.rxPackets == 0 && entry.txPackets == 0) {
+ for (NetworkStats.Entry entry : delta) {
+ if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) {
continue;
}
if (DEBUG_ENERGY) {
- Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes
- + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
- + " txPackets=" + entry.txPackets);
+ Slog.d(TAG, "Mobile uid " + entry.getUid() + ": delta rx="
+ + entry.getRxBytes() + " tx=" + entry.getTxBytes()
+ + " rxPackets=" + entry.getRxPackets()
+ + " txPackets=" + entry.getTxPackets());
}
- totalRxPackets += entry.rxPackets;
- totalTxPackets += entry.txPackets;
+ totalRxPackets += entry.getRxPackets();
+ totalTxPackets += entry.getTxPackets();
- final Uid u = getUidStatsLocked(mapUid(entry.uid), elapsedRealtimeMs, uptimeMs);
- u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
- entry.rxPackets);
- u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
- entry.txPackets);
- if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
+ final Uid u = getUidStatsLocked(
+ mapUid(entry.getUid()), elapsedRealtimeMs, uptimeMs);
+ u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.getRxBytes(),
+ entry.getRxPackets());
+ u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.getTxBytes(),
+ entry.getTxPackets());
+ if (entry.getSet() == NetworkStats.SET_DEFAULT) { // Background transfers
u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA,
- entry.rxBytes, entry.rxPackets);
+ entry.getRxBytes(), entry.getRxPackets());
u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA,
- entry.txBytes, entry.txPackets);
+ entry.getTxBytes(), entry.getTxPackets());
}
mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
- entry.rxBytes);
+ entry.getRxBytes());
mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
- entry.txBytes);
+ entry.getTxBytes());
mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
- entry.rxPackets);
+ entry.getRxPackets());
mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
- entry.txPackets);
+ entry.getTxPackets());
}
// Now distribute proportional blame to the apps that did networking.
long totalPackets = totalRxPackets + totalTxPackets;
if (totalPackets > 0) {
- for (int i = 0; i < size; i++) {
- entry = delta.getValues(i, entry);
- if (entry.rxPackets == 0 && entry.txPackets == 0) {
+ for (NetworkStats.Entry entry : delta) {
+ if (entry.getRxPackets() == 0 && entry.getTxPackets() == 0) {
continue;
}
- final Uid u = getUidStatsLocked(mapUid(entry.uid),
+ final Uid u = getUidStatsLocked(mapUid(entry.getUid()),
elapsedRealtimeMs, uptimeMs);
// Distribute total radio active time in to this app.
- final long appPackets = entry.rxPackets + entry.txPackets;
+ final long appPackets = entry.getRxPackets() + entry.getTxPackets();
final long appRadioTimeUs =
(totalAppRadioTimeUs * appPackets) / totalPackets;
u.noteMobileRadioActiveTimeLocked(appRadioTimeUs, elapsedRealtimeMs);
@@ -13296,17 +13294,17 @@
if (deltaInfo != null) {
ControllerActivityCounterImpl activityCounter =
u.getOrCreateModemControllerActivityLocked();
- if (totalRxPackets > 0 && entry.rxPackets > 0) {
- final long rxMs = (entry.rxPackets
+ if (totalRxPackets > 0 && entry.getRxPackets() > 0) {
+ final long rxMs = (entry.getRxPackets()
* deltaInfo.getReceiveTimeMillis()) / totalRxPackets;
activityCounter.getOrCreateRxTimeCounter()
.increment(rxMs, elapsedRealtimeMs);
}
- if (totalTxPackets > 0 && entry.txPackets > 0) {
+ if (totalTxPackets > 0 && entry.getTxPackets() > 0) {
for (int lvl = 0; lvl < ModemActivityInfo.getNumTxPowerLevels();
lvl++) {
- long txMs = entry.txPackets
+ long txMs = entry.getTxPackets()
* deltaInfo.getTransmitDurationMillisAtPowerLevel(lvl);
txMs /= totalTxPackets;
activityCounter.getOrCreateTxTimeCounters()[lvl]
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1897788..5fee1fa 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4956,6 +4956,9 @@
Used by ChooserActivity. -->
<string translatable="false" name="config_defaultNearbySharingComponent"></string>
+ <!-- URI used for Nearby Share SliceProvider scanning. -->
+ <string translatable="false" name="config_defaultNearbySharingSliceUri"></string>
+
<!-- Boolean indicating whether frameworks needs to reset cell broadcast geo-fencing
check after reboot or airplane mode toggling -->
<bool translatable="false" name="reset_geo_fencing_check_after_boot_or_apm">false</bool>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 3f08e4b..d374b74 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -755,6 +755,8 @@
<dimen name="item_touch_helper_swipe_escape_velocity">120dp</dimen>
<dimen name="item_touch_helper_swipe_escape_max_velocity">800dp</dimen>
+ <!-- The maximum size of the small notification icon. -->
+ <dimen name="notification_small_icon_size">48dp</dimen>
<!-- The maximum height of any image in a remote view. This is applied to all images in custom remoteviews. This value is determined by the maximum notification height -->
<dimen name="notification_custom_view_max_image_height">284dp</dimen>
<!-- The maximum height of any image in a remote view. This is applied to all images in custom remoteviews. This value is determined a maximum notification width -->
@@ -779,6 +781,8 @@
<!-- The alpha of a disabled notification button -->
<item type="dimen" format="float" name="notification_action_disabled_alpha">0.5</item>
+ <!-- The maximum size of the small notification icon on low memory devices. -->
+ <dimen name="notification_small_icon_size_low_ram">@dimen/notification_small_icon_size</dimen>
<!-- The maximum height of any image in a remote view. This is applied to all images in custom remoteviews. -->
<dimen name="notification_custom_view_max_image_height_low_ram">208dp</dimen>
<!-- The maximum height of any image in a remote view. This is applied to all images in custom remoteviews. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3ce6b6c..6ae2829 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3561,6 +3561,7 @@
<java-symbol type="style" name="Theme.DeviceDefault.Autofill.Save" />
<java-symbol type="style" name="Theme.DeviceDefault.Light.Autofill.Save" />
+ <java-symbol type="dimen" name="notification_small_icon_size"/>
<java-symbol type="dimen" name="notification_big_picture_max_height"/>
<java-symbol type="dimen" name="notification_big_picture_max_width"/>
<java-symbol type="dimen" name="notification_right_icon_size"/>
@@ -3569,6 +3570,7 @@
<java-symbol type="dimen" name="notification_custom_view_max_image_height"/>
<java-symbol type="dimen" name="notification_custom_view_max_image_width"/>
+ <java-symbol type="dimen" name="notification_small_icon_size_low_ram"/>
<java-symbol type="dimen" name="notification_big_picture_max_height_low_ram"/>
<java-symbol type="dimen" name="notification_big_picture_max_width_low_ram"/>
<java-symbol type="dimen" name="notification_right_icon_size_low_ram"/>
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index 37cf514..e6d2364 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -39,6 +39,7 @@
import android.content.LocusId;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
+import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.Icon;
@@ -504,6 +505,22 @@
}
@Test
+ public void testBuild_ensureSmallIconIsNotTooBig_resizesIcon() {
+ Icon hugeIcon = Icon.createWithBitmap(
+ Bitmap.createBitmap(3000, 3000, Bitmap.Config.ARGB_8888));
+ Notification notification = new Notification.Builder(mContext, "Channel").setSmallIcon(
+ hugeIcon).build();
+
+ Bitmap smallNotificationIcon = notification.getSmallIcon().getBitmap();
+ assertThat(smallNotificationIcon.getWidth()).isEqualTo(
+ mContext.getResources().getDimensionPixelSize(
+ R.dimen.notification_small_icon_size));
+ assertThat(smallNotificationIcon.getHeight()).isEqualTo(
+ mContext.getResources().getDimensionPixelSize(
+ R.dimen.notification_small_icon_size));
+ }
+
+ @Test
public void testColors_ensureColors_dayMode_producesValidPalette() {
Notification.Colors c = new Notification.Colors();
boolean colorized = false;
diff --git a/core/tests/coretests/src/android/content/pm/AppSearchPersonTest.java b/core/tests/coretests/src/android/content/pm/AppSearchShortcutPersonTest.java
similarity index 92%
rename from core/tests/coretests/src/android/content/pm/AppSearchPersonTest.java
rename to core/tests/coretests/src/android/content/pm/AppSearchShortcutPersonTest.java
index 5ba9059..3c49481 100644
--- a/core/tests/coretests/src/android/content/pm/AppSearchPersonTest.java
+++ b/core/tests/coretests/src/android/content/pm/AppSearchShortcutPersonTest.java
@@ -24,7 +24,7 @@
import org.junit.Test;
@Presubmit
-public class AppSearchPersonTest {
+public class AppSearchShortcutPersonTest {
@Test
public void testBuildPersonAndGetValue() {
@@ -32,7 +32,7 @@
final String key = "key";
final String uri = "name:name";
- final Person person = new AppSearchPerson.Builder(uri)
+ final Person person = new AppSearchShortcutPerson.Builder(uri)
.setName(name)
.setKey(key)
.setIsBot(true)
diff --git a/core/tests/coretests/src/android/os/VibrationEffectTest.java b/core/tests/coretests/src/android/os/VibrationEffectTest.java
index 10cec82..104f077 100644
--- a/core/tests/coretests/src/android/os/VibrationEffectTest.java
+++ b/core/tests/coretests/src/android/os/VibrationEffectTest.java
@@ -16,6 +16,9 @@
package android.os;
+import static android.os.VibrationEffect.VibrationParameter.targetAmplitude;
+import static android.os.VibrationEffect.VibrationParameter.targetFrequency;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
@@ -32,6 +35,7 @@
import android.content.Context;
import android.content.res.Resources;
import android.net.Uri;
+import android.os.VibrationEffect.Composition.UnreachableAfterRepeatingIndefinitelyException;
import android.os.vibrator.PrebakedSegment;
import android.os.vibrator.PrimitiveSegment;
import android.os.vibrator.StepSegment;
@@ -43,6 +47,8 @@
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
+import java.time.Duration;
+
@Presubmit
@RunWith(MockitoJUnitRunner.class)
public class VibrationEffectTest {
@@ -122,16 +128,7 @@
VibrationEffect.createWaveform(TEST_TIMINGS, TEST_AMPLITUDES, -1).validate();
VibrationEffect.createWaveform(new long[]{10, 10}, new int[] {0, 0}, -1).validate();
VibrationEffect.createWaveform(TEST_TIMINGS, TEST_AMPLITUDES, 0).validate();
- VibrationEffect.startWaveform()
- .addStep(/* amplitude= */ 1, /* duration= */ 10)
- .addRamp(/* amplitude= */ 0, /* duration= */ 20)
- .addStep(/* amplitude= */ 1, /* frequencyHz= */ 1, /* duration= */ 100)
- .addRamp(/* amplitude= */ 0.5f, /* frequencyHz= */ 100, /* duration= */ 50)
- .build()
- .validate();
- assertThrows(IllegalStateException.class,
- () -> VibrationEffect.startWaveform().build().validate());
assertThrows(IllegalArgumentException.class,
() -> VibrationEffect.createWaveform(new long[0], new int[0], -1).validate());
assertThrows(IllegalArgumentException.class,
@@ -145,27 +142,31 @@
assertThrows(IllegalArgumentException.class,
() -> VibrationEffect.createWaveform(
TEST_TIMINGS, TEST_AMPLITUDES, TEST_TIMINGS.length).validate());
+ }
+
+ @Test
+ public void testValidateWaveformBuilder() {
+ VibrationEffect.startWaveform(targetAmplitude(1))
+ .addTransition(Duration.ofSeconds(1), targetAmplitude(0.5f), targetFrequency(100))
+ .addTransition(Duration.ZERO, targetAmplitude(0f), targetFrequency(200))
+ .addSustain(Duration.ofMinutes(2))
+ .addTransition(Duration.ofMillis(10), targetAmplitude(1f), targetFrequency(50))
+ .addSustain(Duration.ofMillis(1))
+ .addTransition(Duration.ZERO, targetFrequency(150))
+ .addSustain(Duration.ofMillis(2))
+ .addTransition(Duration.ofSeconds(15), targetAmplitude(1))
+ .build()
+ .validate();
+
+ assertThrows(IllegalStateException.class,
+ () -> VibrationEffect.startWaveform().build().validate());
+ assertThrows(IllegalArgumentException.class, () -> targetAmplitude(-2));
+ assertThrows(IllegalArgumentException.class, () -> targetFrequency(0));
assertThrows(IllegalArgumentException.class,
- () -> VibrationEffect.startWaveform()
- .addStep(/* amplitude= */ -2, 10).build().validate());
+ () -> VibrationEffect.startWaveform().addTransition(
+ Duration.ofMillis(-10), targetAmplitude(1)).build().validate());
assertThrows(IllegalArgumentException.class,
- () -> VibrationEffect.startWaveform()
- .addStep(1, /* frequencyHz= */ -1f, 10).build().validate());
- assertThrows(IllegalArgumentException.class,
- () -> VibrationEffect.startWaveform()
- .addStep(1, /* duration= */ -1).build().validate());
- assertThrows(IllegalArgumentException.class,
- () -> VibrationEffect.startWaveform()
- .addStep(1, 100f, /* duration= */ -1).build().validate());
- assertThrows(IllegalArgumentException.class,
- () -> VibrationEffect.startWaveform()
- .addRamp(/* amplitude= */ -3, 10).build().validate());
- assertThrows(IllegalArgumentException.class,
- () -> VibrationEffect.startWaveform()
- .addRamp(1, /* frequencyHz= */ 0, 10).build().validate());
- assertThrows(IllegalArgumentException.class,
- () -> VibrationEffect.startWaveform()
- .addRamp(1, 10f, /* duration= */ -3).build().validate());
+ () -> VibrationEffect.startWaveform().addSustain(Duration.ZERO).build().validate());
}
@Test
@@ -174,14 +175,24 @@
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
.addEffect(TEST_ONE_SHOT)
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
- .addEffect(TEST_WAVEFORM, 100)
+ .addOffDuration(Duration.ofMillis(100))
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 0.5f, 10)
.addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.compose()
.validate();
+ VibrationEffect.startComposition()
+ .repeatEffectIndefinitely(TEST_ONE_SHOT)
+ .compose()
+ .validate();
+
assertThrows(IllegalStateException.class,
() -> VibrationEffect.startComposition().compose().validate());
+ assertThrows(IllegalStateException.class,
+ () -> VibrationEffect.startComposition()
+ .addOffDuration(Duration.ofSeconds(0))
+ .compose()
+ .validate());
assertThrows(IllegalArgumentException.class,
() -> VibrationEffect.startComposition().addPrimitive(-1).compose().validate());
assertThrows(IllegalArgumentException.class,
@@ -196,12 +207,27 @@
.validate());
assertThrows(IllegalArgumentException.class,
() -> VibrationEffect.startComposition()
- .addEffect(TEST_ONE_SHOT, /* delay= */ -10)
+ .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, -1)
.compose()
.validate());
assertThrows(IllegalArgumentException.class,
() -> VibrationEffect.startComposition()
- .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f, -1)
+ .repeatEffectIndefinitely(
+ // Repeating waveform.
+ VibrationEffect.createWaveform(
+ new long[] { 10 }, new int[] { 100}, 0))
+ .compose()
+ .validate());
+ assertThrows(UnreachableAfterRepeatingIndefinitelyException.class,
+ () -> VibrationEffect.startComposition()
+ .repeatEffectIndefinitely(TEST_WAVEFORM)
+ .addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK)
+ .compose()
+ .validate());
+ assertThrows(UnreachableAfterRepeatingIndefinitelyException.class,
+ () -> VibrationEffect.startComposition()
+ .repeatEffectIndefinitely(TEST_WAVEFORM)
+ .addEffect(TEST_ONE_SHOT)
.compose()
.validate());
}
@@ -354,9 +380,9 @@
assertFalse(VibrationEffect.createWaveform(
new long[]{200, 200, 700}, new int[]{1, 2, 3}, -1).isHapticFeedbackCandidate());
assertFalse(VibrationEffect.startWaveform()
- .addRamp(1, 500)
- .addStep(1, 200)
- .addRamp(0, 500)
+ .addTransition(Duration.ofMillis(500), targetAmplitude(1))
+ .addTransition(Duration.ofMillis(200), targetAmplitude(0.5f))
+ .addTransition(Duration.ofMillis(500), targetAmplitude(0))
.build()
.isHapticFeedbackCandidate());
}
@@ -367,9 +393,9 @@
assertTrue(VibrationEffect.createWaveform(
new long[]{100, 200, 300}, new int[]{1, 2, 3}, -1).isHapticFeedbackCandidate());
assertTrue(VibrationEffect.startWaveform()
- .addRamp(1, 300)
- .addStep(1, 200)
- .addRamp(0, 300)
+ .addTransition(Duration.ofMillis(300), targetAmplitude(1))
+ .addTransition(Duration.ofMillis(200), targetAmplitude(0.5f))
+ .addTransition(Duration.ofMillis(300), targetAmplitude(0))
.build()
.isHapticFeedbackCandidate());
}
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index 69ff7c6..cd42a34 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -81,6 +81,7 @@
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.service.chooser.ChooserTarget;
+import android.util.Log;
import android.view.View;
import androidx.annotation.CallSuper;
@@ -187,7 +188,7 @@
* TODO: remove when we no longer want to test the system's on-the-fly evaluation.
*/
protected boolean shouldTestTogglingAppPredictionServiceAvailabilityAtRuntime() {
- return true;
+ return false;
}
/* --------
@@ -762,6 +763,7 @@
@Test
+ @Ignore
public void testNearbyShareLogging() throws Exception {
Intent sendIntent = createSendTextIntent();
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
@@ -1327,16 +1329,17 @@
final ChooserActivity activity =
mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
-
if (activity.getPackageManager().getAppPredictionServicePackageName() == null) {
assertThat(activity.isAppPredictionServiceAvailable(), is(false));
} else {
- assertThat(activity.isAppPredictionServiceAvailable(), is(true));
-
if (!shouldTestTogglingAppPredictionServiceAvailabilityAtRuntime()) {
return;
}
+ // This isn't a toggle per-se, but isAppPredictionServiceAvailable only works in
+ // system (see comment in the method).
+ assertThat(activity.isAppPredictionServiceAvailable(), is(true));
+
ChooserActivityOverrideData.getInstance().resources =
Mockito.spy(activity.getResources());
when(
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
index d4f08ba..7f85982 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
@@ -51,6 +51,13 @@
static final ChooserActivityOverrideData sOverrides = ChooserActivityOverrideData.getInstance();
private UsageStatsManager mUsm;
+ // ResolverActivity (the base class of ChooserActivity) inspects the launched-from UID at
+ // onCreate and needs to see some non-negative value in the test.
+ @Override
+ public int getLaunchedFromUid() {
+ return 1234;
+ }
+
@Override
protected AbstractMultiProfilePagerAdapter createMultiProfilePagerAdapter(
Intent[] initialIntents, List<ResolveInfo> rList, boolean filterLastUsed) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
index 413627d..e255e44 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java
@@ -54,6 +54,7 @@
import android.view.SurfaceControl;
import android.view.View;
import android.window.SplashScreenView;
+import android.window.StartingWindowInfo;
import android.window.StartingWindowInfo.StartingWindowType;
import com.android.internal.R;
@@ -138,8 +139,8 @@
* executed on splash screen thread. Note that the view can be
* null if failed.
*/
- void createContentView(Context context, @StartingWindowType int suggestType, ActivityInfo info,
- int taskId, Consumer<SplashScreenView> splashScreenViewConsumer,
+ void createContentView(Context context, @StartingWindowType int suggestType,
+ StartingWindowInfo info, Consumer<SplashScreenView> splashScreenViewConsumer,
Consumer<Runnable> uiThreadInitConsumer) {
mSplashscreenWorkerHandler.post(() -> {
SplashScreenView contentView;
@@ -150,7 +151,7 @@
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
} catch (RuntimeException e) {
Slog.w(TAG, "failed creating starting window content at taskId: "
- + taskId, e);
+ + info.taskInfo.taskId, e);
contentView = null;
}
splashScreenViewConsumer.accept(contentView);
@@ -241,7 +242,7 @@
return null;
}
- private SplashScreenView makeSplashScreenContentView(Context context, ActivityInfo ai,
+ private SplashScreenView makeSplashScreenContentView(Context context, StartingWindowInfo info,
@StartingWindowType int suggestType, Consumer<Runnable> uiThreadInitConsumer) {
updateDensity();
@@ -250,6 +251,9 @@
final Drawable legacyDrawable = suggestType == STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN
? peekLegacySplashscreenContent(context, mTmpAttrs) : null;
+ final ActivityInfo ai = info.targetActivityInfo != null
+ ? info.targetActivityInfo
+ : info.taskInfo.topActivityInfo;
final int themeBGColor = legacyDrawable != null
? getBGColorFromCache(ai, () -> estimateWindowBGColor(legacyDrawable))
: getBGColorFromCache(ai, () -> peekWindowBGColor(context, mTmpAttrs));
@@ -258,6 +262,7 @@
.overlayDrawable(legacyDrawable)
.chooseStyle(suggestType)
.setUiThreadInitConsumer(uiThreadInitConsumer)
+ .setAllowHandleEmpty(info.allowHandleEmptySplashScreen())
.build();
}
@@ -327,6 +332,7 @@
private Drawable[] mFinalIconDrawables;
private int mFinalIconSize = mIconSize;
private Consumer<Runnable> mUiThreadInitTask;
+ private boolean mAllowHandleEmpty;
StartingWindowViewBuilder(@NonNull Context context, @NonNull ActivityInfo aInfo) {
mContext = context;
@@ -353,6 +359,11 @@
return this;
}
+ StartingWindowViewBuilder setAllowHandleEmpty(boolean allowHandleEmpty) {
+ mAllowHandleEmpty = allowHandleEmpty;
+ return this;
+ }
+
SplashScreenView build() {
Drawable iconDrawable;
final int animationDuration;
@@ -491,7 +502,8 @@
.setIconBackground(background)
.setCenterViewDrawable(foreground)
.setAnimationDurationMillis(animationDuration)
- .setUiThreadInitConsumer(uiThreadInitTask);
+ .setUiThreadInitConsumer(uiThreadInitTask)
+ .setAllowHandleEmpty(mAllowHandleEmpty);
if (mSuggestType == STARTING_WINDOW_TYPE_SPLASH_SCREEN
&& mTmpAttrs.mBrandingImage != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
index f8902c6..9a966b8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java
@@ -328,7 +328,7 @@
if (mSysuiProxy != null) {
mSysuiProxy.requestTopUi(true, TAG);
}
- mSplashscreenContentDrawer.createContentView(context, suggestType, activityInfo, taskId,
+ mSplashscreenContentDrawer.createContentView(context, suggestType, windowInfo,
viewSupplier::setView, viewSupplier::setUiThreadInitTask);
try {
if (addWindow(taskId, appToken, rootLayout, display, params, suggestType)) {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt
index f8d14c6..af629cc 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/ExpandBubbleScreen.kt
@@ -24,9 +24,6 @@
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.wm.shell.flicker.helpers.BaseAppHelper
-import org.junit.Assume
-import org.junit.Before
import org.junit.runner.RunWith
import org.junit.Test
import org.junit.runners.Parameterized
@@ -62,12 +59,6 @@
}
}
- @Before
- fun setup() {
- // This test doesn't work in shell transitions because of b/205288792
- Assume.assumeFalse(BaseAppHelper.isShellTransitionsEnabled())
- }
-
@Presubmit
@Test
fun testAppIsAlwaysVisible() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt
index c93c5ad..add11c1 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/MultiBubblesScreen.kt
@@ -25,9 +25,6 @@
import com.android.server.wm.flicker.FlickerTestParameter
import com.android.server.wm.flicker.annotation.Group4
import com.android.server.wm.flicker.dsl.FlickerBuilder
-import com.android.wm.shell.flicker.helpers.BaseAppHelper
-import org.junit.Assume
-import org.junit.Before
import org.junit.runner.RunWith
import org.junit.Test
import org.junit.runners.Parameterized
@@ -70,12 +67,6 @@
}
}
- @Before
- fun setup() {
- // This test doesn't work in shell transitions because of b/205288792
- Assume.assumeFalse(BaseAppHelper.isShellTransitionsEnabled())
- }
-
@Presubmit
@Test
fun testAppIsAlwaysVisible() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
index dee13c1..afe64e3 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
@@ -204,7 +204,6 @@
@Presubmit
@Test
fun testAppPlusPipLayerCoversFullScreenOnEnd() {
- // This test doesn't work in shell transitions because of b/206669574
testSpec.assertLayersEnd {
val pipRegion = visibleRegion(pipApp.component).region
visibleRegion(testApp.component)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
index c36dfda..1d61ab4 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
@@ -31,6 +31,7 @@
import com.android.server.wm.traces.common.FlickerComponentName
import com.android.wm.shell.flicker.helpers.ImeAppHelper
import org.junit.Assume.assumeFalse
+import org.junit.Assume.assumeTrue
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -82,6 +83,13 @@
super.statusBarLayerRotatesScales()
}
+ @FlakyTest(bugId = 214452854)
+ @Test
+ fun statusBarLayerRotatesScales_shellTransit() {
+ assumeTrue(isShellTransitionsEnabled)
+ super.statusBarLayerRotatesScales()
+ }
+
/**
* Ensure the pip window remains visible throughout any keyboard interactions
*/
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipLegacySplitScreenTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipLegacySplitScreenTest.kt
index df58194..21175a0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipLegacySplitScreenTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipLegacySplitScreenTest.kt
@@ -92,11 +92,7 @@
/** {@inheritDoc} */
@FlakyTest(bugId = 206753786)
@Test
- override fun statusBarLayerRotatesScales() {
- // This test doesn't work in shell transitions because of b/206753786
- assumeFalse(com.android.server.wm.flicker.helpers.isShellTransitionsEnabled)
- super.statusBarLayerRotatesScales()
- }
+ override fun statusBarLayerRotatesScales() = super.statusBarLayerRotatesScales()
@FlakyTest(bugId = 161435597)
@Test
diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp
index 6989ac0..5db0783 100755
--- a/libs/hwui/jni/Bitmap.cpp
+++ b/libs/hwui/jni/Bitmap.cpp
@@ -686,16 +686,14 @@
}
return data->ptr != nullptr;
}));
- inPlaceCallback(std::move(data.ptr), data.size);
- return STATUS_OK;
+ return inPlaceCallback(std::move(data.ptr), data.size);
} else if (type == BlobType::ASHMEM) {
int rawFd = -1;
int32_t size = 0;
ON_ERROR_RETURN(AParcel_readInt32(parcel, &size));
ON_ERROR_RETURN(AParcel_readParcelFileDescriptor(parcel, &rawFd));
android::base::unique_fd fd(rawFd);
- ashmemCallback(std::move(fd), size);
- return STATUS_OK;
+ return ashmemCallback(std::move(fd), size);
} else {
// Although the above if/else was "exhaustive" guard against unknown types
return STATUS_UNKNOWN_ERROR;
@@ -768,7 +766,7 @@
// framework, we may need to update this maximum size.
static constexpr size_t kMaxColorSpaceSerializedBytes = 80;
-static constexpr auto RuntimeException = "java/lang/RuntimeException";
+static constexpr auto BadParcelableException = "android/os/BadParcelableException";
static bool validateImageInfo(const SkImageInfo& info, int32_t rowBytes) {
// TODO: Can we avoid making a SkBitmap for this?
@@ -809,7 +807,7 @@
kRGB_565_SkColorType != colorType &&
kARGB_4444_SkColorType != colorType &&
kAlpha_8_SkColorType != colorType) {
- jniThrowExceptionFmt(env, RuntimeException,
+ jniThrowExceptionFmt(env, BadParcelableException,
"Bitmap_createFromParcel unknown colortype: %d\n", colorType);
return NULL;
}
@@ -821,7 +819,7 @@
return NULL;
}
if (!Bitmap::computeAllocationSize(rowBytes, height, &allocationSize)) {
- jniThrowExceptionFmt(env, RuntimeException,
+ jniThrowExceptionFmt(env, BadParcelableException,
"Received bad bitmap size: width=%d, height=%d, rowBytes=%d", width,
height, rowBytes);
return NULL;
@@ -831,13 +829,23 @@
p.get(),
// In place callback
[&](std::unique_ptr<int8_t[]> buffer, int32_t size) {
+ if (allocationSize > size) {
+ android_errorWriteLog(0x534e4554, "213169612");
+ return STATUS_BAD_VALUE;
+ }
nativeBitmap = Bitmap::allocateHeapBitmap(allocationSize, imageInfo, rowBytes);
if (nativeBitmap) {
- memcpy(nativeBitmap->pixels(), buffer.get(), size);
+ memcpy(nativeBitmap->pixels(), buffer.get(), allocationSize);
+ return STATUS_OK;
}
+ return STATUS_NO_MEMORY;
},
// Ashmem callback
[&](android::base::unique_fd fd, int32_t size) {
+ if (allocationSize > size) {
+ android_errorWriteLog(0x534e4554, "213169612");
+ return STATUS_BAD_VALUE;
+ }
int flags = PROT_READ;
if (isMutable) {
flags |= PROT_WRITE;
@@ -846,18 +854,21 @@
if (addr == MAP_FAILED) {
const int err = errno;
ALOGW("mmap failed, error %d (%s)", err, strerror(err));
- return;
+ return STATUS_NO_MEMORY;
}
nativeBitmap =
Bitmap::createFrom(imageInfo, rowBytes, fd.release(), addr, size, !isMutable);
+ return STATUS_OK;
});
- if (error != STATUS_OK) {
+
+ if (error != STATUS_OK && error != STATUS_NO_MEMORY) {
// TODO: Stringify the error, see signalExceptionForError in android_util_Binder.cpp
- jniThrowExceptionFmt(env, RuntimeException, "Failed to read from Parcel, error=%d", error);
+ jniThrowExceptionFmt(env, BadParcelableException, "Failed to read from Parcel, error=%d",
+ error);
return nullptr;
}
- if (!nativeBitmap) {
- jniThrowRuntimeException(env, "Could not allocate java pixel ref.");
+ if (error == STATUS_NO_MEMORY || !nativeBitmap) {
+ jniThrowRuntimeException(env, "Could not allocate bitmap data.");
return nullptr;
}
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 09d7fbd..e2e48d3 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -963,7 +963,7 @@
*
* @see HardwareBuffer
*/
- public @NonNull Builder setUsage(long usage) {
+ public @NonNull Builder setUsage(@Usage long usage) {
mUsage = usage;
return this;
}
diff --git a/media/java/android/media/ImageWriter.java b/media/java/android/media/ImageWriter.java
index 6168c22..a1aedf1 100644
--- a/media/java/android/media/ImageWriter.java
+++ b/media/java/android/media/ImageWriter.java
@@ -102,11 +102,10 @@
private int mWidth;
private int mHeight;
private final int mMaxImages;
- private @Usage long mUsage = HardwareBuffer.USAGE_CPU_WRITE_OFTEN;
+ private long mUsage = HardwareBuffer.USAGE_CPU_WRITE_OFTEN;
private @HardwareBuffer.Format int mHardwareBufferFormat;
private @NamedDataSpace long mDataSpace;
private boolean mUseLegacyImageFormat;
- private boolean mUseSurfaceImageFormatInfo;
// Field below is used by native code, do not access or modify.
private int mWriterFormat;
@@ -255,35 +254,38 @@
+ ", maxImages: " + maxImages);
}
- mUseSurfaceImageFormatInfo = useSurfaceImageFormatInfo;
mUseLegacyImageFormat = useLegacyImageFormat;
// Note that the underlying BufferQueue is working in synchronous mode
// to avoid dropping any buffers.
mNativeContext = nativeInit(new WeakReference<>(this), surface, maxImages, width, height,
useSurfaceImageFormatInfo, hardwareBufferFormat, dataSpace, usage);
+ // if useSurfaceImageFormatInfo is true, imageformat should be read from the surface.
if (useSurfaceImageFormatInfo) {
// nativeInit internally overrides UNKNOWN format. So does surface format query after
// nativeInit and before getEstimatedNativeAllocBytes().
imageFormat = SurfaceUtils.getSurfaceFormat(surface);
- // Several public formats use the same native HAL_PIXEL_FORMAT_BLOB. The native
- // allocation estimation sequence depends on the public formats values. To avoid
- // possible errors, convert where necessary.
- if (imageFormat == StreamConfigurationMap.HAL_PIXEL_FORMAT_BLOB) {
- int surfaceDataspace = SurfaceUtils.getSurfaceDataspace(surface);
- switch (surfaceDataspace) {
- case StreamConfigurationMap.HAL_DATASPACE_DEPTH:
- imageFormat = ImageFormat.DEPTH_POINT_CLOUD;
- break;
- case StreamConfigurationMap.HAL_DATASPACE_DYNAMIC_DEPTH:
- imageFormat = ImageFormat.DEPTH_JPEG;
- break;
- case StreamConfigurationMap.HAL_DATASPACE_HEIF:
- imageFormat = ImageFormat.HEIC;
- break;
- default:
- imageFormat = ImageFormat.JPEG;
- }
+ mHardwareBufferFormat = PublicFormatUtils.getHalFormat(imageFormat);
+ mDataSpace = PublicFormatUtils.getHalDataspace(imageFormat);
+ }
+
+ // Several public formats use the same native HAL_PIXEL_FORMAT_BLOB. The native
+ // allocation estimation sequence depends on the public formats values. To avoid
+ // possible errors, convert where necessary.
+ if (imageFormat == StreamConfigurationMap.HAL_PIXEL_FORMAT_BLOB) {
+ int surfaceDataspace = SurfaceUtils.getSurfaceDataspace(surface);
+ switch (surfaceDataspace) {
+ case StreamConfigurationMap.HAL_DATASPACE_DEPTH:
+ imageFormat = ImageFormat.DEPTH_POINT_CLOUD;
+ break;
+ case StreamConfigurationMap.HAL_DATASPACE_DYNAMIC_DEPTH:
+ imageFormat = ImageFormat.DEPTH_JPEG;
+ break;
+ case StreamConfigurationMap.HAL_DATASPACE_HEIF:
+ imageFormat = ImageFormat.HEIC;
+ break;
+ default:
+ imageFormat = ImageFormat.JPEG;
}
mHardwareBufferFormat = PublicFormatUtils.getHalFormat(imageFormat);
mDataSpace = PublicFormatUtils.getHalDataspace(imageFormat);
@@ -307,7 +309,6 @@
private ImageWriter(Surface surface, int maxImages, boolean useSurfaceImageFormatInfo,
int imageFormat, int width, int height) {
mMaxImages = maxImages;
- // update hal format and dataspace only if image format is overridden by producer.
mHardwareBufferFormat = PublicFormatUtils.getHalFormat(imageFormat);
mDataSpace = PublicFormatUtils.getHalDataspace(imageFormat);
@@ -566,6 +567,9 @@
/**
* Get the ImageWriter usage flag.
*
+ * <p>It is not recommended to use this function if {@link Builder#setUsage} is not called.
+ * Invalid usage value will be returned if so.</p>
+ *
* @return The ImageWriter usage flag.
*/
public @Usage long getUsage() {
@@ -873,7 +877,7 @@
private int mHeight = -1;
private int mMaxImages = 1;
private int mImageFormat = ImageFormat.UNKNOWN;
- private @Usage long mUsage = HardwareBuffer.USAGE_CPU_WRITE_OFTEN;
+ private long mUsage = -1;
private @HardwareBuffer.Format int mHardwareBufferFormat = HardwareBuffer.RGBA_8888;
private @NamedDataSpace long mDataSpace = DataSpace.DATASPACE_UNKNOWN;
private boolean mUseSurfaceImageFormatInfo = true;
@@ -885,10 +889,19 @@
/**
* Constructs a new builder for {@link ImageWriter}.
*
+ * <p>Uses {@code surface} input parameter to retrieve image format, hal format
+ * and hal dataspace value for default. </p>
+ *
* @param surface The destination Surface this writer produces Image data into.
+ *
+ * @throws IllegalArgumentException if the surface is already abandoned.
*/
public Builder(@NonNull Surface surface) {
mSurface = surface;
+ // retrieve format from surface
+ mImageFormat = SurfaceUtils.getSurfaceFormat(surface);
+ mDataSpace = SurfaceUtils.getSurfaceDataspace(surface);
+ mHardwareBufferFormat = PublicFormatUtils.getHalFormat(mImageFormat);
}
/**
@@ -926,6 +939,8 @@
* @param imageFormat The format of the {@link ImageWriter}. It can be any valid specified
* by {@link ImageFormat} or {@link PixelFormat}.
* @return the Builder instance with customized image format.
+ *
+ * @throws IllegalArgumentException if {@code imageFormat} is invalid.
*/
@SuppressLint("MissingGetterMatchingBuilder")
public @NonNull Builder setImageFormat(@Format int imageFormat) {
@@ -985,12 +1000,16 @@
/**
* Set the usage flag of this ImageWriter.
- * Default value is {@link HardwareBuffer#USAGE_CPU_WRITE_OFTEN}.
+ *
+ * <p>If this function is not called, usage bit will be set
+ * to {@link HardwareBuffer#USAGE_CPU_WRITE_OFTEN} if the image format is not
+ * {@link ImageFormat#PRIVATE PRIVATE}.</p>
*
* @param usage The intended usage of the images produced by this ImageWriter.
* @return the Builder instance with customized usage flag.
*
* @see HardwareBuffer
+ * @see #getUsage
*/
public @NonNull Builder setUsage(@Usage long usage) {
mUsage = usage;
@@ -1022,6 +1041,7 @@
private int mHeight = -1;
private int mWidth = -1;
private int mFormat = -1;
+ private @NamedDataSpace long mDataSpace = DataSpace.DATASPACE_UNKNOWN;
// When this default timestamp is used, timestamp for the input Image
// will be generated automatically when queueInputBuffer is called.
private final long DEFAULT_TIMESTAMP = Long.MIN_VALUE;
@@ -1034,19 +1054,34 @@
mOwner = writer;
mWidth = writer.mWidth;
mHeight = writer.mHeight;
+ mDataSpace = writer.mDataSpace;
- if (!writer.mUseLegacyImageFormat) {
+ if (!mOwner.mUseLegacyImageFormat) {
mFormat = PublicFormatUtils.getPublicFormat(
- writer.mHardwareBufferFormat, writer.mDataSpace);
+ mOwner.mHardwareBufferFormat, mDataSpace);
}
}
@Override
+ public @NamedDataSpace long getDataSpace() {
+ throwISEIfImageIsInvalid();
+
+ return mDataSpace;
+ }
+
+ @Override
+ public void setDataSpace(@NamedDataSpace long dataSpace) {
+ throwISEIfImageIsInvalid();
+
+ mDataSpace = dataSpace;
+ }
+
+ @Override
public int getFormat() {
throwISEIfImageIsInvalid();
- if (mFormat == -1) {
- mFormat = nativeGetFormat();
+ if (mOwner.mUseLegacyImageFormat && mFormat == -1) {
+ mFormat = nativeGetFormat(mDataSpace);
}
return mFormat;
}
@@ -1114,7 +1149,8 @@
if (mPlanes == null) {
int numPlanes = ImageUtils.getNumPlanesForFormat(getFormat());
- mPlanes = nativeCreatePlanes(numPlanes, getOwner().getFormat());
+ mPlanes = nativeCreatePlanes(numPlanes, getOwner().getFormat(),
+ getOwner().getDataSpace());
}
return mPlanes.clone();
@@ -1222,13 +1258,14 @@
}
// Create the SurfacePlane object and fill the information
- private synchronized native SurfacePlane[] nativeCreatePlanes(int numPlanes, int writerFmt);
+ private synchronized native SurfacePlane[] nativeCreatePlanes(int numPlanes, int writerFmt,
+ long dataSpace);
private synchronized native int nativeGetWidth();
private synchronized native int nativeGetHeight();
- private synchronized native int nativeGetFormat();
+ private synchronized native int nativeGetFormat(long dataSpace);
private synchronized native HardwareBuffer nativeGetHardwareBuffer();
}
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index e75df1d..3fd27d5 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -426,10 +426,30 @@
/** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
public static final int COLOR_Format24BitABGR6666 = 43;
- /** @hide
- * P010 is a 4:2:0 YCbCr semiplanar format comprised of a WxH Y plane
- * followed by a Wx(H/2) CbCr plane. Each sample is represented by a 16-bit
- * little-endian value, with the lower 6 bits set to zero. */
+ /**
+ * P010 is 10-bit-per component 4:2:0 YCbCr semiplanar format.
+ * <p>
+ * This format uses 24 allocated bits per pixel with 15 bits of
+ * data per pixel. Chroma planes are subsampled by 2 both
+ * horizontally and vertically. Each chroma and luma component
+ * has 16 allocated bits in little-endian configuration with 10
+ * MSB of actual data.
+ *
+ * <pre>
+ * byte byte
+ * <--------- i --------> | <------ i + 1 ------>
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ * | UNUSED | Y/Cb/Cr |
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ * 0 5 6 7 0 7
+ * bit
+ * </pre>
+ *
+ * Use this format with {@link Image}. This format corresponds
+ * to {@link android.graphics.ImageFormat#YCBCR_P010}.
+ * <p>
+ */
+ @SuppressLint("AllUpper")
public static final int COLOR_FormatYUVP010 = 54;
/** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
@@ -615,6 +635,24 @@
public static final String FEATURE_EncodingStatistics = "encoding-statistics";
/**
+ * <b>video encoder only</b>: codec supports HDR editing.
+ * <p>
+ * HDR editing support means that the codec accepts 10-bit HDR
+ * input surface, and it is capable of generating any HDR
+ * metadata required from both YUV and RGB input when the
+ * metadata is not present. This feature is only meaningful when
+ * using an HDR capable profile (and 10-bit HDR input).
+ * <p>
+ * This feature implies that the codec is capable of encoding at
+ * least one HDR format, and that it supports RGBA_1010102 as
+ * well as P010, and optionally RGBA_FP16 input formats, and
+ * that the encoder can generate HDR metadata for all supported
+ * HDR input formats.
+ */
+ @SuppressLint("AllUpper")
+ public static final String FEATURE_HdrEditing = "hdr-editing";
+
+ /**
* Query codec feature capabilities.
* <p>
* These features are supported to be used by the codec. These
@@ -654,6 +692,7 @@
new Feature(FEATURE_DynamicTimestamp, (1 << 2), false),
new Feature(FEATURE_QpBounds, (1 << 3), false),
new Feature(FEATURE_EncodingStatistics, (1 << 4), false),
+ new Feature(FEATURE_HdrEditing, (1 << 5), false),
// feature to exclude codec from REGULAR codec list
new Feature(FEATURE_SpecialCodec, (1 << 30), false, true),
};
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index ad8fc07..ea26185 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -1078,8 +1078,8 @@
*
* @throws IOException When an {@link IOException} is thrown while closing a {@link
* MediaDataSource} passed to {@link #setDataSource(MediaDataSource)}. This throws clause exists
- * since API 33, but this method can throw in earlier API versions where the exception is not
- * declared.
+ * since API {@link android.os.Build.VERSION_CODES#TIRAMISU}, but this method can throw in
+ * earlier API versions where the exception is not declared.
*/
@Override
public void close() throws IOException {
@@ -1091,8 +1091,8 @@
*
* @throws IOException When an {@link IOException} is thrown while closing a {@link
* MediaDataSource} passed to {@link #setDataSource(MediaDataSource)}. This throws clause exists
- * since API 33, but this method can throw in earlier API versions where the exception is not
- * declared.
+ * since API {@link android.os.Build.VERSION_CODES#TIRAMISU}, but this method can throw in
+ * earlier API versions where the exception is not declared.
*/
public native void release() throws IOException;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index a6f244f..2772769 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -1059,7 +1059,8 @@
* haptic channels or not. As this function doesn't has a context
* to resolve the uri, the result may be wrong if the uri cannot be
* resolved correctly.
- * Use {@link #hasHapticChannels(int)} instead when possible.
+ * Use {@link #hasHapticChannels(int)} or {@link #hasHapticChannels(Context, Uri)}
+ * instead when possible.
*
* @param ringtoneUri The {@link Uri} of a sound or ringtone.
* @return true if the ringtone contains haptic channels.
@@ -1069,6 +1070,17 @@
}
/**
+ * Returns if the {@link Ringtone} from a given sound URI contains haptics channels or not.
+ *
+ * @param context the {@link android.content.Context} to use when resolving the Uri.
+ * @param ringtoneUri the {@link Uri} of a sound or ringtone.
+ * @return true if the ringtone contains haptic channels.
+ */
+ public static boolean hasHapticChannels(@NonNull Context context, @NonNull Uri ringtoneUri) {
+ return AudioManager.hasHapticChannels(context, ringtoneUri);
+ }
+
+ /**
* Attempts to create a context for the given user.
*
* @return created context, or null if package does not exist
diff --git a/media/java/android/media/tv/AdRequest.java b/media/java/android/media/tv/AdRequest.java
index adcf541..0542c55 100644
--- a/media/java/android/media/tv/AdRequest.java
+++ b/media/java/android/media/tv/AdRequest.java
@@ -29,7 +29,6 @@
/**
* An advertisement request which can be sent to TV input to request AD operations.
- * @hide
*/
public final class AdRequest implements Parcelable {
/** @hide */
diff --git a/media/java/android/media/tv/AdResponse.java b/media/java/android/media/tv/AdResponse.java
index 5dba82c..0c20954 100644
--- a/media/java/android/media/tv/AdResponse.java
+++ b/media/java/android/media/tv/AdResponse.java
@@ -26,7 +26,6 @@
/**
* An advertisement request which can be sent to TV interactive App service to inform AD status.
- * @hide
*/
public final class AdResponse implements Parcelable {
/** @hide */
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index f438d29..cc33a1e 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -394,17 +394,14 @@
/**
* Signal lost.
- * @hide
*/
public static final int SIGNAL_STRENGTH_LOST = 1;
/**
* Weak signal.
- * @hide
*/
public static final int SIGNAL_STRENGTH_WEAK = 2;
/**
* Strong signal.
- * @hide
*/
public static final int SIGNAL_STRENGTH_STRONG = 3;
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 98d4182..f63f444 100755
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -896,7 +896,6 @@
*
* @param response advertisement response.
* @see android.media.tv.interactive.TvInteractiveAppService.Session#requestAd(AdRequest)
- * @hide
*/
public void notifyAdResponse(@NonNull final AdResponse response) {
executeOrPostRunnableOnMainThread(new Runnable() {
@@ -977,7 +976,6 @@
/**
* Notifies signal strength.
- * @hide
*/
public void notifySignalStrength(@TvInputManager.SignalStrength final int strength) {
executeOrPostRunnableOnMainThread(new Runnable() {
@@ -1128,7 +1126,6 @@
* Called when advertisement request is received.
*
* @param request advertisement request received
- * @hide
*/
public void onRequestAd(@NonNull AdRequest request) {
}
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 6c25a70..4d63af7 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -1079,21 +1079,20 @@
/**
* This is called when signal strength is updated.
+ *
* @param inputId The ID of the TV input bound to this view.
* @param strength The current signal strength.
- *
- * @hide
*/
- public void onSignalStrength(String inputId, @TvInputManager.SignalStrength int strength) {
+ public void onSignalStrength(
+ @NonNull String inputId, @TvInputManager.SignalStrength int strength) {
}
/**
* This is called when the session has been tuned to the given channel.
*
* @param channelUri The URI of a channel.
- * @hide
*/
- public void onTuned(String inputId, Uri channelUri) {
+ public void onTuned(@NonNull String inputId, @NonNull Uri channelUri) {
}
}
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
index f1f0af1..4a99715 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
@@ -174,18 +174,15 @@
public @interface TeletextAppState {}
/**
- * Show state of Teletext app.
- * @hide
+ * State of Teletext app: show
*/
public static final int TELETEXT_APP_STATE_SHOW = 1;
/**
- * Hide state of Teletext app.
- * @hide
+ * State of Teletext app: hide
*/
public static final int TELETEXT_APP_STATE_HIDE = 2;
/**
- * Error state of Teletext app.
- * @hide
+ * State of Teletext app: error
*/
public static final int TELETEXT_APP_STATE_ERROR = 3;
@@ -193,9 +190,7 @@
* Key for package name in app link.
* <p>Type: String
*
- * @see #registerAppLinkInfo(String, Bundle)
* @see #sendAppLinkCommand(String, Bundle)
- * @hide
*/
public static final String KEY_PACKAGE_NAME = "package_name";
@@ -203,45 +198,15 @@
* Key for class name in app link.
* <p>Type: String
*
- * @see #registerAppLinkInfo(String, Bundle)
* @see #sendAppLinkCommand(String, Bundle)
- * @hide
*/
public static final String KEY_CLASS_NAME = "class_name";
/**
- * Key for URI scheme in app link.
- * <p>Type: String
- *
- * @see #registerAppLinkInfo(String, Bundle)
- * @hide
- */
- public static final String KEY_URI_SCHEME = "uri_scheme";
-
- /**
- * Key for URI host in app link.
- * <p>Type: String
- *
- * @see #registerAppLinkInfo(String, Bundle)
- * @hide
- */
- public static final String KEY_URI_HOST = "uri_host";
-
- /**
- * Key for URI prefix in app link.
- * <p>Type: String
- *
- * @see #registerAppLinkInfo(String, Bundle)
- * @hide
- */
- public static final String KEY_URI_PREFIX = "uri_prefix";
-
- /**
* Key for command type in app link command.
* <p>Type: String
*
* @see #sendAppLinkCommand(String, Bundle)
- * @hide
*/
public static final String KEY_COMMAND_TYPE = "command_type";
@@ -250,7 +215,6 @@
* <p>Type: String
*
* @see #sendAppLinkCommand(String, Bundle)
- * @hide
*/
public static final String KEY_SERVICE_ID = "service_id";
@@ -259,10 +223,68 @@
* <p>Type: String
*
* @see #sendAppLinkCommand(String, Bundle)
- * @hide
*/
public static final String KEY_BACK_URI = "back_uri";
+ /**
+ * Broadcast intent action to send app command to TV app.
+ *
+ * @see #sendAppLinkCommand(String, Bundle)
+ */
+ public static final String ACTION_APP_LINK_COMMAND =
+ "android.media.tv.interactive.action.APP_LINK_COMMAND";
+
+ /**
+ * Intent key for TV input ID. It's used to send app command to TV app.
+ * <p>Type: String
+ *
+ * @see #sendAppLinkCommand(String, Bundle)
+ * @see #ACTION_APP_LINK_COMMAND
+ */
+ public static final String INTENT_KEY_TV_INPUT_ID = "tv_input_id";
+
+ /**
+ * Intent key for TV interactive app ID. It's used to send app command to TV app.
+ * <p>Type: String
+ *
+ * @see #sendAppLinkCommand(String, Bundle)
+ * @see #ACTION_APP_LINK_COMMAND
+ * @see android.media.tv.interactive.TvInteractiveAppInfo#getId()
+ */
+ public static final String INTENT_KEY_INTERACTIVE_APP_SERVICE_ID = "interactive_app_id";
+
+ /**
+ * Intent key for TV channel URI. It's used to send app command to TV app.
+ * <p>Type: android.net.Uri
+ *
+ * @see #sendAppLinkCommand(String, Bundle)
+ * @see #ACTION_APP_LINK_COMMAND
+ */
+ public static final String INTENT_KEY_CHANNEL_URI = "channel_uri";
+
+ /**
+ * Intent key for broadcast-independent(BI) interactive app type. It's used to send app command
+ * to TV app.
+ * <p>Type: int
+ *
+ * @see #sendAppLinkCommand(String, Bundle)
+ * @see #ACTION_APP_LINK_COMMAND
+ * @see android.media.tv.interactive.TvInteractiveAppInfo#getSupportedTypes()
+ * @see android.media.tv.interactive.TvInteractiveAppView#createBiInteractiveApp(Uri, Bundle)
+ */
+ public static final String INTENT_KEY_BI_INTERACTIVE_APP_TYPE = "bi_interactive_app_type";
+
+ /**
+ * Intent key for broadcast-independent(BI) interactive app URI. It's used to send app command
+ * to TV app.
+ * <p>Type: android.net.Uri
+ *
+ * @see #sendAppLinkCommand(String, Bundle)
+ * @see #ACTION_APP_LINK_COMMAND
+ * @see android.media.tv.interactive.TvInteractiveAppView#createBiInteractiveApp(Uri, Bundle)
+ */
+ public static final String INTENT_KEY_BI_INTERACTIVE_APP_URI = "bi_interactive_app_uri";
+
private final ITvInteractiveAppManager mService;
private final int mUserId;
@@ -358,7 +380,7 @@
@Override
public void onCommandRequest(
- @TvInteractiveAppService.InteractiveAppServiceCommandType String cmdType,
+ @TvInteractiveAppService.PlaybackCommandType String cmdType,
Bundle parameters,
int seq) {
synchronized (mSessionCallbackRecordMap) {
@@ -559,7 +581,6 @@
* that implements {@link TvInteractiveAppService} interface.
*
* @param iAppServiceId The ID of the TV Interactive App service.
- * @hide
*/
public void onInteractiveAppServiceAdded(@NonNull String iAppServiceId) {
}
@@ -571,7 +592,6 @@
* App service package.
*
* @param iAppServiceId The ID of the TV Interactive App service.
- * @hide
*/
public void onInteractiveAppServiceRemoved(@NonNull String iAppServiceId) {
}
@@ -583,7 +603,6 @@
* re-installed or a newer version of the package exists becomes available/unavailable.
*
* @param iAppServiceId The ID of the TV Interactive App service.
- * @hide
*/
public void onInteractiveAppServiceUpdated(@NonNull String iAppServiceId) {
}
@@ -730,8 +749,7 @@
}
/**
- * Prepares TV Interactive App service for the given type.
- * @hide
+ * Prepares TV Interactive App service environment for the given type.
*/
public void prepare(@NonNull String tvIAppServiceId, int type) {
try {
@@ -773,7 +791,6 @@
* @param tvIAppServiceId The ID of TV interactive service which the command to be sent to. The
* ID can be found in {@link TvInputInfo#getId()}.
* @param command The command to be sent.
- * @hide
*/
public void sendAppLinkCommand(@NonNull String tvIAppServiceId, @NonNull Bundle command) {
try {
@@ -1565,7 +1582,7 @@
}
void postCommandRequest(
- final @TvInteractiveAppService.InteractiveAppServiceCommandType String cmdType,
+ final @TvInteractiveAppService.PlaybackCommandType String cmdType,
final Bundle parameters) {
mHandler.post(new Runnable() {
@Override
@@ -1713,7 +1730,7 @@
*/
public void onCommandRequest(
Session session,
- @TvInteractiveAppService.InteractiveAppServiceCommandType String cmdType,
+ @TvInteractiveAppService.PlaybackCommandType String cmdType,
Bundle parameters) {
}
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
index 4716bed..c9856bf 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
@@ -32,6 +32,7 @@
import android.media.tv.BroadcastInfoRequest;
import android.media.tv.BroadcastInfoResponse;
import android.media.tv.TvContentRating;
+import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvTrackInfo;
import android.media.tv.TvView;
@@ -97,46 +98,82 @@
/** @hide */
@Retention(RetentionPolicy.SOURCE)
- @StringDef(prefix = "INTERACTIVE_APP_SERVICE_COMMAND_TYPE_", value = {
- INTERACTIVE_APP_SERVICE_COMMAND_TYPE_TUNE,
- INTERACTIVE_APP_SERVICE_COMMAND_TYPE_TUNE_NEXT,
- INTERACTIVE_APP_SERVICE_COMMAND_TYPE_TUNE_PREV,
- INTERACTIVE_APP_SERVICE_COMMAND_TYPE_STOP,
- INTERACTIVE_APP_SERVICE_COMMAND_TYPE_SET_STREAM_VOLUME,
- INTERACTIVE_APP_SERVICE_COMMAND_TYPE_SELECT_TRACK
+ @StringDef(prefix = "PLAYBACK_COMMAND_TYPE_", value = {
+ PLAYBACK_COMMAND_TYPE_TUNE,
+ PLAYBACK_COMMAND_TYPE_TUNE_NEXT,
+ PLAYBACK_COMMAND_TYPE_TUNE_PREV,
+ PLAYBACK_COMMAND_TYPE_STOP,
+ PLAYBACK_COMMAND_TYPE_SET_STREAM_VOLUME,
+ PLAYBACK_COMMAND_TYPE_SELECT_TRACK
})
- public @interface InteractiveAppServiceCommandType {}
+ public @interface PlaybackCommandType {}
- /** @hide */
- public static final String INTERACTIVE_APP_SERVICE_COMMAND_TYPE_TUNE = "tune";
- /** @hide */
- public static final String INTERACTIVE_APP_SERVICE_COMMAND_TYPE_TUNE_NEXT = "tune_next";
- /** @hide */
- public static final String INTERACTIVE_APP_SERVICE_COMMAND_TYPE_TUNE_PREV = "tune_previous";
- /** @hide */
- public static final String INTERACTIVE_APP_SERVICE_COMMAND_TYPE_STOP = "stop";
- /** @hide */
- public static final String INTERACTIVE_APP_SERVICE_COMMAND_TYPE_SET_STREAM_VOLUME =
+ /**
+ * Playback command type: tune to the given channel.
+ * @see #COMMAND_PARAMETER_KEY_CHANNEL_URI
+ */
+ public static final String PLAYBACK_COMMAND_TYPE_TUNE = "tune";
+ /**
+ * Playback command type: tune to the next channel.
+ */
+ public static final String PLAYBACK_COMMAND_TYPE_TUNE_NEXT = "tune_next";
+ /**
+ * Playback command type: tune to the previous channel.
+ */
+ public static final String PLAYBACK_COMMAND_TYPE_TUNE_PREV = "tune_previous";
+ /**
+ * Playback command type: stop the playback.
+ */
+ public static final String PLAYBACK_COMMAND_TYPE_STOP = "stop";
+ /**
+ * Playback command type: set the volume.
+ */
+ public static final String PLAYBACK_COMMAND_TYPE_SET_STREAM_VOLUME =
"set_stream_volume";
- /** @hide */
- public static final String INTERACTIVE_APP_SERVICE_COMMAND_TYPE_SELECT_TRACK = "select_track";
- /** @hide */
+ /**
+ * Playback command type: select the given track.
+ */
+ public static final String PLAYBACK_COMMAND_TYPE_SELECT_TRACK = "select_track";
+ /**
+ * Playback command parameter: channel URI.
+ * <p>Type: android.net.Uri
+ *
+ * @see #PLAYBACK_COMMAND_TYPE_TUNE
+ */
public static final String COMMAND_PARAMETER_KEY_CHANNEL_URI = "command_channel_uri";
- /** @hide */
+ /**
+ * Playback command parameter: TV input ID.
+ * <p>Type: String
+ *
+ * @see TvInputInfo#getId()
+ */
public static final String COMMAND_PARAMETER_KEY_INPUT_ID = "command_input_id";
- /** @hide */
+ /**
+ * Playback command parameter: stream volume.
+ * <p>Type: float
+ *
+ * @see #PLAYBACK_COMMAND_TYPE_SET_STREAM_VOLUME
+ */
public static final String COMMAND_PARAMETER_KEY_VOLUME = "command_volume";
- /** @hide */
+ /**
+ * Playback command parameter: track type.
+ * <p>Type: int
+ *
+ * @see #PLAYBACK_COMMAND_TYPE_SELECT_TRACK
+ * @see TvTrackInfo#getType()
+ */
public static final String COMMAND_PARAMETER_KEY_TRACK_TYPE = "command_track_type";
- /** @hide */
+ /**
+ * Playback command parameter: track ID.
+ * <p>Type: String
+ *
+ * @see #PLAYBACK_COMMAND_TYPE_SELECT_TRACK
+ * @see TvTrackInfo#getId()
+ */
public static final String COMMAND_PARAMETER_KEY_TRACK_ID = "command_track_id";
- /** @hide */
- public static final String COMMAND_PARAMETER_KEY_TRACK_SELECT_MODE =
- "command_track_select_mode";
/**
* Command to quiet channel change. No channel banner or channel info is shown.
* <p>Refer to HbbTV Spec 2.0.4 chapter A.2.4.3.
- * @hide
*/
public static final String COMMAND_PARAMETER_KEY_CHANGE_CHANNEL_QUIETLY =
"command_change_channel_quietly";
@@ -145,9 +182,9 @@
private final RemoteCallbackList<ITvInteractiveAppServiceCallback> mCallbacks =
new RemoteCallbackList<>();
- /** @hide */
@Override
- public final IBinder onBind(Intent intent) {
+ @Nullable
+ public final IBinder onBind(@NonNull Intent intent) {
ITvInteractiveAppService.Stub tvIAppServiceBinder = new ITvInteractiveAppService.Stub() {
@Override
public void registerCallback(ITvInteractiveAppServiceCallback cb) {
@@ -210,23 +247,20 @@
* Registers App link info.
* @hide
*/
- public void onRegisterAppLinkInfo(AppLinkInfo appLinkInfo) {
- // TODO: make it abstract when unhide
+ public void onRegisterAppLinkInfo(@NonNull AppLinkInfo appLinkInfo) {
}
/**
* Unregisters App link info.
* @hide
*/
- public void onUnregisterAppLinkInfo(AppLinkInfo appLinkInfo) {
- // TODO: make it abstract when unhide
+ public void onUnregisterAppLinkInfo(@NonNull AppLinkInfo appLinkInfo) {
}
/**
* Called when app link command is received.
*
* @see android.media.tv.interactive.TvInteractiveAppManager#sendAppLinkCommand(String, Bundle)
- * @hide
*/
public void onAppLinkCommand(@NonNull Bundle command) {
}
@@ -318,7 +352,6 @@
*
* @param enable {@code true} if you want to enable the media view. {@code false}
* otherwise.
- * @hide
*/
public void setMediaViewEnabled(final boolean enable) {
mHandler.post(new Runnable() {
@@ -353,7 +386,6 @@
/**
* Resets TvIAppService session.
- * @hide
*/
public void onResetInteractiveApp() {
}
@@ -384,43 +416,37 @@
/**
* To toggle Digital Teletext Application if there is one in AIT app list.
- * @param enable
- * @hide
+ * @param enable {@code true} to enable teletext app; {@code false} otherwise.
*/
public void onSetTeletextAppEnabled(boolean enable) {
}
/**
* Receives current channel URI.
- * @hide
*/
public void onCurrentChannelUri(@Nullable Uri channelUri) {
}
/**
* Receives logical channel number (LCN) of current channel.
- * @hide
*/
public void onCurrentChannelLcn(int lcn) {
}
/**
- * Receives stream volume.
- * @hide
+ * Receives current stream volume.
*/
public void onStreamVolume(float volume) {
}
/**
* Receives track list.
- * @hide
*/
public void onTrackInfoList(@NonNull List<TvTrackInfo> tracks) {
}
/**
* Receives current TV input ID.
- * @hide
*/
public void onCurrentTvInputId(@Nullable String inputId) {
}
@@ -460,7 +486,6 @@
*
* @param width The width of the media view.
* @param height The height of the media view.
- * @hide
*/
public void onMediaViewSizeChanged(int width, int height) {
}
@@ -470,7 +495,6 @@
* implementation can override this method and return its own view.
*
* @return a view attached to the media window
- * @hide
*/
@Nullable
public View onCreateMediaView() {
@@ -479,10 +503,8 @@
/**
* Releases TvInteractiveAppService session.
- * @hide
*/
- public void onRelease() {
- }
+ public abstract void onRelease();
/**
* Called when the corresponding TV input tuned to a channel.
@@ -494,49 +516,42 @@
/**
* Called when the corresponding TV input selected to a track.
- * @hide
*/
- public void onTrackSelected(int type, String trackId) {
+ public void onTrackSelected(@TvTrackInfo.Type int type, @NonNull String trackId) {
}
/**
* Called when the tracks are changed.
- * @hide
*/
- public void onTracksChanged(List<TvTrackInfo> tracks) {
+ public void onTracksChanged(@NonNull List<TvTrackInfo> tracks) {
}
/**
* Called when video is available.
- * @hide
*/
public void onVideoAvailable() {
}
/**
* Called when video is unavailable.
- * @hide
*/
- public void onVideoUnavailable(int reason) {
+ public void onVideoUnavailable(@TvInputManager.VideoUnavailableReason int reason) {
}
/**
* Called when content is allowed.
- * @hide
*/
public void onContentAllowed() {
}
/**
* Called when content is blocked.
- * @hide
*/
- public void onContentBlocked(TvContentRating rating) {
+ public void onContentBlocked(@NonNull TvContentRating rating) {
}
/**
* Called when signal strength is changed.
- * @hide
*/
public void onSignalStrength(@TvInputManager.SignalStrength int strength) {
}
@@ -550,60 +565,61 @@
/**
* Called when an advertisement response is received.
- * @hide
*/
public void onAdResponse(@NonNull AdResponse response) {
}
- /**
- * TODO: JavaDoc of APIs related to input events.
- * @hide
- */
@Override
public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
return false;
}
- /**
- * @hide
- */
@Override
public boolean onKeyLongPress(int keyCode, @NonNull KeyEvent event) {
return false;
}
- /**
- * @hide
- */
@Override
public boolean onKeyMultiple(int keyCode, int count, @NonNull KeyEvent event) {
return false;
}
- /**
- * @hide
- */
@Override
public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
return false;
}
/**
- * @hide
+ * Implement this method to handle touch screen motion events on the current session.
+ *
+ * @param event The motion event being received.
+ * @return If you handled the event, return {@code true}. If you want to allow the event to
+ * be handled by the next receiver, return {@code false}.
+ * @see View#onTouchEvent
*/
public boolean onTouchEvent(@NonNull MotionEvent event) {
return false;
}
/**
- * @hide
+ * Implement this method to handle trackball events on the current session.
+ *
+ * @param event The motion event being received.
+ * @return If you handled the event, return {@code true}. If you want to allow the event to
+ * be handled by the next receiver, return {@code false}.
+ * @see View#onTrackballEvent
*/
public boolean onTrackballEvent(@NonNull MotionEvent event) {
return false;
}
/**
- * @hide
+ * Implement this method to handle generic motion events on the current session.
+ *
+ * @param event The motion event being received.
+ * @return If you handled the event, return {@code true}. If you want to allow the event to
+ * be handled by the next receiver, return {@code false}.
+ * @see View#onGenericMotionEvent
*/
public boolean onGenericMotionEvent(@NonNull MotionEvent event) {
return false;
@@ -693,13 +709,13 @@
}
/**
- * requests a specific command to be processed by the related TV input.
+ * Sends a specific playback command to be processed by the related TV input.
+ *
* @param cmdType type of the specific command
* @param parameters parameters of the specific command
- * @hide
*/
- public void requestCommand(
- @InteractiveAppServiceCommandType String cmdType, Bundle parameters) {
+ public void sendPlaybackCommandRequest(
+ @PlaybackCommandType @NonNull String cmdType, @Nullable Bundle parameters) {
executeOrPostRunnableOnMainThread(new Runnable() {
@MainThread
@Override
@@ -721,9 +737,8 @@
/**
* Sets broadcast video bounds.
- * @hide
*/
- public void setVideoBounds(Rect rect) {
+ public void setVideoBounds(@NonNull Rect rect) {
executeOrPostRunnableOnMainThread(new Runnable() {
@MainThread
@Override
@@ -744,7 +759,6 @@
/**
* Requests the URI of the current channel.
- * @hide
*/
public void requestCurrentChannelUri() {
executeOrPostRunnableOnMainThread(new Runnable() {
@@ -767,7 +781,6 @@
/**
* Requests the logic channel number (LCN) of the current channel.
- * @hide
*/
public void requestCurrentChannelLcn() {
executeOrPostRunnableOnMainThread(new Runnable() {
@@ -790,7 +803,6 @@
/**
* Requests stream volume.
- * @hide
*/
public void requestStreamVolume() {
executeOrPostRunnableOnMainThread(new Runnable() {
@@ -813,7 +825,6 @@
/**
* Requests the list of {@link TvTrackInfo}.
- * @hide
*/
public void requestTrackInfoList() {
executeOrPostRunnableOnMainThread(new Runnable() {
@@ -838,7 +849,6 @@
* Requests current TV input ID.
*
* @see android.media.tv.TvInputInfo
- * @hide
*/
public void requestCurrentTvInputId() {
executeOrPostRunnableOnMainThread(new Runnable() {
@@ -863,7 +873,6 @@
* Sends an advertisement request to be processed by the related TV input.
*
* @param request The advertisement request
- * @hide
*/
public void requestAd(@NonNull final AdRequest request) {
executeOrPostRunnableOnMainThread(new Runnable() {
@@ -1082,7 +1091,6 @@
/**
* Notifies when the digital teletext app state is changed.
* @param state the current state.
- * @hide
*/
public final void notifyTeletextAppStateChanged(
@TvInteractiveAppManager.TeletextAppState int state) {
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppView.java b/media/java/android/media/tv/interactive/TvInteractiveAppView.java
index 2922bae..773e54f 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppView.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppView.java
@@ -170,23 +170,20 @@
}
}
- /** @hide */
@Override
- protected void onAttachedToWindow() {
+ public void onAttachedToWindow() {
super.onAttachedToWindow();
createSessionMediaView();
}
- /** @hide */
@Override
- protected void onDetachedFromWindow() {
+ public void onDetachedFromWindow() {
removeSessionMediaView();
super.onDetachedFromWindow();
}
- /** @hide */
@Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ public void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (DEBUG) {
Log.d(TAG, "onLayout (left=" + left + ", top=" + top + ", right=" + right
+ ", bottom=" + bottom + ",)");
@@ -199,9 +196,8 @@
}
}
- /** @hide */
@Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mSurfaceView.measure(widthMeasureSpec, heightMeasureSpec);
int width = mSurfaceView.getMeasuredWidth();
int height = mSurfaceView.getMeasuredHeight();
@@ -211,9 +207,8 @@
childState << MEASURED_HEIGHT_STATE_SHIFT));
}
- /** @hide */
@Override
- protected void onVisibilityChanged(View changedView, int visibility) {
+ public void onVisibilityChanged(@NonNull View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
mSurfaceView.setVisibility(visibility);
if (visibility == View.VISIBLE) {
@@ -244,7 +239,6 @@
/**
* Resets this TvInteractiveAppView.
- * @hide
*/
public void reset() {
if (DEBUG) Log.d(TAG, "reset()");
@@ -330,7 +324,11 @@
/**
* Dispatches an unhandled input event to the next receiver.
- * @hide
+ *
+ * It gives the host application a chance to dispatch the unhandled input events.
+ *
+ * @param event The input event.
+ * @return {@code true} if the event was handled by the view, {@code false} otherwise.
*/
public boolean dispatchUnhandledInputEvent(@NonNull InputEvent event) {
if (mOnUnhandledInputEventListener != null) {
@@ -349,21 +347,28 @@
* @param event The input event.
* @return If you handled the event, return {@code true}. If you want to allow the event to be
* handled by the next receiver, return {@code false}.
- * @hide
*/
public boolean onUnhandledInputEvent(@NonNull InputEvent event) {
return false;
}
/**
- * Registers a callback to be invoked when an input event is not handled
+ * Sets a listener to be invoked when an input event is not handled
* by the TV Interactive App.
*
* @param listener The callback to be invoked when the unhandled input event is received.
- * @hide
*/
- public void setOnUnhandledInputEventListener(@NonNull OnUnhandledInputEventListener listener) {
+ public void setOnUnhandledInputEventListener(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OnUnhandledInputEventListener listener) {
mOnUnhandledInputEventListener = listener;
+ // TODO: handle CallbackExecutor
+ }
+ /**
+ * Clears the {@link OnUnhandledInputEventListener}.
+ */
+ public void clearOnUnhandledInputEventListener() {
+ mOnUnhandledInputEventListener = null;
}
@Override
@@ -427,7 +432,6 @@
/**
* Resets the interactive application.
- * @hide
*/
public void resetInteractiveApp() {
if (DEBUG) {
@@ -440,9 +444,11 @@
/**
* Sends current channel URI to related TV interactive app.
- * @hide
+ *
+ * @param channelUri The current channel URI; {@code null} if there is no currently tuned
+ * channel.
*/
- public void sendCurrentChannelUri(Uri channelUri) {
+ public void sendCurrentChannelUri(@Nullable Uri channelUri) {
if (DEBUG) {
Log.d(TAG, "sendCurrentChannelUri");
}
@@ -453,7 +459,6 @@
/**
* Sends current channel logical channel number (LCN) to related TV interactive app.
- * @hide
*/
public void sendCurrentChannelLcn(int lcn) {
if (DEBUG) {
@@ -466,7 +471,6 @@
/**
* Sends stream volume to related TV interactive app.
- * @hide
*/
public void sendStreamVolume(float volume) {
if (DEBUG) {
@@ -479,9 +483,8 @@
/**
* Sends track info list to related TV interactive app.
- * @hide
*/
- public void sendTrackInfoList(List<TvTrackInfo> tracks) {
+ public void sendTrackInfoList(@Nullable List<TvTrackInfo> tracks) {
if (DEBUG) {
Log.d(TAG, "sendTrackInfoList");
}
@@ -496,7 +499,6 @@
* @param inputId The current TV input ID whose channel is tuned. {@code null} if no channel is
* tuned.
* @see android.media.tv.TvInputInfo
- * @hide
*/
public void sendCurrentTvInputId(@Nullable String inputId) {
if (DEBUG) {
@@ -588,8 +590,11 @@
/**
* To toggle Digital Teletext Application if there is one in AIT app list.
- * @param enable
- * @hide
+ *
+ * <p>A Teletext Application is a broadcast-related application to display text and basic
+ * graphics.
+ *
+ * @param enable {@code true} to enable Teletext app; {@code false} to disable it.
*/
public void setTeletextAppEnabled(boolean enable) {
if (DEBUG) {
@@ -607,17 +612,17 @@
// TODO: unhide the following public APIs
/**
- * This is called when a command is requested to be processed by the related TV input.
+ * This is called when a playback command is requested to be processed by the related TV
+ * input.
*
* @param iAppServiceId The ID of the TV interactive app service bound to this view.
* @param cmdType type of the command
* @param parameters parameters of the command
- * @hide
*/
- public void onCommandRequest(
+ public void onPlaybackCommandRequest(
@NonNull String iAppServiceId,
- @NonNull @TvInteractiveAppService.InteractiveAppServiceCommandType String cmdType,
- @Nullable Bundle parameters) {
+ @NonNull @TvInteractiveAppService.PlaybackCommandType String cmdType,
+ @NonNull Bundle parameters) {
}
/**
@@ -656,7 +661,6 @@
*
* @param iAppServiceId The ID of the TV interactive app service bound to this view.
* @param state digital teletext app current state.
- * @hide
*/
public void onTeletextAppStateChanged(
@NonNull String iAppServiceId,
@@ -664,59 +668,55 @@
}
/**
- * This is called when {@link TvInteractiveAppService.Session#SetVideoBounds} is called.
+ * This is called when {@link TvInteractiveAppService.Session#setVideoBounds(Rect)} is
+ * called.
*
* @param iAppServiceId The ID of the TV interactive app service bound to this view.
- * @hide
*/
public void onSetVideoBounds(@NonNull String iAppServiceId, @NonNull Rect rect) {
}
/**
- * This is called when {@link TvInteractiveAppService.Session#RequestCurrentChannelUri} is
+ * This is called when {@link TvInteractiveAppService.Session#requestCurrentChannelUri()} is
* called.
*
* @param iAppServiceId The ID of the TV interactive app service bound to this view.
- * @hide
*/
public void onRequestCurrentChannelUri(@NonNull String iAppServiceId) {
}
/**
- * This is called when {@link TvInteractiveAppService.Session#RequestCurrentChannelLcn} is
+ * This is called when {@link TvInteractiveAppService.Session#requestCurrentChannelLcn()} is
* called.
*
* @param iAppServiceId The ID of the TV interactive app service bound to this view.
- * @hide
*/
public void onRequestCurrentChannelLcn(@NonNull String iAppServiceId) {
}
/**
- * This is called when {@link TvInteractiveAppService.Session#RequestStreamVolume} is
+ * This is called when {@link TvInteractiveAppService.Session#requestStreamVolume()} is
* called.
*
* @param iAppServiceId The ID of the TV interactive app service bound to this view.
- * @hide
*/
public void onRequestStreamVolume(@NonNull String iAppServiceId) {
}
/**
- * This is called when {@link TvInteractiveAppService.Session#RequestTrackInfoList} is
+ * This is called when {@link TvInteractiveAppService.Session#requestTrackInfoList()} is
* called.
*
* @param iAppServiceId The ID of the TV interactive app service bound to this view.
- * @hide
*/
public void onRequestTrackInfoList(@NonNull String iAppServiceId) {
}
/**
- * This is called when {@link TvIAppService.Session#RequestCurrentTvInputId} is called.
+ * This is called when {@link TvInteractiveAppService.Session#requestCurrentTvInputId()} is
+ * called.
*
* @param iAppServiceId The ID of the TV interactive app service bound to this view.
- * @hide
*/
public void onRequestCurrentTvInputId(@NonNull String iAppServiceId) {
}
@@ -725,7 +725,6 @@
/**
* Interface definition for a callback to be invoked when the unhandled input event is received.
- * @hide
*/
public interface OnUnhandledInputEventListener {
/**
@@ -818,7 +817,7 @@
@Override
public void onCommandRequest(
Session session,
- @TvInteractiveAppService.InteractiveAppServiceCommandType String cmdType,
+ @TvInteractiveAppService.PlaybackCommandType String cmdType,
Bundle parameters) {
if (DEBUG) {
Log.d(TAG, "onCommandRequest (cmdType=" + cmdType + ", parameters="
@@ -833,7 +832,8 @@
mCallbackExecutor.execute(() -> {
synchronized (mCallbackLock) {
if (mCallback != null) {
- mCallback.onCommandRequest(mIAppServiceId, cmdType, parameters);
+ mCallback.onPlaybackCommandRequest(
+ mIAppServiceId, cmdType, parameters);
}
}
});
diff --git a/media/java/android/media/tv/tuner/filter/SharedFilter.java b/media/java/android/media/tv/tuner/filter/SharedFilter.java
index 056c5d5..740ab9c 100644
--- a/media/java/android/media/tv/tuner/filter/SharedFilter.java
+++ b/media/java/android/media/tv/tuner/filter/SharedFilter.java
@@ -92,9 +92,21 @@
synchronized (mCallbackLock) {
if (mCallback != null) {
mCallback.onFilterEvent(this, events);
+ } else {
+ for (FilterEvent event : events) {
+ if (event instanceof MediaEvent) {
+ ((MediaEvent)event).release();
+ }
+ }
}
}
});
+ } else {
+ for (FilterEvent event : events) {
+ if (event instanceof MediaEvent) {
+ ((MediaEvent)event).release();
+ }
+ }
}
}
}
@@ -187,6 +199,8 @@
if (mIsClosed) {
return;
}
+ mCallback = null;
+ mExecutor = null;
nativeSharedClose();
mIsClosed = true;
}
diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp
index 2e419a6..eca26dc 100644
--- a/media/jni/android_media_ImageWriter.cpp
+++ b/media/jni/android_media_ImageWriter.cpp
@@ -460,8 +460,6 @@
} else {
// Set consumer buffer format to user specified format
android_dataspace nativeDataspace = static_cast<android_dataspace>(dataSpace);
- int userFormat = static_cast<int>(mapHalFormatDataspaceToPublicFormat(
- hardwareBufferFormat, nativeDataspace));
res = native_window_set_buffers_format(anw.get(), hardwareBufferFormat);
if (res != OK) {
ALOGE("%s: Unable to configure consumer native buffer format to %#x",
@@ -478,20 +476,29 @@
return 0;
}
ctx->setBufferDataSpace(nativeDataspace);
- surfaceFormat = userFormat;
+ surfaceFormat = static_cast<int32_t>(mapHalFormatDataspaceToPublicFormat(
+ hardwareBufferFormat, nativeDataspace));
}
ctx->setBufferFormat(surfaceFormat);
env->SetIntField(thiz,
gImageWriterClassInfo.mWriterFormat, reinterpret_cast<jint>(surfaceFormat));
- res = native_window_set_usage(anw.get(), ndkUsage);
- if (res != OK) {
- ALOGE("%s: Configure usage %08x for format %08x failed: %s (%d)",
- __FUNCTION__, static_cast<unsigned int>(ndkUsage),
- surfaceFormat, strerror(-res), res);
- jniThrowRuntimeException(env, "Failed to SW_WRITE_OFTEN configure usage");
- return 0;
+ // ndkUsage == -1 means setUsage in ImageWriter class is not called.
+ // skip usage setting if setUsage in ImageWriter is not called and imageformat is opaque.
+ if (!(ndkUsage == -1 && isFormatOpaque(surfaceFormat))) {
+ if (ndkUsage == -1) {
+ ndkUsage = GRALLOC_USAGE_SW_WRITE_OFTEN;
+ }
+ res = native_window_set_usage(anw.get(), ndkUsage);
+ if (res != OK) {
+ ALOGE("%s: Configure usage %08x for format %08x failed: %s (%d)",
+ __FUNCTION__, static_cast<unsigned int>(ndkUsage),
+ surfaceFormat, strerror(-res), res);
+ jniThrowRuntimeException(env,
+ "Failed to SW_WRITE_OFTEN configure usage");
+ return 0;
+ }
}
int minUndequeuedBufferCount = 0;
@@ -952,7 +959,7 @@
return buffer->getHeight();
}
-static jint Image_getFormat(JNIEnv* env, jobject thiz) {
+static jint Image_getFormat(JNIEnv* env, jobject thiz, jlong dataSpace) {
ALOGV("%s", __FUNCTION__);
GraphicBuffer* buffer;
Image_getNativeContext(env, thiz, &buffer, NULL);
@@ -962,9 +969,9 @@
return 0;
}
- // ImageWriter doesn't support data space yet, assuming it is unknown.
PublicFormat publicFmt = mapHalFormatDataspaceToPublicFormat(buffer->getPixelFormat(),
- HAL_DATASPACE_UNKNOWN);
+ static_cast<android_dataspace>(dataSpace));
+
return static_cast<jint>(publicFmt);
}
@@ -1031,14 +1038,14 @@
}
static jobjectArray Image_createSurfacePlanes(JNIEnv* env, jobject thiz,
- int numPlanes, int writerFormat) {
+ int numPlanes, int writerFormat, long dataSpace) {
ALOGV("%s: create SurfacePlane array with size %d", __FUNCTION__, numPlanes);
int rowStride, pixelStride;
uint8_t *pData;
uint32_t dataSize;
jobject byteBuffer;
- int format = Image_getFormat(env, thiz);
+ int format = Image_getFormat(env, thiz, dataSpace);
if (isFormatOpaque(format) && numPlanes > 0) {
String8 msg;
msg.appendFormat("Format 0x%x is opaque, thus not writable, the number of planes (%d)"
@@ -1108,11 +1115,11 @@
};
static JNINativeMethod gImageMethods[] = {
- {"nativeCreatePlanes", "(II)[Landroid/media/ImageWriter$WriterSurfaceImage$SurfacePlane;",
+ {"nativeCreatePlanes", "(IIJ)[Landroid/media/ImageWriter$WriterSurfaceImage$SurfacePlane;",
(void*)Image_createSurfacePlanes },
{"nativeGetWidth", "()I", (void*)Image_getWidth },
{"nativeGetHeight", "()I", (void*)Image_getHeight },
- {"nativeGetFormat", "()I", (void*)Image_getFormat },
+ {"nativeGetFormat", "(J)I", (void*)Image_getFormat },
{"nativeGetHardwareBuffer", "()Landroid/hardware/HardwareBuffer;",
(void*)Image_getHardwareBuffer },
};
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 68dd8d0..9ed1ac0 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -4147,6 +4147,7 @@
Result r = filterClient->close();
filterClient->decStrong(filter);
+ filterClient = nullptr;
if (shared) {
env->SetLongField(filter, gFields.sharedFilterContext, 0);
} else {
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
index d3d5a08..77fc171 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
@@ -434,7 +434,8 @@
@NonNull
public Builder setRatType(@Annotation.NetworkType int ratType) {
if (!CollectionUtils.contains(TelephonyManager.getAllNetworkTypes(), ratType)
- && ratType != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
+ && ratType != TelephonyManager.NETWORK_TYPE_UNKNOWN
+ && ratType != NetworkTemplate.NETWORK_TYPE_5G_NSA) {
throw new IllegalArgumentException("Invalid ratType " + ratType);
}
mRatType = ratType;
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java
index cad8075..dba3991 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java
@@ -652,7 +652,9 @@
*
* @hide
*/
- public boolean matches(NetworkIdentity ident) {
+ @SystemApi(client = MODULE_LIBRARIES)
+ public boolean matches(@NonNull NetworkIdentity ident) {
+ Objects.requireNonNull(ident);
if (!matchesMetered(ident)) return false;
if (!matchesRoaming(ident)) return false;
if (!matchesDefaultNetwork(ident)) return false;
diff --git a/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java b/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java
index f5aa652..b4e84dd 100644
--- a/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java
+++ b/packages/SettingsLib/src/com/android/settingslib/NetworkPolicyEditor.java
@@ -27,9 +27,7 @@
import android.net.NetworkPolicy;
import android.net.NetworkPolicyManager;
import android.net.NetworkTemplate;
-import android.net.wifi.WifiInfo;
import android.os.AsyncTask;
-import android.text.TextUtils;
import android.util.RecurrenceRule;
import com.google.android.collect.Lists;
@@ -124,7 +122,7 @@
if (policy != null) {
return policy;
} else {
- return getPolicy(buildUnquotedNetworkTemplate(template));
+ return getPolicy(template);
}
}
@@ -207,21 +205,4 @@
policy.clearSnooze();
writeAsync();
}
-
- /**
- * Build a revised {@link NetworkTemplate} that matches the same rule, but
- * with an unquoted {@link NetworkTemplate#getNetworkId()}. Used to work
- * around legacy bugs.
- */
- private static NetworkTemplate buildUnquotedNetworkTemplate(NetworkTemplate template) {
- if (template == null) return null;
- final String networkId = template.getNetworkId();
- final String strippedNetworkId = WifiInfo.sanitizeSsid(networkId);
- if (!TextUtils.equals(strippedNetworkId, networkId)) {
- return new NetworkTemplate(
- template.getMatchRule(), template.getSubscriberId(), strippedNetworkId);
- } else {
- return null;
- }
- }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
index b56ae38..4939e04 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatteryStatus.java
@@ -88,14 +88,15 @@
}
/**
- * Determine whether the device is plugged in (USB, power, or wireless).
+ * Determine whether the device is plugged in (USB, power, wireless or dock).
*
* @return true if the device is plugged in.
*/
public boolean isPluggedIn() {
return plugged == BatteryManager.BATTERY_PLUGGED_AC
|| plugged == BatteryManager.BATTERY_PLUGGED_USB
- || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
+ || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS
+ || plugged == BatteryManager.BATTERY_PLUGGED_DOCK;
}
/**
@@ -118,6 +119,15 @@
}
/**
+ * Determine whether the device is plugged in dock.
+ *
+ * @return true if the device is plugged in dock
+ */
+ public boolean isPluggedInDock() {
+ return plugged == BatteryManager.BATTERY_PLUGGED_DOCK;
+ }
+
+ /**
* Whether or not the device is charged. Note that some devices never return 100% for
* battery level, so this allows either battery level or status to determine if the
* battery is charged.
diff --git a/packages/SettingsLib/src/com/android/settingslib/mobile/OWNERS b/packages/SettingsLib/src/com/android/settingslib/mobile/OWNERS
new file mode 100644
index 0000000..ab9b5dc
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/mobile/OWNERS
@@ -0,0 +1,4 @@
+# Default reviewers for this and subdirectories.
+bonianchen@google.com
+
+# Emergency approvers in case the above are not available
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index cff45c6..30c6645 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -16,7 +16,6 @@
package com.android.settingslib.net;
-import static android.net.TrafficStats.MB_IN_BYTES;
import static android.telephony.TelephonyManager.SIM_STATE_READY;
import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
@@ -49,6 +48,7 @@
private static final StringBuilder PERIOD_BUILDER = new StringBuilder(50);
private static final java.util.Formatter PERIOD_FORMATTER = new java.util.Formatter(
PERIOD_BUILDER, Locale.getDefault());
+ private static final long MB_IN_BYTES = 1024 * 1024;
private final Context mContext;
private final NetworkPolicyManager mPolicyManager;
@@ -237,10 +237,8 @@
final int matchRule = networkTemplate.getMatchRule();
switch (matchRule) {
case NetworkTemplate.MATCH_MOBILE:
- case NetworkTemplate.MATCH_MOBILE_WILDCARD:
return ConnectivityManager.TYPE_MOBILE;
case NetworkTemplate.MATCH_WIFI:
- case NetworkTemplate.MATCH_WIFI_WILDCARD:
return ConnectivityManager.TYPE_WIFI;
case NetworkTemplate.MATCH_ETHERNET:
return ConnectivityManager.TYPE_ETHERNET;
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
index afd44d5..386a47a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageUtils.java
@@ -63,14 +63,32 @@
private static NetworkTemplate getNormalizedMobileTemplate(
TelephonyManager telephonyManager, int subId) {
final NetworkTemplate mobileTemplate = getMobileTemplateForSubId(telephonyManager, subId);
- final String[] mergedSubscriberIds = telephonyManager
- .createForSubscriptionId(subId).getMergedImsisFromGroup();
+ final Set<String> mergedSubscriberIds = Set.of(telephonyManager
+ .createForSubscriptionId(subId).getMergedImsisFromGroup());
if (ArrayUtils.isEmpty(mergedSubscriberIds)) {
Log.i(TAG, "mergedSubscriberIds is null.");
return mobileTemplate;
}
- return NetworkTemplate.normalize(mobileTemplate, mergedSubscriberIds);
+ return normalizeMobileTemplate(mobileTemplate, mergedSubscriberIds);
+ }
+
+ private static NetworkTemplate normalizeMobileTemplate(
+ NetworkTemplate template, Set<String> mergedSet) {
+ if (template.getSubscriberIds().isEmpty()) return template;
+ // The input template should have at most 1 subscriberId.
+ final String subscriberId = template.getSubscriberIds().iterator().next();
+
+ if (mergedSet.contains(subscriberId)) {
+ // Requested template subscriber is part of the merge group; return
+ // a template that matches all merged subscribers.
+ return new NetworkTemplate.Builder(template.getMatchRule())
+ .setSubscriberIds(mergedSet)
+ .setWifiNetworkKeys(template.getWifiNetworkKeys())
+ .setMeteredness(NetworkStats.METERED_YES).build();
+ }
+
+ return template;
}
private static NetworkTemplate getMobileTemplateForSubId(
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
index 43c05b8..504390c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
@@ -53,8 +53,9 @@
long totalUsage = 0L;
long totalForeground = 0L;
for (int uid : mUids) {
- final NetworkStats stats = mNetworkStatsManager.queryDetailsForUid(
- mNetworkTemplate, start, end, uid);
+ final NetworkStats stats = mNetworkStatsManager.queryDetailsForUidTagState(
+ mNetworkTemplate, start, end, uid, NetworkStats.Bucket.TAG_NONE,
+ NetworkStats.Bucket.STATE_ALL);
final long usage = getTotalUsage(stats);
if (usage > 0L) {
totalUsage += usage;
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/OWNERS b/packages/SettingsLib/src/com/android/settingslib/net/OWNERS
new file mode 100644
index 0000000..ab9b5dc
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/OWNERS
@@ -0,0 +1,4 @@
+# Default reviewers for this and subdirectories.
+bonianchen@google.com
+
+# Emergency approvers in case the above are not available
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java b/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java
index 02326ea..623eb33 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/UidDetailProvider.java
@@ -17,6 +17,7 @@
package com.android.settingslib.net;
import android.app.AppGlobals;
+import android.app.usage.NetworkStats;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
@@ -116,13 +117,13 @@
detail.label = res.getString(R.string.process_kernel_label);
detail.icon = pm.getDefaultActivityIcon();
return detail;
- case TrafficStats.UID_REMOVED:
+ case NetworkStats.Bucket.UID_REMOVED:
detail.label = res.getString(UserManager.supportsMultipleUsers()
? R.string.data_usage_uninstalled_apps_users
: R.string.data_usage_uninstalled_apps);
detail.icon = pm.getDefaultActivityIcon();
return detail;
- case TrafficStats.UID_TETHERING:
+ case NetworkStats.Bucket.UID_TETHERING:
final TetheringManager tm = mContext.getSystemService(TetheringManager.class);
detail.label = res.getString(Utils.getTetheringLabel(tm));
detail.icon = pm.getDefaultActivityIcon();
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 1601043..8e9e02a 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -37,6 +37,9 @@
<!-- When the lock screen is showing and the phone plugged in, and the battery is not fully charged, say that it's wirelessly charging. [CHAR LIMIT=50] -->
<string name="keyguard_plugged_in_wireless"><xliff:g id="percentage" example="20%">%s</xliff:g> • Charging wirelessly</string>
+ <!-- When the lock screen is showing and the phone plugged in, and the battery is not fully charged, say that it's dock charging. [CHAR LIMIT=50] -->
+ <string name="keyguard_plugged_in_dock"><xliff:g id="percentage" example="20%">%s</xliff:g> • Charging Dock</string>
+
<!-- When the lock screen is showing and the phone plugged in, and the battery
is not fully charged, say that it's charging. -->
<string name="keyguard_plugged_in"><xliff:g id="percentage">%s</xliff:g> • Charging</string>
diff --git a/packages/SystemUI/res/drawable/ic_list.xml b/packages/SystemUI/res/drawable/ic_list.xml
deleted file mode 100644
index 7ef5299..0000000
--- a/packages/SystemUI/res/drawable/ic_list.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2021 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<!-- Remove when Fgs manager tile is removed -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="48dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
- <path
- android:pathData="M2,4h4v4h-4z"
- android:fillColor="#000000"/>
- <path
- android:pathData="M8,4h14v4h-14z"
- android:fillColor="#000000"/>
- <path
- android:pathData="M2,10h4v4h-4z"
- android:fillColor="#000000"/>
- <path
- android:pathData="M8,10h14v4h-14z"
- android:fillColor="#000000"/>
- <path
- android:pathData="M2,16h4v4h-4z"
- android:fillColor="#000000"/>
- <path
- android:pathData="M8,16h14v4h-14z"
- android:fillColor="#000000"/>
-</vector>
diff --git a/packages/SystemUI/res/layout/controls_detail_dialog.xml b/packages/SystemUI/res/layout/controls_detail_dialog.xml
index 28fc863..4d2317c 100644
--- a/packages/SystemUI/res/layout/controls_detail_dialog.xml
+++ b/packages/SystemUI/res/layout/controls_detail_dialog.xml
@@ -15,47 +15,52 @@
limitations under the License.
-->
-<LinearLayout
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/control_detail_root"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:background="@android:color/black">
+ android:layout_height="match_parent">
<LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layout_marginBottom="4dp">
- <ImageView
- android:id="@+id/control_detail_close"
- android:contentDescription="@string/accessibility_desc_close"
- android:src="@drawable/ic_arrow_back"
- android:background="?android:attr/selectableItemBackgroundBorderless"
- android:tint="@color/control_primary_text"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:padding="12dp" />
- <Space
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_height="1dp" />
- <ImageView
- android:id="@+id/control_detail_open_in_app"
- android:contentDescription="@string/controls_open_app"
- android:src="@drawable/ic_open_in_new"
- android:background="?android:attr/selectableItemBackgroundBorderless"
- android:tint="@color/control_primary_text"
- android:layout_width="48dp"
- android:layout_height="48dp"
- android:padding="12dp" />
- </LinearLayout>
-
- <FrameLayout
- android:id="@+id/controls_activity_view"
+ android:id="@+id/control_task_view_container"
android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:orientation="vertical" />
-</LinearLayout>
+ android:layout_height="match_parent"
+ android:layout_gravity="right|top"
+ android:layout_marginRight="@dimen/controls_task_view_right_margin"
+ android:orientation="vertical">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:layout_marginBottom="4dp">
+ <ImageView
+ android:id="@+id/control_detail_close"
+ android:contentDescription="@string/accessibility_desc_close"
+ android:src="@drawable/ic_close"
+ android:background="?android:attr/selectableItemBackgroundBorderless"
+ android:tint="@color/control_primary_text"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:padding="12dp" />
+ <Space
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="1dp" />
+ <ImageView
+ android:id="@+id/control_detail_open_in_app"
+ android:contentDescription="@string/controls_open_app"
+ android:src="@drawable/ic_open_in_new"
+ android:background="?android:attr/selectableItemBackgroundBorderless"
+ android:tint="@color/control_primary_text"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:padding="12dp" />
+ </LinearLayout>
+
+ <FrameLayout
+ android:id="@+id/controls_activity_view"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+ </LinearLayout>
+</FrameLayout>
diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
index 3cfe056..89d046b 100644
--- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml
@@ -25,4 +25,8 @@
<!-- margin from keyguard status bar to clock. For split shade it should be
keyguard_split_shade_top_margin - status_bar_header_height_keyguard = 8dp -->
<dimen name="keyguard_clock_top_margin">8dp</dimen>
+
+ <!-- Limit the TaskView to this percentage of the overall screen width (0.0 - 1.0) -->
+ <item name="controls_task_view_width_percentage" translatable="false" format="float" type="dimen">0.45</item>
+ <dimen name="controls_task_view_right_margin">8dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 461a598..81e3e04 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -194,6 +194,7 @@
<color name="control_enabled_cool_foreground">@color/GM2_blue_300</color>
<color name="control_thumbnail_tint">#33000000</color>
<color name="control_thumbnail_shadow_color">@*android:color/black</color>
+ <color name="controls_task_view_bg">#CC191C1D</color>
<!-- Docked misalignment message -->
<color name="misalignment_text_color">#F28B82</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index fc2756e..9d7cf1a 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -82,7 +82,7 @@
<!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
<string name="quick_settings_tiles_stock" translatable="false">
- internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,fgsmanager,color_correction
+ internet,bt,flashlight,dnd,alarm,airplane,controls,wallet,rotation,battery,cast,screenrecord,mictoggle,cameratoggle,location,hotspot,inversion,saver,dark,work,night,reverse,reduce_brightness,qr_code_scanner,onehanded,color_correction
</string>
<!-- The tiles to display in QuickSettings -->
@@ -581,6 +581,9 @@
<!-- Whether to use the split 2-column notification shade -->
<bool name="config_use_split_notification_shade">false</bool>
+ <!-- Whether notification header should never show section headers. -->
+ <bool name="config_notification_never_show_section_headers">false</bool>
+
<!-- Default udfps icon. Same path as ic_fingerprint.xml -->
<string name="config_udfpsIcon" translatable="false">
M25.5,16.3283C28.47,14.8433 31.9167,14 35.5834,14C39.2501,14 42.6968,14.8433 45.6668,16.3283
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 67d5b2f..af7ef53 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1052,6 +1052,9 @@
<dimen name="controls_setup_subtitle">14sp</dimen>
<dimen name="controls_setup_vertical_padding">52dp</dimen>
<dimen name="controls_detail_dialog_header_height">52dp</dimen>
+ <!-- Limit the TaskView to this percentage of the overall screen width (0.0 - 1.0) -->
+ <item name="controls_task_view_width_percentage" translatable="false" format="float" type="dimen">1.0</item>
+ <dimen name="controls_task_view_right_margin">0dp</dimen>
<!-- Home Controls activity view detail panel-->
<dimen name="controls_activity_view_corner_radius">@*android:dimen/config_bottomDialogCornerRadius</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 7384ccc..6eab2b2 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -796,6 +796,9 @@
<!-- Indication on the keyguard that is shown when the device is charging slowly. Should match keyguard_plugged_in_charging_slowly [CHAR LIMIT=50]-->
<string name="keyguard_indication_charging_time_slowly"><xliff:g id="percentage">%2$s</xliff:g> • Charging slowly • Full in <xliff:g id="charging_time_left" example="4 hr, 2 min">%1$s</xliff:g></string>
+ <!-- Indication on the keyguard that is shown when the device is dock charging. [CHAR LIMIT=80]-->
+ <string name="keyguard_indication_charging_time_dock"><xliff:g id="percentage" example="20%">%2$s</xliff:g> • Charging Dock • Full in <xliff:g id="charging_time_left" example="4 hr, 2 min">%1$s</xliff:g></string>
+
<!-- Related to user switcher --><skip/>
<!-- Accessibility label for the button that opens the user switcher. -->
@@ -2355,6 +2358,11 @@
<!-- Title for User Switch dialog. [CHAR LIMIT=20] -->
<string name="qs_user_switch_dialog_title">Select user</string>
+ <!-- Label for the entry point to open the dialog which shows currently running applications [CHAR LIMIT=NONE]-->
+ <plurals name="fgs_manager_footer_label">
+ <item quantity="one"><xliff:g id="count" example="1">%s</xliff:g> app running in the background</item>
+ <item quantity="other"><xliff:g id="count" example="2">%s</xliff:g> apps running in the background</item>
+ </plurals>
<!-- Title for dialog listing applications currently running in the backing [CHAR LIMIT=NONE]-->
<string name="fgs_manager_dialog_title">Apps running in the background</string>
<!-- Label of the button to stop the app from running in the background [CHAR LIMIT=12]-->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index ff5699b..ac98739 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -746,7 +746,7 @@
<style name="Theme.SystemUI.Dialog.Control.DetailPanel" parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar">
<item name="android:windowFullscreen">false</item>
<item name="android:windowIsFloating">false</item>
- <item name="android:windowBackground">@android:color/black</item>
+ <item name="android:windowBackground">@color/controls_task_view_bg</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
</style>
diff --git a/packages/SystemUI/res/values/tiles_states_strings.xml b/packages/SystemUI/res/values/tiles_states_strings.xml
index a610caa..e273416 100644
--- a/packages/SystemUI/res/values/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values/tiles_states_strings.xml
@@ -308,14 +308,4 @@
<item>Off</item>
<item>On</item>
</string-array>
-
- <!-- State names for fgsmanager tile: unavailable, off, on.
- This subtitle is shown when the tile is in that particular state but does not set its own
- subtitle, so some of these may never appear on screen. They should still be translated as
- if they could appear.[CHAR LIMIT=32] -->
- <string-array name="tile_states_fgsmanager">
- <item>Unavailable</item>
- <item>Off</item>
- <item>On</item>
- </string-array>
</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java b/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java
index 710980a..e6d5719 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java
@@ -58,7 +58,7 @@
LayoutInflater mInflater;
- private MetricsLogger mMetricsLogger;
+ private final MetricsLogger mMetricsLogger;
private String[] mPackages;
private PackageItemAdapter mAdapter;
@@ -75,16 +75,15 @@
};
@Inject
- ForegroundServicesDialog() {
+ ForegroundServicesDialog(MetricsLogger metricsLogger) {
super();
+ mMetricsLogger = metricsLogger;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mMetricsLogger = Dependency.get(MetricsLogger.class);
-
mInflater = LayoutInflater.from(this);
mAdapter = new PackageItemAdapter(this);
diff --git a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
index 3f5c2c8..aedaf96 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/PhoneStateMonitor.java
@@ -28,7 +28,6 @@
import androidx.annotation.Nullable;
import com.android.systemui.BootCompleteCache;
-import com.android.systemui.Dependency;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -78,10 +77,11 @@
@Inject
PhoneStateMonitor(Context context, BroadcastDispatcher broadcastDispatcher,
- Lazy<Optional<StatusBar>> statusBarOptionalLazy, BootCompleteCache bootCompleteCache) {
+ Lazy<Optional<StatusBar>> statusBarOptionalLazy, BootCompleteCache bootCompleteCache,
+ StatusBarStateController statusBarStateController) {
mContext = context;
mStatusBarOptionalLazy = statusBarOptionalLazy;
- mStatusBarStateController = Dependency.get(StatusBarStateController.class);
+ mStatusBarStateController = statusBarStateController;
mDefaultHome = getCurrentDefaultHome();
bootCompleteCache.addListener(() -> mDefaultHome = getCurrentDefaultHome());
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
index 5732145..1c98099 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
@@ -35,7 +35,6 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.assist.AssistLogger;
import com.android.systemui.assist.AssistManager;
@@ -46,6 +45,8 @@
import javax.inject.Inject;
+import dagger.Lazy;
+
/**
* Default UiController implementation. Shows white edge lights along the bottom of the phone,
* expanding from the corners to meet in the center.
@@ -65,6 +66,8 @@
protected final AssistLogger mAssistLogger;
private final WindowManager mWindowManager;
+ private final MetricsLogger mMetricsLogger;
+ private final Lazy<AssistManager> mAssistManagerLazy;
private final WindowManager.LayoutParams mLayoutParams;
private final PathInterpolator mProgressInterpolator = new PathInterpolator(.83f, 0, .84f, 1);
@@ -75,10 +78,14 @@
private ValueAnimator mInvocationAnimator = new ValueAnimator();
@Inject
- public DefaultUiController(Context context, AssistLogger assistLogger) {
+ public DefaultUiController(Context context, AssistLogger assistLogger,
+ WindowManager windowManager, MetricsLogger metricsLogger,
+ Lazy<AssistManager> assistManagerLazy) {
mAssistLogger = assistLogger;
mRoot = new FrameLayout(context);
- mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ mWindowManager = windowManager;
+ mMetricsLogger = metricsLogger;
+ mAssistManagerLazy = assistManagerLazy;
mLayoutParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
@@ -152,9 +159,9 @@
/* isInvocationComplete = */ false,
/* assistantComponent = */ null,
/* legacyDeviceState = */ null);
- MetricsLogger.action(new LogMaker(MetricsEvent.ASSISTANT)
+ mMetricsLogger.write(new LogMaker(MetricsEvent.ASSISTANT)
.setType(MetricsEvent.TYPE_ACTION)
- .setSubtype(Dependency.get(AssistManager.class).toLoggingSubType(type)));
+ .setSubtype(mAssistManagerLazy.get().toLoggingSubType(type)));
}
// Logs assistant invocation cancelled.
if ((mInvocationAnimator == null || !mInvocationAnimator.isRunning())
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index fd37b35..21edb24 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -52,7 +52,6 @@
import android.widget.ScrollView;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -106,7 +105,7 @@
private final float mTranslationY;
- @VisibleForTesting final WakefulnessLifecycle mWakefulnessLifecycle;
+ private final WakefulnessLifecycle mWakefulnessLifecycle;
@VisibleForTesting @ContainerState int mContainerState = STATE_UNKNOWN;
@@ -187,10 +186,12 @@
public AuthContainerView build(int[] sensorIds, boolean credentialAllowed,
@Nullable List<FingerprintSensorPropertiesInternal> fpProps,
- @Nullable List<FaceSensorPropertiesInternal> faceProps) {
+ @Nullable List<FaceSensorPropertiesInternal> faceProps,
+ WakefulnessLifecycle wakefulnessLifecycle) {
mConfig.mSensorIds = sensorIds;
mConfig.mCredentialAllowed = credentialAllowed;
- return new AuthContainerView(mConfig, new Injector(), fpProps, faceProps);
+ return new AuthContainerView(
+ mConfig, new Injector(), fpProps, faceProps, wakefulnessLifecycle);
}
}
@@ -276,7 +277,8 @@
@VisibleForTesting
AuthContainerView(Config config, Injector injector,
@Nullable List<FingerprintSensorPropertiesInternal> fpProps,
- @Nullable List<FaceSensorPropertiesInternal> faceProps) {
+ @Nullable List<FaceSensorPropertiesInternal> faceProps,
+ WakefulnessLifecycle wakefulnessLifecycle) {
super(config.mContext);
mConfig = config;
@@ -289,7 +291,7 @@
mHandler = new Handler(Looper.getMainLooper());
mWindowManager = mContext.getSystemService(WindowManager.class);
- mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
+ mWakefulnessLifecycle = wakefulnessLifecycle;
mTranslationY = getResources()
.getDimension(R.dimen.biometric_dialog_animation_translation_offset);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 2b12f67..f833c2a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -63,6 +63,7 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeReceiver;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.util.concurrency.Execution;
@@ -130,6 +131,7 @@
@NonNull private final SparseBooleanArray mUdfpsEnrolledForUser;
private SensorPrivacyManager mSensorPrivacyManager;
+ private final WakefulnessLifecycle mWakefulnessLifecycle;
private class BiometricTaskStackListener extends TaskStackListener {
@Override
@@ -479,9 +481,11 @@
Provider<UdfpsController> udfpsControllerFactory,
Provider<SidefpsController> sidefpsControllerFactory,
@NonNull DisplayManager displayManager,
+ WakefulnessLifecycle wakefulnessLifecycle,
@Main Handler handler) {
super(context);
mExecution = execution;
+ mWakefulnessLifecycle = wakefulnessLifecycle;
mHandler = handler;
mCommandQueue = commandQueue;
mActivityTaskManager = activityTaskManager;
@@ -788,7 +792,8 @@
skipAnimation,
operationId,
requestId,
- multiSensorConfig);
+ multiSensorConfig,
+ mWakefulnessLifecycle);
if (newDialog == null) {
Log.e(TAG, "Unsupported type configuration");
@@ -868,7 +873,8 @@
protected AuthDialog buildDialog(PromptInfo promptInfo, boolean requireConfirmation,
int userId, int[] sensorIds, boolean credentialAllowed, String opPackageName,
boolean skipIntro, long operationId, long requestId,
- @BiometricMultiSensorMode int multiSensorConfig) {
+ @BiometricMultiSensorMode int multiSensorConfig,
+ WakefulnessLifecycle wakefulnessLifecycle) {
return new AuthContainerView.Builder(mContext)
.setCallback(this)
.setPromptInfo(promptInfo)
@@ -879,7 +885,7 @@
.setOperationId(operationId)
.setRequestId(requestId)
.setMultiSensorConfig(multiSensorConfig)
- .build(sensorIds, credentialAllowed, mFpProps, mFaceProps);
+ .build(sensorIds, credentialAllowed, mFpProps, mFaceProps, wakefulnessLifecycle);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 6581490..5ddfd75 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -28,6 +28,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.graphics.Point;
import android.graphics.RectF;
import android.hardware.biometrics.SensorLocationInternal;
import android.hardware.display.DisplayManager;
@@ -45,6 +46,7 @@
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
+import android.view.Surface;
import android.view.VelocityTracker;
import android.view.View;
import android.view.WindowManager;
@@ -414,8 +416,33 @@
final long sinceLastLog = mSystemClock.elapsedRealtime() - mTouchLogTime;
if (!isIlluminationRequested && !mGoodCaptureReceived &&
!exceedsVelocityThreshold) {
- onFingerDown((int) event.getRawX(), (int) event.getRawY(), minor,
- major);
+ final int rawX = (int) event.getRawX();
+ final int rawY = (int) event.getRawY();
+ // Default coordinates assume portrait mode.
+ int x = rawX;
+ int y = rawY;
+
+ // Gets the size based on the current rotation of the display.
+ Point p = new Point();
+ mContext.getDisplay().getRealSize(p);
+
+ // Transform x, y to portrait mode if the device is in landscape mode.
+ switch (mContext.getDisplay().getRotation()) {
+ case Surface.ROTATION_90:
+ x = p.y - rawY;
+ y = rawX;
+ break;
+
+ case Surface.ROTATION_270:
+ x = rawY;
+ y = p.x - rawX;
+ break;
+
+ default:
+ // Do nothing to stay in portrait mode.
+ }
+
+ onFingerDown(x, y, minor, major);
Log.v(TAG, "onTouch | finger down: " + touchInfo);
mTouchLogTime = mSystemClock.elapsedRealtime();
mPowerManager.userActivity(mSystemClock.uptimeMillis(),
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
index 4758ab0..dc3d1b5 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
@@ -41,12 +41,12 @@
* The activity being launched is specified by {@link android.service.controls.Control#getAppIntent}.
*/
class DetailDialog(
- val activityContext: Context?,
+ val activityContext: Context,
val taskView: TaskView,
val pendingIntent: PendingIntent,
val cvh: ControlViewHolder
) : Dialog(
- activityContext ?: cvh.context,
+ activityContext,
R.style.Theme_SystemUI_Dialog_Control_DetailPanel
) {
companion object {
@@ -58,6 +58,10 @@
}
var detailTaskId = INVALID_TASK_ID
+ private lateinit var taskViewContainer: View
+ private val taskWidthPercentWidth = activityContext.resources.getFloat(
+ R.dimen.controls_task_view_width_percentage
+ )
private val fillInIntent = Intent().apply {
putExtra(EXTRA_USE_PANEL, true)
@@ -75,13 +79,18 @@
val stateCallback = object : TaskView.Listener {
override fun onInitialized() {
- val options = activityContext?.let {
- ActivityOptions.makeCustomAnimation(
- it,
- 0 /* enterResId */,
- 0 /* exitResId */
- )
- } ?: ActivityOptions.makeBasic()
+ taskViewContainer.apply {
+ // For some devices, limit the overall width of the taskView
+ val lp = getLayoutParams()
+ lp.width = (getWidth() * taskWidthPercentWidth).toInt()
+ setLayoutParams(lp)
+ }
+
+ val options = ActivityOptions.makeCustomAnimation(
+ activityContext,
+ 0 /* enterResId */,
+ 0 /* exitResId */
+ )
taskView.startActivity(
pendingIntent,
fillInIntent,
@@ -112,16 +121,14 @@
}
init {
- if (activityContext == null) {
- window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY)
- }
-
// To pass touches to the task inside TaskView.
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)
window.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY)
setContentView(R.layout.controls_detail_dialog)
+ taskViewContainer = requireViewById<ViewGroup>(R.id.control_task_view_container)
+
requireViewById<ViewGroup>(R.id.controls_activity_view).apply {
addView(taskView)
setAlpha(0f)
@@ -130,6 +137,9 @@
requireViewById<ImageView>(R.id.control_detail_close).apply {
setOnClickListener { _: View -> dismiss() }
}
+ requireViewById<View>(R.id.control_detail_root).apply {
+ setOnClickListener { _: View -> dismiss() }
+ }
requireViewById<ImageView>(R.id.control_detail_open_in_app).apply {
setOnClickListener { v: View ->
@@ -145,17 +155,10 @@
// consume all insets to achieve slide under effect
window.getDecorView().setOnApplyWindowInsetsListener {
v: View, insets: WindowInsets ->
- taskView.apply {
- val l = getPaddingLeft()
- val t = getPaddingTop()
- val r = getPaddingRight()
- setPadding(l, t, r, insets.getInsets(Type.systemBars()).bottom)
- }
-
val l = v.getPaddingLeft()
- val b = v.getPaddingBottom()
val r = v.getPaddingRight()
- v.setPadding(l, insets.getInsets(Type.systemBars()).top, r, b)
+ val insets = insets.getInsets(Type.systemBars())
+ v.setPadding(l, insets.top, r, insets.bottom)
WindowInsets.CONSUMED
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index e465ae4..85c9644 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -77,6 +77,10 @@
@Override
public int getItemCount() {
+ if (mController.isZeroMode()) {
+ // Add extra one for "pair new" or dynamic group
+ return mController.getMediaDevices().size() + 1;
+ }
return mController.getMediaDevices().size();
}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index ad4a2f4..dbd641b 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -58,7 +58,6 @@
import com.android.settingslib.Utils;
import com.android.settingslib.fuelgauge.BatterySaverUtils;
import com.android.settingslib.utils.PowerUtil;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SystemUIApplication;
import com.android.systemui.dagger.SysUISingleton;
@@ -421,7 +420,7 @@
new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse(url))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- Dependency.get(ActivityStarter.class).startActivity(helpIntent,
+ mActivityStarter.startActivity(helpIntent,
true /* dismissShade */, resultCode -> {
mHighTempDialog = null;
});
@@ -456,7 +455,7 @@
new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse(url))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- Dependency.get(ActivityStarter.class).startActivity(helpIntent,
+ mActivityStarter.startActivity(helpIntent,
true /* dismissShade */, resultCode -> {
mThermalShutdownDialog = null;
});
@@ -516,7 +515,7 @@
helpIntent.setClassName("com.android.settings",
"com.android.settings.HelpTrampoline");
helpIntent.putExtra(Intent.EXTRA_TEXT, contextString);
- Dependency.get(ActivityStarter.class).startActivity(helpIntent,
+ mActivityStarter.startActivity(helpIntent,
true /* dismissShade */, resultCode -> {
mUsbHighTempDialog = null;
});
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 37a0f59..642af59 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -43,7 +43,6 @@
import com.android.settingslib.fuelgauge.Estimate;
import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.CoreStartable;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
@@ -80,13 +79,13 @@
@VisibleForTesting
final Receiver mReceiver = new Receiver();
- private PowerManager mPowerManager;
- private WarningsUI mWarnings;
+ private final PowerManager mPowerManager;
+ private final WarningsUI mWarnings;
private InattentiveSleepWarningView mOverlayView;
private final Configuration mLastConfiguration = new Configuration();
private int mPlugType = 0;
private int mInvalidCharger = 0;
- private EnhancedEstimates mEnhancedEstimates;
+ private final EnhancedEstimates mEnhancedEstimates;
private Future mLastShowWarningTask;
private boolean mEnableSkinTemperatureWarning;
private boolean mEnableUsbTemperatureAlarm;
@@ -113,18 +112,20 @@
@Inject
public PowerUI(Context context, BroadcastDispatcher broadcastDispatcher,
- CommandQueue commandQueue, Lazy<Optional<StatusBar>> statusBarOptionalLazy) {
+ CommandQueue commandQueue, Lazy<Optional<StatusBar>> statusBarOptionalLazy,
+ WarningsUI warningsUI, EnhancedEstimates enhancedEstimates,
+ PowerManager powerManager) {
super(context);
mBroadcastDispatcher = broadcastDispatcher;
mCommandQueue = commandQueue;
mStatusBarOptionalLazy = statusBarOptionalLazy;
+ mWarnings = warningsUI;
+ mEnhancedEstimates = enhancedEstimates;
+ mPowerManager = powerManager;
}
public void start() {
- mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mScreenOffTime = mPowerManager.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
- mWarnings = Dependency.get(WarningsUI.class);
- mEnhancedEstimates = Dependency.get(EnhancedEstimates.class);
mLastConfiguration.setTo(mContext.getResources().getConfiguration());
ContentObserver obs = new ContentObserver(mHandler) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index 1dba536..ded6ae0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -85,6 +85,7 @@
private final QSPanelController mQsPanelController;
private final QuickQSPanelController mQuickQSPanelController;
private final QuickStatusBarHeader mQuickStatusBarHeader;
+ private final QSFgsManagerFooter mFgsManagerFooter;
private final QSSecurityFooter mSecurityFooter;
private final QS mQs;
private final View mQSFooterActions;
@@ -151,7 +152,8 @@
public QSAnimator(QS qs, QuickQSPanel quickPanel, QuickStatusBarHeader quickStatusBarHeader,
QSPanelController qsPanelController,
QuickQSPanelController quickQSPanelController, QSTileHost qsTileHost,
- QSSecurityFooter securityFooter, @Main Executor executor, TunerService tunerService,
+ QSFgsManagerFooter fgsManagerFooter, QSSecurityFooter securityFooter,
+ @Main Executor executor, TunerService tunerService,
QSExpansionPathInterpolator qsExpansionPathInterpolator,
@Named(QS_FOOTER) FooterActionsView qsFooterActionsView,
@Named(QQS_FOOTER) FooterActionsView qqsFooterActionsView) {
@@ -162,6 +164,7 @@
mQuickStatusBarHeader = quickStatusBarHeader;
mQQSFooterActions = qqsFooterActionsView;
mQSFooterActions = qsFooterActionsView;
+ mFgsManagerFooter = fgsManagerFooter;
mSecurityFooter = securityFooter;
mHost = qsTileHost;
mExecutor = executor;
@@ -481,6 +484,7 @@
// Fade in the security footer and the divider as we reach the final position
Builder builder = new Builder().setStartDelay(EXPANDED_TILE_DELAY);
+ builder.addFloat(mFgsManagerFooter.getView(), "alpha", 0, 1);
builder.addFloat(mSecurityFooter.getView(), "alpha", 0, 1);
if (mQsPanelController.shouldUseHorizontalLayout()
&& mQsPanelController.mMediaHost.hostView != null) {
@@ -490,6 +494,7 @@
mQsPanelController.mMediaHost.hostView.setAlpha(1.0f);
}
mAllPagesDelayedAnimator = builder.build();
+ mAllViews.add(mFgsManagerFooter.getView());
mAllViews.add(mSecurityFooter.getView());
translationYBuilder.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator());
qqsTranslationYBuilder.setInterpolator(mQSExpansionPathInterpolator.getYInterpolator());
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java
new file mode 100644
index 0000000..082de16
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFgsManagerFooter.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2022 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.qs;
+
+import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;
+
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED;
+import static com.android.systemui.qs.dagger.QSFragmentModule.QS_FGS_MANAGER_FOOTER_VIEW;
+
+import android.content.Context;
+import android.provider.DeviceConfig;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.fgsmanager.FgsManagerDialogFactory;
+import com.android.systemui.statusbar.policy.RunningFgsController;
+
+import java.util.concurrent.Executor;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+/**
+ * Footer entry point for the foreground service manager
+ */
+public class QSFgsManagerFooter implements View.OnClickListener {
+
+ private final View mRootView;
+ private final TextView mFooterText;
+ private final Context mContext;
+ private final Executor mMainExecutor;
+ private final Executor mExecutor;
+ private final RunningFgsController mRunningFgsController;
+ private final FgsManagerDialogFactory mFgsManagerDialogFactory;
+
+ private boolean mIsInitialized = false;
+ private boolean mIsAvailable = false;
+
+ @Inject
+ QSFgsManagerFooter(@Named(QS_FGS_MANAGER_FOOTER_VIEW) View rootView,
+ @Main Executor mainExecutor, RunningFgsController runningFgsController,
+ @Background Executor executor,
+ FgsManagerDialogFactory fgsManagerDialogFactory) {
+ mRootView = rootView;
+ mFooterText = mRootView.findViewById(R.id.footer_text);
+ ImageView icon = mRootView.findViewById(R.id.primary_footer_icon);
+ icon.setImageResource(R.drawable.ic_info_outline);
+ mContext = rootView.getContext();
+ mMainExecutor = mainExecutor;
+ mExecutor = executor;
+ mRunningFgsController = runningFgsController;
+ mFgsManagerDialogFactory = fgsManagerDialogFactory;
+ }
+
+ public void init() {
+ if (mIsInitialized) {
+ return;
+ }
+
+ mRootView.setOnClickListener(this);
+
+ mRunningFgsController.addCallback(packages -> refreshState());
+
+ DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_SYSTEMUI, mExecutor,
+ (DeviceConfig.OnPropertiesChangedListener) properties -> {
+ mIsAvailable = properties.getBoolean(TASK_MANAGER_ENABLED, mIsAvailable);
+ });
+ mIsAvailable = DeviceConfig.getBoolean(NAMESPACE_SYSTEMUI, TASK_MANAGER_ENABLED, false);
+
+ mIsInitialized = true;
+ }
+
+ @Override
+ public void onClick(View view) {
+ mFgsManagerDialogFactory.create(mRootView);
+ }
+
+ public void refreshState() {
+ mExecutor.execute(this::handleRefreshState);
+ }
+
+ public View getView() {
+ return mRootView;
+ }
+
+ private boolean isAvailable() {
+ return mIsAvailable;
+ }
+
+ public void handleRefreshState() {
+ int numPackages = mRunningFgsController.getPackagesWithFgs().size();
+ mMainExecutor.execute(() -> {
+ mFooterText.setText(mContext.getResources().getQuantityString(
+ R.plurals.fgs_manager_footer_label, numPackages, numPackages));
+ mRootView.setVisibility(numPackages > 0 && isAvailable() ? View.VISIBLE : View.GONE);
+ });
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 38061a8..6b515c8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -86,6 +86,8 @@
new ArrayList<>();
@Nullable
+ protected View mFgsManagerFooter;
+ @Nullable
protected View mSecurityFooter;
@Nullable
@@ -448,7 +450,12 @@
switchToParent(mSecurityFooter, mHeaderContainer, 0);
} else {
// Add after the footer
- int index = indexOfChild(mFooter);
+ int index;
+ if (mFgsManagerFooter != null) {
+ index = indexOfChild(mFgsManagerFooter);
+ } else {
+ index = indexOfChild(mFooter);
+ }
switchToParent(mSecurityFooter, this, index + 1);
}
}
@@ -722,6 +729,17 @@
switchSecurityFooter(shouldUseSplitNotificationShade);
}
+ /**
+ * Set the fgs manager footer view and switch it into the right place
+ * @param view the view in question
+ */
+ public void setFgsManagerFooter(View view) {
+ mFgsManagerFooter = view;
+ // Add after the footer
+ int index = indexOfChild(mFooter);
+ switchToParent(mFgsManagerFooter, this, index + 1);
+ }
+
protected void setPageMargin(int pageMargin) {
if (mTileLayout instanceof PagedTileLayout) {
((PagedTileLayout) mTileLayout).setPageMargin(pageMargin);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
index 001c740e..cbfe944 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelController.java
@@ -57,6 +57,7 @@
public class QSPanelController extends QSPanelControllerBase<QSPanel> {
public static final String QS_REMOVE_LABELS = "sysui_remove_labels";
+ private final QSFgsManagerFooter mQSFgsManagerFooter;
private final QSSecurityFooter mQsSecurityFooter;
private final TunerService mTunerService;
private final QSCustomizerController mQsCustomizerController;
@@ -94,7 +95,8 @@
};
@Inject
- QSPanelController(QSPanel view, QSSecurityFooter qsSecurityFooter, TunerService tunerService,
+ QSPanelController(QSPanel view, QSFgsManagerFooter qsFgsManagerFooter,
+ QSSecurityFooter qsSecurityFooter, TunerService tunerService,
QSTileHost qstileHost, QSCustomizerController qsCustomizerController,
@Named(QS_USING_MEDIA_PLAYER) boolean usingMediaPlayer,
@Named(QS_PANEL) MediaHost mediaHost,
@@ -105,6 +107,7 @@
FalsingManager falsingManager, CommandQueue commandQueue) {
super(view, qstileHost, qsCustomizerController, usingMediaPlayer, mediaHost,
metricsLogger, uiEventLogger, qsLogger, dumpManager);
+ mQSFgsManagerFooter = qsFgsManagerFooter;
mQsSecurityFooter = qsSecurityFooter;
mTunerService = tunerService;
mQsCustomizerController = qsCustomizerController;
@@ -128,6 +131,7 @@
mMediaHost.init(MediaHierarchyManager.LOCATION_QS);
mQsCustomizerController.init();
mBrightnessSliderController.init();
+ mQSFgsManagerFooter.init();
}
private void updateMediaExpansion() {
@@ -146,6 +150,7 @@
refreshAllTiles();
}
mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener);
+ mView.setFgsManagerFooter(mQSFgsManagerFooter.getView());
mView.setSecurityFooter(mQsSecurityFooter.getView(), mShouldUseSplitNotificationShade);
switchTileLayout(true);
mBrightnessMirrorHandler.onQsPanelAttached();
@@ -230,6 +235,7 @@
public void refreshAllTiles() {
mBrightnessController.checkRestrictionAndSetEnabled();
super.refreshAllTiles();
+ mQSFgsManagerFooter.refreshState();
mQsSecurityFooter.refreshState();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index d3bad16..90cf92a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -181,6 +181,7 @@
}
private void clearAccessibilityState() {
+ mNeedsFocus = false;
if (mAccessibilityAction == ACTION_ADD) {
// Remove blank tile from last spot
mTiles.remove(--mEditIndex);
@@ -415,9 +416,6 @@
int oldLeft, int oldTop, int oldRight, int oldBottom) {
holder.mTileView.removeOnLayoutChangeListener(this);
holder.mTileView.requestAccessibilityFocus();
- if (mAccessibilityAction == ACTION_NONE) {
- holder.mTileView.clearAccessibilityFocus();
- }
}
});
mNeedsFocus = false;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
index 11e5b6e..1958caf 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
@@ -53,6 +53,7 @@
*/
@Module
public interface QSFragmentModule {
+ String QS_FGS_MANAGER_FOOTER_VIEW = "qs_fgs_manager_footer";
String QS_SECURITY_FOOTER_VIEW = "qs_security_footer";
String QQS_FOOTER = "qqs_footer";
String QS_FOOTER = "qs_footer";
@@ -205,4 +206,15 @@
static StatusIconContainer providesStatusIconContainer(QuickStatusBarHeader qsHeader) {
return qsHeader.findViewById(R.id.statusIcons);
}
+
+ /** */
+ @Provides
+ @QSScope
+ @Named(QS_FGS_MANAGER_FOOTER_VIEW)
+ static View providesQSFgsManagerFooterView(
+ @QSThemedContext LayoutInflater layoutInflater,
+ QSPanel qsPanel
+ ) {
+ return layoutInflater.inflate(R.layout.quick_settings_security_footer, qsPanel, false);
+ }
}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
index 5e68f61..86fc4de 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
@@ -39,7 +39,6 @@
import com.android.systemui.qs.tiles.DataSaverTile;
import com.android.systemui.qs.tiles.DeviceControlsTile;
import com.android.systemui.qs.tiles.DndTile;
-import com.android.systemui.qs.tiles.FgsManagerTile;
import com.android.systemui.qs.tiles.FlashlightTile;
import com.android.systemui.qs.tiles.HotspotTile;
import com.android.systemui.qs.tiles.InternetTile;
@@ -99,7 +98,6 @@
private final Provider<QuickAccessWalletTile> mQuickAccessWalletTileProvider;
private final Provider<QRCodeScannerTile> mQRCodeScannerTileProvider;
private final Provider<OneHandedModeTile> mOneHandedModeTileProvider;
- private final Provider<FgsManagerTile> mFgsManagerTileProvider;
private final Lazy<QSHost> mQsHostLazy;
private final Provider<CustomTile.Builder> mCustomTileBuilderProvider;
@@ -137,7 +135,6 @@
Provider<QuickAccessWalletTile> quickAccessWalletTileProvider,
Provider<QRCodeScannerTile> qrCodeScannerTileProvider,
Provider<OneHandedModeTile> oneHandedModeTileProvider,
- Provider<FgsManagerTile> fgsManagerTileProvider,
Provider<ColorCorrectionTile> colorCorrectionTileProvider) {
mQsHostLazy = qsHostLazy;
mCustomTileBuilderProvider = customTileBuilderProvider;
@@ -171,7 +168,6 @@
mQuickAccessWalletTileProvider = quickAccessWalletTileProvider;
mQRCodeScannerTileProvider = qrCodeScannerTileProvider;
mOneHandedModeTileProvider = oneHandedModeTileProvider;
- mFgsManagerTileProvider = fgsManagerTileProvider;
mColorCorrectionTileProvider = colorCorrectionTileProvider;
}
@@ -246,8 +242,6 @@
return mQRCodeScannerTileProvider.get();
case "onehanded":
return mOneHandedModeTileProvider.get();
- case "fgsmanager":
- return mFgsManagerTileProvider.get();
case "color_correction":
return mColorCorrectionTileProvider.get();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index 7efb983..821dfa5f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -653,7 +653,6 @@
"qr_code_scanner" to R.array.tile_states_qr_code_scanner,
"alarm" to R.array.tile_states_alarm,
"onehanded" to R.array.tile_states_onehanded,
- "fgsmanager" to R.array.tile_states_fgsmanager,
"color_correction" to R.array.tile_states_color_correction
)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FgsManagerTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/FgsManagerTile.kt
deleted file mode 100644
index 939a297..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FgsManagerTile.kt
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.qs.tiles
-
-import android.content.Intent
-import android.os.Handler
-import android.os.Looper
-import android.provider.DeviceConfig
-import android.view.View
-import com.android.internal.config.sysui.SystemUiDeviceConfigFlags
-import com.android.internal.logging.MetricsLogger
-import com.android.systemui.DejankUtils
-import com.android.systemui.R
-import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.fgsmanager.FgsManagerDialogFactory
-import com.android.systemui.plugins.ActivityStarter
-import com.android.systemui.plugins.FalsingManager
-import com.android.systemui.plugins.qs.QSTile
-import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.qs.QSHost
-import com.android.systemui.qs.logging.QSLogger
-import com.android.systemui.qs.tileimpl.QSTileImpl
-import com.android.systemui.statusbar.policy.RunningFgsController
-import com.android.systemui.statusbar.policy.RunningFgsController.UserPackageTime
-import java.util.concurrent.Executor
-import javax.inject.Inject
-
-/**
- * Quicksettings tile for the foreground services manager (task manager)
- */
-class FgsManagerTile @Inject constructor(
- host: QSHost?,
- @Background backgroundLooper: Looper?,
- @Background private val backgroundExecutor: Executor?,
- @Main mainHandler: Handler?,
- falsingManager: FalsingManager?,
- metricsLogger: MetricsLogger?,
- statusBarStateController: StatusBarStateController?,
- activityStarter: ActivityStarter?,
- qsLogger: QSLogger?,
- private val fgsManagerDialogFactory: FgsManagerDialogFactory,
- private val runningFgsController: RunningFgsController
-) : QSTileImpl<QSTile.State>(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
- statusBarStateController, activityStarter, qsLogger), RunningFgsController.Callback {
-
- override fun handleInitialize() {
- super.handleInitialize()
- mUiHandler.post { runningFgsController.observe(lifecycle, this) }
- }
-
- override fun isAvailable(): Boolean {
- return DejankUtils.whitelistIpcs<Boolean> {
- DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI,
- SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED, false)
- }
- }
-
- override fun newTileState(): QSTile.State {
- return QSTile.State()
- }
-
- override fun handleClick(view: View?) {
- mUiHandler.post { fgsManagerDialogFactory.create(view) }
- }
-
- override fun handleUpdateState(state: QSTile.State?, arg: Any?) {
- state?.label = tileLabel
- state?.secondaryLabel = runningFgsController.getPackagesWithFgs().size.toString()
- state?.handlesLongClick = false
- state?.icon = ResourceIcon.get(R.drawable.ic_list)
- }
-
- override fun getMetricsCategory(): Int = 0
-
- override fun getLongClickIntent(): Intent? = null
-
- // Inline the string so we don't waste translator time since this isn't used in the mocks.
- // TODO If mocks change need to remember to move this to strings.xml
- override fun getTileLabel(): CharSequence = "Active apps"
-
- override fun onFgsPackagesChanged(packages: List<UserPackageTime>) = refreshState()
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
index d7d1de0..991a68f 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessController.java
@@ -398,6 +398,11 @@
min = mBrightnessMin;
max = mBrightnessMax;
}
+
+ // Ensure the slider is in a fixed position first, then check if we should animate.
+ if (mSliderAnimator != null && mSliderAnimator.isStarted()) {
+ mSliderAnimator.cancel();
+ }
// convertGammaToLinearFloat returns 0-1
if (BrightnessSynchronizer.floatEquals(brightnessValue,
convertGammaToLinearFloat(mControl.getValue(), min, max))) {
@@ -420,9 +425,6 @@
mControl.setValue(target);
mControlValueInitialized = true;
}
- if (mSliderAnimator != null && mSliderAnimator.isStarted()) {
- mSliderAnimator.cancel();
- }
mSliderAnimator = ValueAnimator.ofInt(mControl.getValue(), target);
mSliderAnimator.addUpdateListener((ValueAnimator animation) -> {
mExternalChange = true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 963a0d7..6335f88 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -151,6 +151,7 @@
private boolean mPowerPluggedIn;
private boolean mPowerPluggedInWired;
private boolean mPowerPluggedInWireless;
+ private boolean mPowerPluggedInDock;
private boolean mPowerCharged;
private boolean mBatteryOverheated;
private boolean mEnableBatteryDefender;
@@ -786,6 +787,10 @@
chargingId = hasChargingTime
? R.string.keyguard_indication_charging_time_wireless
: R.string.keyguard_plugged_in_wireless;
+ } else if (mPowerPluggedInDock) {
+ chargingId = hasChargingTime
+ ? R.string.keyguard_indication_charging_time_dock
+ : R.string.keyguard_plugged_in_dock;
} else {
chargingId = hasChargingTime
? R.string.keyguard_indication_charging_time
@@ -911,6 +916,7 @@
boolean wasPluggedIn = mPowerPluggedIn;
mPowerPluggedInWired = status.isPluggedInWired() && isChargingOrFull;
mPowerPluggedInWireless = status.isPluggedInWireless() && isChargingOrFull;
+ mPowerPluggedInDock = status.isPluggedInDock() && isChargingOrFull;
mPowerPluggedIn = status.isPluggedIn() && isChargingOrFull;
mPowerCharged = status.isCharged();
mChargingWattage = status.maxChargingWattage;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionHeaderVisibilityProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionHeaderVisibilityProvider.kt
index 03b978e..68bdd18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionHeaderVisibilityProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionHeaderVisibilityProvider.kt
@@ -16,7 +16,9 @@
package com.android.systemui.statusbar.notification
+import android.content.Context
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.R
import javax.inject.Inject
/**
@@ -29,6 +31,10 @@
* visibility when it invalidates, and we just store that state here.)
*/
@SysUISingleton
-class SectionHeaderVisibilityProvider @Inject constructor() {
+class SectionHeaderVisibilityProvider @Inject constructor(
+ context: Context
+) {
+ var neverShowSectionHeaders = context.resources.getBoolean(R.bool.config_notification_never_show_section_headers)
+ private set
var sectionHeadersVisible = true
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
index 733be9c..0ce07cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
@@ -220,8 +220,10 @@
}
private void invalidateListFromFilter(String reason) {
- mSectionHeaderVisibilityProvider.setSectionHeadersVisible(
- mStatusBarStateController.getState() != StatusBarState.KEYGUARD);
+ boolean onKeyguard = mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
+ boolean neverShowSections = mSectionHeaderVisibilityProvider.getNeverShowSectionHeaders();
+ boolean showSections = !onKeyguard && !neverShowSections;
+ mSectionHeaderVisibilityProvider.setSectionHeadersVisible(showSections);
mNotifFilter.invalidateList();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 769f689..e59c99a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -3928,6 +3928,15 @@
mKeyguardStatusViewController.animateFoldToAod();
}
+ /**
+ * Cancels fold to AOD transition and resets view state
+ */
+ public void cancelFoldToAodAnimation() {
+ cancelAnimation();
+ resetAlpha();
+ resetTranslation();
+ }
+
/** */
public void setImportantForAccessibility(int mode) {
mView.setImportantForAccessibility(mode);
@@ -4046,6 +4055,10 @@
mView.setTranslationX(0f);
}
+ public void resetAlpha() {
+ mView.setAlpha(1f);
+ }
+
public ViewPropertyAnimator fadeOut(long startDelayMs, long durationMs, Runnable endAction) {
return mView.animate().alpha(0).setStartDelay(startDelayMs).setDuration(
durationMs).setInterpolator(Interpolators.ALPHA_OUT).withLayer().withEndAction(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 455ffdc..d3f2794 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -2998,7 +2998,7 @@
}
private void onLaunchTransitionFadingEnded() {
- mNotificationPanelViewController.setAlpha(1.0f);
+ mNotificationPanelViewController.resetAlpha();
mNotificationPanelViewController.onAffordanceLaunchEnded();
releaseGestureWakeLock();
runLaunchTransitionEndRunnable();
@@ -3029,7 +3029,7 @@
}
updateScrimController();
mPresenter.updateMediaMetaData(false, true);
- mNotificationPanelViewController.setAlpha(1);
+ mNotificationPanelViewController.resetAlpha();
mNotificationPanelViewController.fadeOut(
FADE_KEYGUARD_START_DELAY, FADE_KEYGUARD_DURATION,
this::onLaunchTransitionFadingEnded);
@@ -3130,7 +3130,7 @@
releaseGestureWakeLock();
mNotificationPanelViewController.onAffordanceLaunchEnded();
mNotificationPanelViewController.cancelAnimation();
- mNotificationPanelViewController.setAlpha(1f);
+ mNotificationPanelViewController.resetAlpha();
mNotificationPanelViewController.resetTranslation();
mNotificationPanelViewController.resetViewGroupFade();
updateDozingState();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index 59969c0..5e91a25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -30,6 +30,7 @@
import android.content.PermissionChecker;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
+import android.database.ContentObserver;
import android.location.LocationManager;
import android.os.Handler;
import android.os.Looper;
@@ -43,6 +44,8 @@
import androidx.annotation.VisibleForTesting;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
import com.android.systemui.BootCompleteCache;
import com.android.systemui.appops.AppOpItem;
import com.android.systemui.appops.AppOpsController;
@@ -53,6 +56,7 @@
import com.android.systemui.settings.UserTracker;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.Utils;
+import com.android.systemui.util.settings.SecureSettings;
import java.util.ArrayList;
import java.util.List;
@@ -71,30 +75,48 @@
private final DeviceConfigProxy mDeviceConfigProxy;
private final BootCompleteCache mBootCompleteCache;
private final UserTracker mUserTracker;
+ private final UiEventLogger mUiEventLogger;
private final H mHandler;
private final Handler mBackgroundHandler;
private final PackageManager mPackageManager;
+ private final ContentObserver mContentObserver;
+ private final SecureSettings mSecureSettings;
private boolean mAreActiveLocationRequests;
private boolean mShouldDisplayAllAccesses;
- private boolean mShowSystemAccesses;
+ private boolean mShowSystemAccessesFlag;
+ private boolean mShowSystemAccessesSetting;
@Inject
public LocationControllerImpl(Context context, AppOpsController appOpsController,
DeviceConfigProxy deviceConfigProxy,
@Main Looper mainLooper, @Background Handler backgroundHandler,
BroadcastDispatcher broadcastDispatcher, BootCompleteCache bootCompleteCache,
- UserTracker userTracker, PackageManager packageManager) {
+ UserTracker userTracker, PackageManager packageManager, UiEventLogger uiEventLogger,
+ SecureSettings secureSettings) {
mContext = context;
mAppOpsController = appOpsController;
mDeviceConfigProxy = deviceConfigProxy;
mBootCompleteCache = bootCompleteCache;
mHandler = new H(mainLooper);
mUserTracker = userTracker;
+ mUiEventLogger = uiEventLogger;
+ mSecureSettings = secureSettings;
mBackgroundHandler = backgroundHandler;
mPackageManager = packageManager;
mShouldDisplayAllAccesses = getAllAccessesSetting();
- mShowSystemAccesses = getShowSystemSetting();
+ mShowSystemAccessesFlag = getShowSystemFlag();
+ mShowSystemAccessesSetting = getShowSystemSetting();
+ mContentObserver = new ContentObserver(mBackgroundHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ mShowSystemAccessesSetting = getShowSystemSetting();
+ }
+ };
+
+ // Register to listen for changes in Settings.Secure settings.
+ mSecureSettings.registerContentObserver(
+ Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, mContentObserver);
// Register to listen for changes in DeviceConfig settings.
mDeviceConfigProxy.addOnPropertiesChangedListener(
@@ -102,7 +124,7 @@
backgroundHandler::post,
properties -> {
mShouldDisplayAllAccesses = getAllAccessesSetting();
- mShowSystemAccesses = getShowSystemSetting();
+ mShowSystemAccessesFlag = getShowSystemSetting();
updateActiveLocationRequests();
});
@@ -191,10 +213,15 @@
SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_SMALL_ENABLED, false);
}
- private boolean getShowSystemSetting() {
+ private boolean getShowSystemFlag() {
return mDeviceConfigProxy.getBoolean(DeviceConfig.NAMESPACE_PRIVACY,
SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_SHOW_SYSTEM, false);
}
+
+ private boolean getShowSystemSetting() {
+ return mSecureSettings.getInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0) == 1;
+ }
+
/**
* Returns true if there currently exist active high power location requests.
*/
@@ -222,6 +249,10 @@
}
boolean hadActiveLocationRequests = mAreActiveLocationRequests;
boolean shouldDisplay = false;
+ boolean showSystem = mShowSystemAccessesFlag || mShowSystemAccessesSetting;
+ boolean systemAppOp = false;
+ boolean nonSystemAppOp = false;
+ boolean isSystemApp;
List<AppOpItem> appOpsItems = mAppOpsController.getActiveAppOps();
final List<UserInfo> profiles = mUserTracker.getUserProfiles();
@@ -229,18 +260,38 @@
for (int i = 0; i < numItems; i++) {
if (appOpsItems.get(i).getCode() == OP_FINE_LOCATION
|| appOpsItems.get(i).getCode() == OP_COARSE_LOCATION) {
- if (mShowSystemAccesses) {
- shouldDisplay = true;
+ isSystemApp = isSystemApp(profiles, appOpsItems.get(i));
+ if (isSystemApp) {
+ systemAppOp = true;
} else {
- shouldDisplay |= !isSystemApp(profiles, appOpsItems.get(i));
+ nonSystemAppOp = true;
}
+
+ shouldDisplay = showSystem || shouldDisplay || !isSystemApp;
}
}
- mAreActiveLocationRequests = areActiveHighPowerLocationRequests() || shouldDisplay;
+ boolean highPowerOp = areActiveHighPowerLocationRequests();
+ mAreActiveLocationRequests = highPowerOp || shouldDisplay;
if (mAreActiveLocationRequests != hadActiveLocationRequests) {
mHandler.sendEmptyMessage(H.MSG_LOCATION_ACTIVE_CHANGED);
}
+
+ // Log each of the types of location access that would cause the location indicator to be
+ // shown, regardless of device's setting state. This is used to understand how often a
+ // user would see the location indicator based on any settings state the device could be in.
+ if (!hadActiveLocationRequests && (highPowerOp || systemAppOp || nonSystemAppOp)) {
+ if (highPowerOp) {
+ mUiEventLogger.log(
+ LocationIndicatorEvent.LOCATION_INDICATOR_MONITOR_HIGH_POWER);
+ }
+ if (systemAppOp) {
+ mUiEventLogger.log(LocationIndicatorEvent.LOCATION_INDICATOR_SYSTEM_APP);
+ }
+ if (nonSystemAppOp) {
+ mUiEventLogger.log(LocationIndicatorEvent.LOCATION_INDICATOR_NON_SYSTEM_APP);
+ }
+ }
}
private boolean isSystemApp(List<UserInfo> profiles, AppOpItem item) {
@@ -283,6 +334,11 @@
mAreActiveLocationRequests = areActiveHighPowerLocationRequests();
if (mAreActiveLocationRequests != hadActiveLocationRequests) {
mHandler.sendEmptyMessage(H.MSG_LOCATION_ACTIVE_CHANGED);
+ if (mAreActiveLocationRequests) {
+ // Log that the indicator was shown for a high power op.
+ mUiEventLogger.log(
+ LocationIndicatorEvent.LOCATION_INDICATOR_MONITOR_HIGH_POWER);
+ }
}
}
}
@@ -341,4 +397,24 @@
cb -> cb.onLocationSettingsChanged(isEnabled));
}
}
-}
+
+ /**
+ * Enum for events which prompt the location indicator to appear.
+ */
+ enum LocationIndicatorEvent implements UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "Location indicator shown for high power access")
+ LOCATION_INDICATOR_MONITOR_HIGH_POWER(935),
+ @UiEvent(doc = "Location indicator shown for system app access")
+ LOCATION_INDICATOR_SYSTEM_APP(936),
+ @UiEvent(doc = "Location indicator shown for non system app access")
+ LOCATION_INDICATOR_NON_SYSTEM_APP(937);
+
+ private final int mId;
+ LocationIndicatorEvent(int id) {
+ mId = id;
+ }
+ @Override public int getId() {
+ return mId;
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/VpnStatusObserver.kt b/packages/SystemUI/src/com/android/systemui/statusbar/tv/VpnStatusObserver.kt
index e25a105..c199744 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/VpnStatusObserver.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/VpnStatusObserver.kt
@@ -25,7 +25,6 @@
import com.android.internal.messages.nano.SystemMessageProto
import com.android.internal.net.VpnConfig
import com.android.systemui.CoreStartable
-import com.android.systemui.Dependency
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.policy.SecurityController
@@ -35,12 +34,13 @@
* Observes if a vpn connection is active and displays a notification to the user
*/
@SysUISingleton
-class VpnStatusObserver @Inject constructor(context: Context) : CoreStartable(context),
+class VpnStatusObserver @Inject constructor(
+ context: Context,
+ private val securityController: SecurityController
+) : CoreStartable(context),
SecurityController.SecurityControllerCallback {
private var vpnConnected = false
- private val securityController: SecurityController =
- Dependency.get(SecurityController::class.java)
private val notificationManager = NotificationManager.from(context)
private val notificationChannel = createNotificationChannel()
private val vpnConnectedNotificationBuilder = createVpnConnectedNotificationBuilder()
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt b/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt
index aaf35af..c481fc9 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/FoldAodAnimationController.kt
@@ -16,8 +16,10 @@
package com.android.systemui.unfold
+import android.os.Handler
import android.os.PowerManager
import android.provider.Settings
+import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.statusbar.LightRevealScrim
@@ -37,6 +39,7 @@
class FoldAodAnimationController
@Inject
constructor(
+ @Main private val handler: Handler,
private val keyguardViewMediatorLazy: Lazy<KeyguardViewMediator>,
private val wakefulnessLifecycle: WakefulnessLifecycle,
private val globalSettings: GlobalSettings
@@ -50,6 +53,14 @@
private var shouldPlayAnimation = false
private val statusListeners = arrayListOf<FoldAodAnimationStatus>()
+ private val startAnimationRunnable = Runnable {
+ statusBar.notificationPanelViewController.startFoldToAodAnimation {
+ // End action
+ isAnimationPlaying = false
+ keyguardViewMediatorLazy.get().maybeHandlePendingLock()
+ }
+ }
+
private var isAnimationPlaying = false
override fun initialize(statusBar: StatusBar, lightRevealScrim: LightRevealScrim) {
@@ -79,6 +90,11 @@
}
override fun onStartedWakingUp() {
+ if (isAnimationPlaying) {
+ handler.removeCallbacks(startAnimationRunnable)
+ statusBar.notificationPanelViewController.cancelFoldToAodAnimation();
+ }
+
shouldPlayAnimation = false
isAnimationPlaying = false
}
@@ -115,11 +131,10 @@
fun onScreenTurnedOn() {
if (shouldPlayAnimation) {
- statusBar.notificationPanelViewController.startFoldToAodAnimation {
- // End action
- isAnimationPlaying = false
- keyguardViewMediatorLazy.get().maybeHandlePendingLock()
- }
+ handler.removeCallbacks(startAnimationRunnable)
+
+ // Post starting the animation to the next frame to avoid junk due to inset changes
+ handler.post(startAnimationRunnable)
shouldPlayAnimation = false
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java b/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java
index be5e0a0..089650c 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/DumpTruck.java
@@ -26,8 +26,6 @@
import androidx.core.content.FileProvider;
-import com.android.systemui.Dependency;
-
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
@@ -35,7 +33,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -53,12 +50,14 @@
private static final int BUFSIZ = 1024 * 1024; // 1MB
private final Context context;
+ private GarbageMonitor mGarbageMonitor;
private Uri hprofUri;
private long rss;
final StringBuilder body = new StringBuilder();
- public DumpTruck(Context context) {
+ public DumpTruck(Context context, GarbageMonitor garbageMonitor) {
this.context = context;
+ mGarbageMonitor = garbageMonitor;
}
/**
@@ -68,8 +67,6 @@
* @return this, for chaining
*/
public DumpTruck captureHeaps(List<Long> pids) {
- final GarbageMonitor gm = Dependency.get(GarbageMonitor.class);
-
final File dumpDir = new File(context.getCacheDir(), FILEPROVIDER_PATH);
dumpDir.mkdirs();
hprofUri = null;
@@ -83,16 +80,14 @@
for (Long pidL : pids) {
final int pid = pidL.intValue();
body.append(" pid ").append(pid);
- if (gm != null) {
- GarbageMonitor.ProcessMemInfo info = gm.getMemInfo(pid);
- if (info != null) {
- body.append(":")
- .append(" up=")
- .append(info.getUptime())
- .append(" rss=")
- .append(info.currentRss);
- rss = info.currentRss;
- }
+ GarbageMonitor.ProcessMemInfo info = mGarbageMonitor.getMemInfo(pid);
+ if (info != null) {
+ body.append(":")
+ .append(" up=")
+ .append(info.getUptime())
+ .append(" rss=")
+ .append(info.currentRss);
+ rss = info.currentRss;
}
if (pid == myPid) {
final String path =
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
index 612b7cb..9fed158 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
@@ -150,7 +150,7 @@
mTrackedGarbage = leakDetector.getTrackedGarbage();
mLeakReporter = leakReporter;
- mDumpTruck = new DumpTruck(mContext);
+ mDumpTruck = new DumpTruck(mContext, this);
dumpManager.registerDumpable(getClass().getSimpleName(), this);
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
index 31b17f8..6fefce2 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShell.java
@@ -41,7 +41,6 @@
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.CoreStartable;
-import com.android.systemui.Dependency;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.WMComponent;
import com.android.systemui.dagger.qualifiers.Main;
@@ -125,6 +124,7 @@
private final SysUiState mSysUiState;
private final WakefulnessLifecycle mWakefulnessLifecycle;
private final ProtoTracer mProtoTracer;
+ private final UserInfoController mUserInfoController;
private final Executor mSysUiMainExecutor;
private boolean mIsSysUiStateValid;
@@ -153,6 +153,7 @@
SysUiState sysUiState,
ProtoTracer protoTracer,
WakefulnessLifecycle wakefulnessLifecycle,
+ UserInfoController userInfoController,
@Main Executor sysUiMainExecutor) {
super(context);
mCommandQueue = commandQueue;
@@ -171,6 +172,7 @@
mShellCommandHandler = shellCommandHandler;
mCompatUIOptional = sizeCompatUIOptional;
mDragAndDropOptional = dragAndDropOptional;
+ mUserInfoController = userInfoController;
mSysUiMainExecutor = sysUiMainExecutor;
}
@@ -231,8 +233,7 @@
});
// The media session listener needs to be re-registered when switching users
- UserInfoController userInfoController = Dependency.get(UserInfoController.class);
- userInfoController.addCallback((String name, Drawable picture, String userAccount) ->
+ mUserInfoController.addCallback((String name, Drawable picture, String userAccount) ->
pip.registerSessionListenerForCurrentUser());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
index 0b399cf..ae1268d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.java
@@ -56,6 +56,7 @@
import android.widget.ScrollView;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
import org.junit.Before;
import org.junit.Test;
@@ -75,6 +76,7 @@
private @Mock AuthDialogCallback mCallback;
private @Mock UserManager mUserManager;
+ private @Mock WakefulnessLifecycle mWakefulnessLifecycle;
@Before
public void setup() {
@@ -263,15 +265,17 @@
componentInfo,
FingerprintSensorProperties.TYPE_REAR,
false /* resetLockoutRequiresHardwareAuthToken */));
- mAuthContainer = new TestableAuthContainer(config, fpProps, null /* faceProps */);
+ mAuthContainer = new TestableAuthContainer(config, fpProps, null /* faceProps */,
+ mWakefulnessLifecycle);
}
private class TestableAuthContainer extends AuthContainerView {
TestableAuthContainer(AuthContainerView.Config config,
@Nullable List<FingerprintSensorPropertiesInternal> fpProps,
- @Nullable List<FaceSensorPropertiesInternal> faceProps) {
+ @Nullable List<FaceSensorPropertiesInternal> faceProps,
+ WakefulnessLifecycle wakefulnessLifecycle) {
- super(config, new MockInjector(), fpProps, faceProps);
+ super(config, new MockInjector(), fpProps, faceProps, wakefulnessLifecycle);
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 08c7714..786f547 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -69,6 +69,7 @@
import com.android.internal.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.util.concurrency.Execution;
import com.android.systemui.util.concurrency.FakeExecution;
@@ -117,6 +118,8 @@
private SidefpsController mSidefpsController;
@Mock
private DisplayManager mDisplayManager;
+ @Mock
+ private WakefulnessLifecycle mWakefulnessLifecycle;
@Captor
ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mAuthenticatorsRegisteredCaptor;
@Captor
@@ -677,14 +680,15 @@
Provider<SidefpsController> sidefpsControllerFactory) {
super(context, execution, commandQueue, activityTaskManager, windowManager,
fingerprintManager, faceManager, udfpsControllerFactory,
- sidefpsControllerFactory, mDisplayManager, mHandler);
+ sidefpsControllerFactory, mDisplayManager, mWakefulnessLifecycle, mHandler);
}
@Override
protected AuthDialog buildDialog(PromptInfo promptInfo,
boolean requireConfirmation, int userId, int[] sensorIds, boolean credentialAllowed,
String opPackageName, boolean skipIntro, long operationId, long requestId,
- @BiometricManager.BiometricMultiSensorMode int multiSensorConfig) {
+ @BiometricManager.BiometricMultiSensorMode int multiSensorConfig,
+ WakefulnessLifecycle wakefulnessLifecycle) {
mLastBiometricPromptInfo = promptInfo;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
index 89c0712..421ae03 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputAdapterTest.java
@@ -100,7 +100,7 @@
public void getItemCount_zeroMode_containExtraOneForPairNew() {
when(mMediaOutputController.isZeroMode()).thenReturn(true);
- assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size());
+ assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaDevices.size() + 1);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
index e73e5ff..721809c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
@@ -28,7 +28,6 @@
import static org.mockito.Mockito.when;
import android.content.BroadcastReceiver;
-import android.content.Context;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Handler;
@@ -81,9 +80,9 @@
private static final int OLD_BATTERY_LEVEL_10 = 10;
private static final long VERY_BELOW_SEVERE_HYBRID_THRESHOLD = TimeUnit.MINUTES.toMillis(15);
public static final int BATTERY_LEVEL_10 = 10;
- private WarningsUI mMockWarnings;
+ @Mock private WarningsUI mMockWarnings;
private PowerUI mPowerUI;
- private EnhancedEstimates mEnhancedEstimates;
+ @Mock private EnhancedEstimates mEnhancedEstimates;
@Mock private PowerManager mPowerManager;
@Mock private IThermalService mThermalServiceMock;
private IThermalEventListener mUsbThermalEventListener;
@@ -96,13 +95,9 @@
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- mMockWarnings = mDependency.injectMockDependency(WarningsUI.class);
- mEnhancedEstimates = mDependency.injectMockDependency(EnhancedEstimates.class);
when(mStatusBarOptionalLazy.get()).thenReturn(Optional.of(mStatusBar));
- mContext.addMockSystemService(Context.POWER_SERVICE, mPowerManager);
-
createPowerUi();
mSkinThermalEventListener = mPowerUI.new SkinThermalEventListener();
mUsbThermalEventListener = mPowerUI.new UsbThermalEventListener();
@@ -690,7 +685,8 @@
private void createPowerUi() {
mPowerUI = new PowerUI(
- mContext, mBroadcastDispatcher, mCommandQueue, mStatusBarOptionalLazy);
+ mContext, mBroadcastDispatcher, mCommandQueue, mStatusBarOptionalLazy,
+ mMockWarnings, mEnhancedEstimates, mPowerManager);
mPowerUI.mThermalService = mThermalServiceMock;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
index 3242adb..b5ce706 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.java
@@ -80,6 +80,8 @@
@Mock
private TunerService mTunerService;
@Mock
+ private QSFgsManagerFooter mQSFgsManagerFooter;
+ @Mock
private QSSecurityFooter mQSSecurityFooter;
@Mock
private QSLogger mQSLogger;
@@ -127,8 +129,8 @@
.thenReturn(mQSTileRevealController);
when(mMediaHost.getDisappearParameters()).thenReturn(new DisappearParameters());
- mController = new QSPanelController(mQSPanel, mQSSecurityFooter, mTunerService,
- mQSTileHost, mQSCustomizerController, true, mMediaHost,
+ mController = new QSPanelController(mQSPanel, mQSFgsManagerFooter, mQSSecurityFooter,
+ mTunerService, mQSTileHost, mQSCustomizerController, true, mMediaHost,
mQSTileRevealControllerFactory, mDumpManager, mMetricsLogger, mUiEventLogger,
mQSLogger, mBrightnessControllerFactory, mToggleSliderViewControllerFactory,
mFalsingManager, mCommandQueue
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt
index 968b12a..88b133e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt
@@ -34,7 +34,6 @@
import com.android.systemui.qs.tiles.DataSaverTile
import com.android.systemui.qs.tiles.DeviceControlsTile
import com.android.systemui.qs.tiles.DndTile
-import com.android.systemui.qs.tiles.FgsManagerTile
import com.android.systemui.qs.tiles.FlashlightTile
import com.android.systemui.qs.tiles.HotspotTile
import com.android.systemui.qs.tiles.InternetTile
@@ -92,7 +91,6 @@
"wallet" to QuickAccessWalletTile::class.java,
"qr_code_scanner" to QRCodeScannerTile::class.java,
"onehanded" to OneHandedModeTile::class.java,
- "fgsmanager" to FgsManagerTile::class.java,
"color_correction" to ColorCorrectionTile::class.java
)
@@ -133,7 +131,6 @@
@Mock private lateinit var quickAccessWalletTile: QuickAccessWalletTile
@Mock private lateinit var qrCodeScannerTile: QRCodeScannerTile
@Mock private lateinit var oneHandedModeTile: OneHandedModeTile
- @Mock private lateinit var fgsManagerTile: FgsManagerTile
@Mock private lateinit var colorCorrectionTile: ColorCorrectionTile
private lateinit var factory: QSFactoryImpl
@@ -178,7 +175,6 @@
{ quickAccessWalletTile },
{ qrCodeScannerTile },
{ oneHandedModeTile },
- { fgsManagerTile },
{ colorCorrectionTile }
)
// When adding/removing tiles, fix also [specMap]
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
index 2126dda..f5554c5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/LocationControllerImplTest.java
@@ -14,6 +14,8 @@
package com.android.systemui.statusbar.policy;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -27,6 +29,7 @@
import android.os.Handler;
import android.os.UserHandle;
import android.provider.DeviceConfig;
+import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
@@ -34,6 +37,7 @@
import androidx.test.filters.SmallTest;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
+import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.BootCompleteCache;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.appops.AppOpItem;
@@ -43,6 +47,7 @@
import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback;
import com.android.systemui.util.DeviceConfigProxy;
import com.android.systemui.util.DeviceConfigProxyFake;
+import com.android.systemui.util.settings.SecureSettings;
import com.google.common.collect.ImmutableList;
@@ -60,9 +65,11 @@
private LocationControllerImpl mLocationController;
private TestableLooper mTestableLooper;
private DeviceConfigProxy mDeviceConfigProxy;
+ private UiEventLoggerFake mUiEventLogger;
@Mock private AppOpsController mAppOpsController;
@Mock private UserTracker mUserTracker;
+ @Mock private SecureSettings mSecureSettings;
@Before
public void setup() {
@@ -72,6 +79,7 @@
when(mUserTracker.getUserProfiles())
.thenReturn(ImmutableList.of(new UserInfo(0, "name", 0)));
mDeviceConfigProxy = new DeviceConfigProxyFake();
+ mUiEventLogger = new UiEventLoggerFake();
mTestableLooper = TestableLooper.get(this);
mLocationController = new LocationControllerImpl(mContext,
@@ -82,7 +90,9 @@
mock(BroadcastDispatcher.class),
mock(BootCompleteCache.class),
mUserTracker,
- mContext.getPackageManager());
+ mContext.getPackageManager(),
+ mUiEventLogger,
+ mSecureSettings);
mTestableLooper.processAllMessages();
}
@@ -160,6 +170,10 @@
mTestableLooper.processAllMessages();
verify(callback, times(1)).onLocationActiveChanged(anyBoolean());
+ assertThat(mUiEventLogger.numLogs()).isEqualTo(1);
+ assertThat(mUiEventLogger.eventId(0)).isEqualTo(
+ LocationControllerImpl.LocationIndicatorEvent.LOCATION_INDICATOR_MONITOR_HIGH_POWER
+ .getId());
}
@Test
@@ -194,7 +208,7 @@
}
@Test
- public void testCallbackNotified_additionalOps_shouldShowSystem() {
+ public void testCallbackNotified_additionalOps_shouldNotShowSystem() {
LocationChangeCallback callback = mock(LocationChangeCallback.class);
mLocationController.addCallback(callback);
mDeviceConfigProxy.setProperty(
@@ -219,7 +233,9 @@
@Test
- public void testCallbackNotified_additionalOps_shouldNotShowSystem() {
+ public void testCallbackNotified_additionalOps_shouldShowSystem() {
+ when(mSecureSettings.getInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0))
+ .thenReturn(1);
LocationChangeCallback callback = mock(LocationChangeCallback.class);
mLocationController.addCallback(callback);
mDeviceConfigProxy.setProperty(
@@ -251,6 +267,66 @@
mTestableLooper.processAllMessages();
verify(callback, times(1)).onLocationActiveChanged(false);
+
+ when(mSecureSettings.getInt(Settings.Secure.LOCATION_SHOW_SYSTEM_OPS, 0))
+ .thenReturn(0);
+ mLocationController.onActiveStateChanged(AppOpsManager.OP_FINE_LOCATION, 0,
+ "com.google.android.gms", true);
+
+ mTestableLooper.processAllMessages();
+
+ // onLocationActive(true) was not called again because the setting is disabled.
+ verify(callback, times(1)).onLocationActiveChanged(true);
+ }
+
+ @Test
+ public void testCallbackNotified_verifyMetrics() {
+ LocationChangeCallback callback = mock(LocationChangeCallback.class);
+ mLocationController.addCallback(callback);
+ mDeviceConfigProxy.setProperty(
+ DeviceConfig.NAMESPACE_PRIVACY,
+ SystemUiDeviceConfigFlags.PROPERTY_LOCATION_INDICATORS_SMALL_ENABLED,
+ "true",
+ true);
+ mTestableLooper.processAllMessages();
+
+ when(mAppOpsController.getActiveAppOps())
+ .thenReturn(ImmutableList.of(
+ new AppOpItem(AppOpsManager.OP_FINE_LOCATION, 0, "com.google.android.gms",
+ System.currentTimeMillis()),
+ new AppOpItem(AppOpsManager.OP_COARSE_LOCATION, 0,
+ "com.google.android.googlequicksearchbox",
+ System.currentTimeMillis()),
+ new AppOpItem(AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION, 0,
+ "com.google.android.apps.maps",
+ System.currentTimeMillis())));
+ mLocationController.onActiveStateChanged(AppOpsManager.OP_FINE_LOCATION, 0,
+ "com.google.android.gms", true);
+
+ mTestableLooper.processAllMessages();
+
+ verify(callback, times(1)).onLocationActiveChanged(true);
+ assertThat(mUiEventLogger.numLogs()).isEqualTo(3);
+ assertThat(mUiEventLogger.eventId(0)).isEqualTo(
+ LocationControllerImpl.LocationIndicatorEvent.LOCATION_INDICATOR_MONITOR_HIGH_POWER
+ .getId());
+ // Even though the system access wasn't shown due to the device settings, ensure it was
+ // still logged.
+ assertThat(mUiEventLogger.eventId(1)).isEqualTo(
+ LocationControllerImpl.LocationIndicatorEvent.LOCATION_INDICATOR_SYSTEM_APP
+ .getId());
+ assertThat(mUiEventLogger.eventId(2)).isEqualTo(
+ LocationControllerImpl.LocationIndicatorEvent.LOCATION_INDICATOR_NON_SYSTEM_APP
+ .getId());
+ mUiEventLogger.getLogs().clear();
+
+ when(mAppOpsController.getActiveAppOps()).thenReturn(ImmutableList.of());
+ mLocationController.onActiveStateChanged(AppOpsManager.OP_FINE_LOCATION, 0,
+ "com.google.android.gms", false);
+ mTestableLooper.processAllMessages();
+
+ verify(callback, times(1)).onLocationActiveChanged(false);
+ assertThat(mUiEventLogger.numLogs()).isEqualTo(0);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
index 2f2e536..6593823 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/WMShellTest.java
@@ -32,6 +32,7 @@
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.tracing.ProtoTracer;
import com.android.wm.shell.ShellCommandHandler;
import com.android.wm.shell.common.ShellExecutor;
@@ -79,6 +80,7 @@
@Mock ProtoTracer mProtoTracer;
@Mock ShellCommandHandler mShellCommandHandler;
@Mock CompatUI mCompatUI;
+ @Mock UserInfoController mUserInfoController;
@Mock ShellExecutor mSysUiMainExecutor;
@Mock DragAndDrop mDragAndDrop;
@@ -92,7 +94,7 @@
Optional.of(mDragAndDrop),
mCommandQueue, mConfigurationController, mKeyguardUpdateMonitor,
mNavigationModeController, mScreenLifecycle, mSysUiState, mProtoTracer,
- mWakefulnessLifecycle, mSysUiMainExecutor);
+ mWakefulnessLifecycle, mUserInfoController, mSysUiMainExecutor);
}
@Test
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 5d48d78..2f8dea7 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -323,13 +323,20 @@
if (mHealthInfo.batteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) {
return true;
}
- if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_AC) != 0 && mHealthInfo.chargerAcOnline) {
+ if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_AC) != 0
+ && mHealthInfo.chargerAcOnline) {
return true;
}
- if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_USB) != 0 && mHealthInfo.chargerUsbOnline) {
+ if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_USB) != 0
+ && mHealthInfo.chargerUsbOnline) {
return true;
}
- if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0 && mHealthInfo.chargerWirelessOnline) {
+ if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0
+ && mHealthInfo.chargerWirelessOnline) {
+ return true;
+ }
+ if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_DOCK) != 0
+ && mHealthInfo.chargerDockOnline) {
return true;
}
return false;
@@ -442,6 +449,8 @@
return BatteryManager.BATTERY_PLUGGED_USB;
} else if (healthInfo.chargerWirelessOnline) {
return BatteryManager.BATTERY_PLUGGED_WIRELESS;
+ } else if (healthInfo.chargerDockOnline) {
+ return BatteryManager.BATTERY_PLUGGED_DOCK;
} else {
return BATTERY_PLUGGED_NONE;
}
@@ -1118,6 +1127,8 @@
batteryPluggedValue = OsProtoEnums.BATTERY_PLUGGED_USB;
} else if (mHealthInfo.chargerWirelessOnline) {
batteryPluggedValue = OsProtoEnums.BATTERY_PLUGGED_WIRELESS;
+ } else if (mHealthInfo.chargerDockOnline) {
+ batteryPluggedValue = OsProtoEnums.BATTERY_PLUGGED_DOCK;
}
proto.write(BatteryServiceDumpProto.PLUGGED, batteryPluggedValue);
proto.write(
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index b1b4c44..f67e732 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2871,51 +2871,13 @@
return mode == AppOpsManager.MODE_ALLOWED;
}
- /**
- * Checks whether the calling package is trusted.
- *
- * The calling package is trusted if it's from system or the supposed package name matches the
- * UID making the call.
- *
- * @throws SecurityException if the package name and UID don't match.
- */
- private void verifyCallingPackage(String callingPackage) {
- final int callingUid = Binder.getCallingUid();
- // The caller is System or Shell.
- if (callingUid == SYSTEM_UID || isCallerShell()) {
- return;
- }
-
- // Handle the special UIDs that don't have real package (audioserver, cameraserver, etc).
- final String resolvedPackage = AppOpsManager.resolvePackageName(callingUid,
- null /* packageName */);
- if (resolvedPackage != null && resolvedPackage.equals(callingPackage)) {
- return;
- }
-
- final int claimedUid = getPackageManagerInternal().getPackageUid(callingPackage,
- 0 /* flags */, UserHandle.getUserId(callingUid));
- if (callingUid == claimedUid) {
- return;
- }
-
- throw new SecurityException(
- "Claimed calling package " + callingPackage + " does not match the calling UID "
- + Binder.getCallingUid());
- }
-
- private void enforceUsageStatsPermission(String callingPackage, String func) {
- verifyCallingPackage(callingPackage);
- // Since the protection level of PACKAGE_USAGE_STATS has 'appop', apps may grant this
- // permission via that way. We need to check both app-ops and permission.
- if (!hasUsageStatsPermission(callingPackage)) {
- enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, func);
- }
- }
-
@Override
public int getPackageProcessState(String packageName, String callingPackage) {
- enforceUsageStatsPermission(callingPackage, "getPackageProcessState");
+ if (!hasUsageStatsPermission(callingPackage)) {
+ enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
+ "getPackageProcessState");
+ }
+
final int[] procState = {PROCESS_STATE_NONEXISTENT};
synchronized (mProcLock) {
mProcessList.forEachLruProcessesLOSP(false, proc -> {
@@ -6976,7 +6938,11 @@
@Override
public int getUidProcessState(int uid, String callingPackage) {
- enforceUsageStatsPermission(callingPackage, "getUidProcessState");
+ if (!hasUsageStatsPermission(callingPackage)) {
+ enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
+ "getUidProcessState");
+ }
+
synchronized (mProcLock) {
return mProcessList.getUidProcStateLOSP(uid);
}
@@ -6984,7 +6950,11 @@
@Override
public @ProcessCapability int getUidProcessCapabilities(int uid, String callingPackage) {
- enforceUsageStatsPermission(callingPackage, "getUidProcessCapabilities");
+ if (!hasUsageStatsPermission(callingPackage)) {
+ enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
+ "getUidProcessState");
+ }
+
synchronized (mProcLock) {
return mProcessList.getUidProcessCapabilityLOSP(uid);
}
@@ -6993,7 +6963,10 @@
@Override
public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
String callingPackage) {
- enforceUsageStatsPermission(callingPackage, "registerUidObserver");
+ if (!hasUsageStatsPermission(callingPackage)) {
+ enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
+ "registerUidObserver");
+ }
mUidObserverController.register(observer, which, cutpoint, callingPackage,
Binder.getCallingUid());
}
@@ -7005,7 +6978,10 @@
@Override
public boolean isUidActive(int uid, String callingPackage) {
- enforceUsageStatsPermission(callingPackage, "isUidActive");
+ if (!hasUsageStatsPermission(callingPackage)) {
+ enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
+ "isUidActive");
+ }
synchronized (mProcLock) {
if (isUidActiveLOSP(uid)) {
return true;
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index bb939b7..ec6b782 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -28,6 +28,7 @@
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AppGlobals;
@@ -37,6 +38,7 @@
import android.app.PendingIntent;
import android.app.RemoteServiceException.CannotDeliverBroadcastException;
import android.app.usage.UsageEvents.Event;
+import android.app.usage.UsageStatsManagerInternal;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.IIntentReceiver;
@@ -69,6 +71,7 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FrameworkStatsLog;
+import com.android.server.LocalServices;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -325,6 +328,7 @@
mService.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_START_RECEIVER);
// Tell the application to launch this receiver.
+ maybeReportBroadcastDispatchedEventLocked(r);
r.intent.setComponent(r.curComponent);
boolean started = false;
@@ -917,6 +921,7 @@
r.receiverTime = SystemClock.uptimeMillis();
maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r);
maybeScheduleTempAllowlistLocked(filter.owningUid, r, r.options);
+ maybeReportBroadcastDispatchedEventLocked(r);
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);
@@ -1831,6 +1836,45 @@
mPendingBroadcastRecvIndex = recIdx;
}
+
+ @Nullable
+ private String getTargetPackage(BroadcastRecord r) {
+ if (r.intent == null) {
+ return null;
+ }
+ if (r.intent.getPackage() != null) {
+ return r.intent.getPackage();
+ } else if (r.intent.getComponent() != null) {
+ return r.intent.getComponent().getPackageName();
+ }
+ return null;
+ }
+
+ private void maybeReportBroadcastDispatchedEventLocked(BroadcastRecord r) {
+ final String targetPackage = getTargetPackage(r);
+ // Ignore non-explicit broadcasts
+ if (targetPackage == null) {
+ return;
+ }
+ // TODO (206518114): Only allow apps with ACCESS_PACKAGE_USAGE_STATS to set
+ // getIdForResponseEvent.
+ if (r.options == null || r.options.getIdForResponseEvent() <= 0) {
+ return;
+ }
+ // TODO (206518114): Only report this event when the broadcast is dispatched while the app
+ // is in the background state.
+ getUsageStatsManagerInternal().reportBroadcastDispatched(
+ r.callingUid, targetPackage, UserHandle.of(r.userId),
+ r.options.getIdForResponseEvent(), SystemClock.elapsedRealtime());
+ }
+
+ @NonNull
+ private UsageStatsManagerInternal getUsageStatsManagerInternal() {
+ final UsageStatsManagerInternal usageStatsManagerInternal =
+ LocalServices.getService(UsageStatsManagerInternal.class);
+ return usageStatsManagerInternal;
+ }
+
private boolean noteOpForManifestReceiver(int appOp, BroadcastRecord r, ResolveInfo info,
ComponentName component) {
if (ArrayUtils.isEmpty(info.activityInfo.attributionTags)) {
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 6ec9836..42fca9b 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -371,7 +371,7 @@
* @return false if SCO isn't connected
*/
/*package*/ synchronized boolean isBluetoothScoOn() {
- if (mBluetoothHeadset == null) {
+ if (mBluetoothHeadset == null || mBluetoothHeadsetDevice == null) {
return false;
}
return mBluetoothHeadset.getAudioState(mBluetoothHeadsetDevice)
@@ -505,7 +505,7 @@
// Discard timeout message
mDeviceBroker.handleCancelFailureToConnectToBtHeadsetService();
mBluetoothHeadset = headset;
- setBtScoActiveDevice(mBluetoothHeadset.getActiveDevice());
+ setBtScoActiveDevice(headset != null ? headset.getActiveDevice() : null);
// Refresh SCO audio state
checkScoAudioState();
if (mScoAudioState != SCO_STATE_ACTIVATE_REQ
@@ -513,7 +513,7 @@
return;
}
boolean status = false;
- if (mBluetoothHeadsetDevice != null) {
+ if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
switch (mScoAudioState) {
case SCO_STATE_ACTIVATE_REQ:
status = connectBluetoothScoAudioHelper(
@@ -552,6 +552,9 @@
}
private AudioDeviceAttributes btHeadsetDeviceToAudioDevice(BluetoothDevice btDevice) {
+ if (btDevice == null) {
+ return new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, "");
+ }
String address = btDevice.getAddress();
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
address = "";
diff --git a/services/core/java/com/android/server/clipboard/OWNERS b/services/core/java/com/android/server/clipboard/OWNERS
index 5449df9..0d5dbf9 100644
--- a/services/core/java/com/android/server/clipboard/OWNERS
+++ b/services/core/java/com/android/server/clipboard/OWNERS
@@ -1 +1,3 @@
per-file EmulatorClipboardMonitor.java = bohu@google.com,lfy@google.com,rkir@google.com
+
+olilan@google.com
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index 240168b..a1d722b 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -32,6 +32,7 @@
import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.util.Preconditions;
import com.android.server.display.utils.Plog;
+import com.android.server.display.whitebalance.DisplayWhiteBalanceController;
import java.io.PrintWriter;
import java.util.Arrays;
@@ -69,7 +70,7 @@
@Nullable
public static BrightnessMappingStrategy create(Resources resources,
DisplayDeviceConfig displayDeviceConfig) {
- return create(resources, displayDeviceConfig, /* isForIdleMode= */ false);
+ return create(resources, displayDeviceConfig, /* isForIdleMode= */ false, null);
}
/**
@@ -80,8 +81,10 @@
*/
@Nullable
public static BrightnessMappingStrategy createForIdleMode(Resources resources,
- DisplayDeviceConfig displayDeviceConfig) {
- return create(resources, displayDeviceConfig, /* isForIdleMode= */ true);
+ DisplayDeviceConfig displayDeviceConfig, DisplayWhiteBalanceController
+ displayWhiteBalanceController) {
+ return create(resources, displayDeviceConfig, /* isForIdleMode= */ true,
+ displayWhiteBalanceController);
}
/**
@@ -96,7 +99,8 @@
*/
@Nullable
private static BrightnessMappingStrategy create(Resources resources,
- DisplayDeviceConfig displayDeviceConfig, boolean isForIdleMode) {
+ DisplayDeviceConfig displayDeviceConfig, boolean isForIdleMode,
+ DisplayWhiteBalanceController displayWhiteBalanceController) {
// Display independent, mode dependent values
float[] brightnessLevelsNits;
@@ -135,7 +139,7 @@
builder.setShortTermModelLowerLuxMultiplier(SHORT_TERM_MODEL_THRESHOLD_RATIO);
builder.setShortTermModelUpperLuxMultiplier(SHORT_TERM_MODEL_THRESHOLD_RATIO);
return new PhysicalMappingStrategy(builder.build(), nitsRange, brightnessRange,
- autoBrightnessAdjustmentMaxGamma, isForIdleMode);
+ autoBrightnessAdjustmentMaxGamma, isForIdleMode, displayWhiteBalanceController);
} else if (isValidMapping(luxLevels, brightnessLevelsBacklight) && !isForIdleMode) {
return new SimpleMappingStrategy(luxLevels, brightnessLevelsBacklight,
autoBrightnessAdjustmentMaxGamma, shortTermModelTimeout);
@@ -770,9 +774,11 @@
private float mUserLux;
private float mUserBrightness;
private final boolean mIsForIdleMode;
+ private final DisplayWhiteBalanceController mDisplayWhiteBalanceController;
public PhysicalMappingStrategy(BrightnessConfiguration config, float[] nits,
- float[] brightness, float maxGamma, boolean isForIdleMode) {
+ float[] brightness, float maxGamma, boolean isForIdleMode,
+ DisplayWhiteBalanceController displayWhiteBalanceController) {
Preconditions.checkArgument(nits.length != 0 && brightness.length != 0,
"Nits and brightness arrays must not be empty!");
@@ -789,6 +795,7 @@
mAutoBrightnessAdjustment = 0;
mUserLux = -1;
mUserBrightness = -1;
+ mDisplayWhiteBalanceController = displayWhiteBalanceController;
mNits = nits;
mBrightness = brightness;
@@ -836,6 +843,12 @@
public float getBrightness(float lux, String packageName,
@ApplicationInfo.Category int category) {
float nits = mBrightnessSpline.interpolate(lux);
+
+ // Adjust nits to compensate for display white balance colour strength.
+ if (mDisplayWhiteBalanceController != null && isForIdleMode()) {
+ nits = mDisplayWhiteBalanceController.calculateAdjustedBrightnessNits(nits);
+ }
+
float brightness = mNitsToBrightnessSpline.interpolate(nits);
// Correct the brightness according to the current application and its category, but
// only if no user data point is set (as this will override the user setting).
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 3feffc6..7ad4979 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -1318,7 +1318,9 @@
if (callingUid != Process.SYSTEM_UID
&& (flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) {
- if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) {
+ // The virtualDevice instance has been validated above using isValidVirtualDevice
+ if (virtualDevice == null
+ && !checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) {
throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to "
+ "create a virtual display which is not in the default DisplayGroup.");
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 31c496ed..ec4b91a 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -50,6 +50,8 @@
import android.provider.Settings;
import android.util.Log;
import android.util.MathUtils;
+import android.util.MutableFloat;
+import android.util.MutableInt;
import android.util.Slog;
import android.util.TimeUtils;
import android.view.Display;
@@ -895,7 +897,7 @@
mDisplayDeviceConfig);
if (isIdleScreenBrightnessEnabled) {
mIdleModeBrightnessMapper = BrightnessMappingStrategy.createForIdleMode(resources,
- mDisplayDeviceConfig);
+ mDisplayDeviceConfig, mDisplayWhiteBalanceController);
}
if (mInteractiveModeBrightnessMapper != null) {
@@ -1390,6 +1392,7 @@
// Animate the screen brightness when the screen is on or dozing.
// Skip the animation when the screen is off or suspended or transition to/from VR.
+ boolean brightnessAdjusted = false;
if (!mPendingScreenOff) {
if (mSkipScreenOnBrightnessRamp) {
if (state == Display.STATE_ON) {
@@ -1482,15 +1485,19 @@
// slider event so notify as if the system changed the brightness.
userInitiatedChange = false;
}
- notifyBrightnessChanged(brightnessState, userInitiatedChange,
+ notifyBrightnessTrackerChanged(brightnessState, userInitiatedChange,
hadUserBrightnessPoint);
}
// We save the brightness info *after* the brightness setting has been changed and
// adjustments made so that the brightness info reflects the latest value.
- saveBrightnessInfo(getScreenBrightnessSetting(), animateValue);
+ brightnessAdjusted = saveBrightnessInfo(getScreenBrightnessSetting(), animateValue);
} else {
- saveBrightnessInfo(getScreenBrightnessSetting());
+ brightnessAdjusted = saveBrightnessInfo(getScreenBrightnessSetting());
+ }
+
+ if (brightnessAdjusted) {
+ postBrightnessChangeRunnable();
}
// Log any changes to what is currently driving the brightness setting.
@@ -1606,31 +1613,50 @@
public BrightnessInfo getBrightnessInfo() {
synchronized (mCachedBrightnessInfo) {
return new BrightnessInfo(
- mCachedBrightnessInfo.brightness,
- mCachedBrightnessInfo.adjustedBrightness,
- mCachedBrightnessInfo.brightnessMin,
- mCachedBrightnessInfo.brightnessMax,
- mCachedBrightnessInfo.hbmMode,
- mCachedBrightnessInfo.highBrightnessTransitionPoint);
+ mCachedBrightnessInfo.brightness.value,
+ mCachedBrightnessInfo.adjustedBrightness.value,
+ mCachedBrightnessInfo.brightnessMin.value,
+ mCachedBrightnessInfo.brightnessMax.value,
+ mCachedBrightnessInfo.hbmMode.value,
+ mCachedBrightnessInfo.hbmTransitionPoint.value);
}
}
- private void saveBrightnessInfo(float brightness) {
- saveBrightnessInfo(brightness, brightness);
+ private boolean saveBrightnessInfo(float brightness) {
+ return saveBrightnessInfo(brightness, brightness);
}
- private void saveBrightnessInfo(float brightness, float adjustedBrightness) {
+ private boolean saveBrightnessInfo(float brightness, float adjustedBrightness) {
synchronized (mCachedBrightnessInfo) {
- mCachedBrightnessInfo.brightness = brightness;
- mCachedBrightnessInfo.adjustedBrightness = adjustedBrightness;
- mCachedBrightnessInfo.brightnessMin = mHbmController.getCurrentBrightnessMin();
- mCachedBrightnessInfo.brightnessMax = mHbmController.getCurrentBrightnessMax();
- mCachedBrightnessInfo.hbmMode = mHbmController.getHighBrightnessMode();
- mCachedBrightnessInfo.highBrightnessTransitionPoint =
- mHbmController.getTransitionPoint();
+ boolean changed = false;
+
+ changed |=
+ mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightness,
+ brightness);
+ changed |=
+ mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.adjustedBrightness,
+ adjustedBrightness);
+ changed |=
+ mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightnessMin,
+ mHbmController.getCurrentBrightnessMin());
+ changed |=
+ mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.brightnessMax,
+ mHbmController.getCurrentBrightnessMax());
+ changed |=
+ mCachedBrightnessInfo.checkAndSetInt(mCachedBrightnessInfo.hbmMode,
+ mHbmController.getHighBrightnessMode());
+ changed |=
+ mCachedBrightnessInfo.checkAndSetFloat(mCachedBrightnessInfo.hbmTransitionPoint,
+ mHbmController.getTransitionPoint());
+
+ return changed;
}
}
+ void postBrightnessChangeRunnable() {
+ mHandler.post(mOnBrightnessChangeRunnable);
+ }
+
private HighBrightnessModeController createHbmControllerLocked() {
final DisplayDevice device = mLogicalDisplay.getPrimaryDisplayDeviceLocked();
final DisplayDeviceConfig ddConfig = device.getDisplayDeviceConfig();
@@ -1645,7 +1671,7 @@
displayUniqueId, PowerManager.BRIGHTNESS_MIN, PowerManager.BRIGHTNESS_MAX, hbmData,
() -> {
sendUpdatePowerStateLocked();
- mHandler.post(mOnBrightnessChangeRunnable);
+ postBrightnessChangeRunnable();
// TODO(b/192258832): Switch the HBMChangeCallback to a listener pattern.
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.update();
@@ -2147,7 +2173,7 @@
private void setCurrentScreenBrightness(float brightnessValue) {
if (brightnessValue != mCurrentScreenBrightnessSetting) {
mCurrentScreenBrightnessSetting = brightnessValue;
- mHandler.post(mOnBrightnessChangeRunnable);
+ postBrightnessChangeRunnable();
}
}
@@ -2199,7 +2225,7 @@
return true;
}
- private void notifyBrightnessChanged(float brightness, boolean userInitiated,
+ private void notifyBrightnessTrackerChanged(float brightness, boolean userInitiated,
boolean hadUserDataPoint) {
final float brightnessInNits = convertToNits(brightness);
if (mPowerRequest.useAutoBrightness && brightnessInNits >= 0.0f
@@ -2309,16 +2335,17 @@
pw.println(" mColorFadeFadesConfig=" + mColorFadeFadesConfig);
pw.println(" mColorFadeEnabled=" + mColorFadeEnabled);
synchronized (mCachedBrightnessInfo) {
- pw.println(" mCachedBrightnessInfo.brightness=" + mCachedBrightnessInfo.brightness);
+ pw.println(" mCachedBrightnessInfo.brightness=" +
+ mCachedBrightnessInfo.brightness.value);
pw.println(" mCachedBrightnessInfo.adjustedBrightness=" +
- mCachedBrightnessInfo.adjustedBrightness);
+ mCachedBrightnessInfo.adjustedBrightness.value);
pw.println(" mCachedBrightnessInfo.brightnessMin=" +
- mCachedBrightnessInfo.brightnessMin);
+ mCachedBrightnessInfo.brightnessMin.value);
pw.println(" mCachedBrightnessInfo.brightnessMax=" +
- mCachedBrightnessInfo.brightnessMax);
- pw.println(" mCachedBrightnessInfo.hbmMode=" + mCachedBrightnessInfo.hbmMode);
- pw.println(" mCachedBrightnessInfo.highBrightnessTransitionPoint=" +
- mCachedBrightnessInfo.highBrightnessTransitionPoint);
+ mCachedBrightnessInfo.brightnessMax.value);
+ pw.println(" mCachedBrightnessInfo.hbmMode=" + mCachedBrightnessInfo.hbmMode.value);
+ pw.println(" mCachedBrightnessInfo.hbmTransitionPoint=" +
+ mCachedBrightnessInfo.hbmTransitionPoint.value);
}
pw.println(" mDisplayBlanksAfterDozeConfig=" + mDisplayBlanksAfterDozeConfig);
pw.println(" mBrightnessBucketsInDozeConfig=" + mBrightnessBucketsInDozeConfig);
@@ -2476,7 +2503,10 @@
private void reportStats(float brightness) {
float hbmTransitionPoint = PowerManager.BRIGHTNESS_MAX;
synchronized(mCachedBrightnessInfo) {
- hbmTransitionPoint = mCachedBrightnessInfo.highBrightnessTransitionPoint;
+ if (mCachedBrightnessInfo.hbmTransitionPoint == null) {
+ return;
+ }
+ hbmTransitionPoint = mCachedBrightnessInfo.hbmTransitionPoint.value;
}
final boolean aboveTransition = brightness > hbmTransitionPoint;
@@ -2773,11 +2803,31 @@
}
static class CachedBrightnessInfo {
- public float brightness;
- public float adjustedBrightness;
- public float brightnessMin;
- public float brightnessMax;
- public int hbmMode;
- public float highBrightnessTransitionPoint;
+ public MutableFloat brightness = new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+ public MutableFloat adjustedBrightness =
+ new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+ public MutableFloat brightnessMin =
+ new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+ public MutableFloat brightnessMax =
+ new MutableFloat(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+ public MutableInt hbmMode = new MutableInt(BrightnessInfo.HIGH_BRIGHTNESS_MODE_OFF);
+ public MutableFloat hbmTransitionPoint =
+ new MutableFloat(HighBrightnessModeController.HBM_TRANSITION_POINT_INVALID);
+
+ public boolean checkAndSetFloat(MutableFloat mf, float f) {
+ if (mf.value != f) {
+ mf.value = f;
+ return true;
+ }
+ return false;
+ }
+
+ public boolean checkAndSetInt(MutableInt mi, int i) {
+ if (mi.value != i) {
+ mi.value = i;
+ return true;
+ }
+ return false;
+ }
}
}
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index f9a1368..8035526 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -1453,7 +1453,7 @@
/**
* Local service that allows color transforms to be enabled from other system services.
*/
- public final class ColorDisplayServiceInternal {
+ public class ColorDisplayServiceInternal {
/**
* Set the current CCT value for the display white balance transform, and if the transform
@@ -1472,6 +1472,11 @@
return false;
}
+ /** Get the luminance of the current chromatic adaptation matrix. */
+ public float getDisplayWhiteBalanceLuminance() {
+ return mDisplayWhiteBalanceTintController.getLuminance();
+ }
+
/**
* Reset the CCT value for the display white balance transform to its default value.
*/
diff --git a/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java b/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java
index bdbaaa8..936149c 100644
--- a/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java
+++ b/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java
@@ -251,6 +251,18 @@
}
}
+ public float getLuminance() {
+ synchronized (mLock) {
+ if (mChromaticAdaptationMatrix != null && mChromaticAdaptationMatrix.length == 9) {
+ // Compute only the luminance (y) value of the xyz * [1 1 1] transform.
+ return 1 / (mChromaticAdaptationMatrix[1] + mChromaticAdaptationMatrix[4]
+ + mChromaticAdaptationMatrix[7]);
+ } else {
+ return -1;
+ }
+ }
+ }
+
private ColorSpace.Rgb makeRgbColorSpaceFromXYZ(float[] redGreenBlueXYZ, float[] whiteXYZ) {
return new ColorSpace.Rgb(
"Display Color Space",
diff --git a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java
index d64fcbc..151ec81 100644
--- a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java
+++ b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java
@@ -21,7 +21,6 @@
import android.util.Spline;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
import com.android.server.display.utils.AmbientFilter;
@@ -456,6 +455,22 @@
}
/**
+ * Calculate the adjusted brightness, in nits, due to the DWB color adaptation
+ *
+ * @param requestedBrightnessNits brightness the framework requires to be output
+ * @return the adjusted brightness the framework needs to output to counter the drop in
+ * brightness due to DWB, or the requestedBrightnessNits if an adjustment cannot be made
+ */
+ public float calculateAdjustedBrightnessNits(float requestedBrightnessNits) {
+ float luminance = mColorDisplayServiceInternal.getDisplayWhiteBalanceLuminance();
+ if (luminance == -1) {
+ return requestedBrightnessNits;
+ }
+ float effectiveBrightness = requestedBrightnessNits * luminance;
+ return (requestedBrightnessNits - effectiveBrightness) + requestedBrightnessNits;
+ }
+
+ /**
* The DisplayWhiteBalanceController decouples itself from its parent (DisplayPowerController)
* by providing this interface to implement (and a method to set its callbacks object), and
* calling these methods.
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 8a6aa0d..feb0d138 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -203,7 +203,7 @@
/**
* This class provides a system service that manages input methods.
*/
-public class InputMethodManagerService extends IInputMethodManager.Stub
+public final class InputMethodManagerService extends IInputMethodManager.Stub
implements Handler.Callback {
static final boolean DEBUG = false;
static final String TAG = "InputMethodManagerService";
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index c01851a..fac7a40 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -100,7 +100,6 @@
import static android.net.NetworkTemplate.MATCH_WIFI;
import static android.net.NetworkTemplate.buildTemplateCarrierMetered;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
-import static android.net.TrafficStats.MB_IN_BYTES;
import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
import static android.os.Trace.TRACE_TAG_NETWORK;
import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED;
@@ -182,7 +181,6 @@
import android.net.NetworkStateSnapshot;
import android.net.NetworkTemplate;
import android.net.TelephonyNetworkSpecifier;
-import android.net.TrafficStats;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.BestClock;
@@ -2299,7 +2297,7 @@
if (dataWarningConfig == WARNING_DISABLED) {
return WARNING_DISABLED;
} else {
- return dataWarningConfig * MB_IN_BYTES;
+ return DataUnit.MEBIBYTES.toBytes(dataWarningConfig);
}
}
@@ -3468,9 +3466,9 @@
plans.add(SubscriptionPlan.Builder
.createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
.setTitle("G-Mobile")
- .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+ .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
- .setDataUsage(1 * TrafficStats.GB_IN_BYTES,
+ .setDataUsage(DataUnit.GIBIBYTES.toBytes(1),
ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
.build());
plans.add(SubscriptionPlan.Builder
@@ -3478,15 +3476,15 @@
.setTitle("G-Mobile Happy")
.setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
- .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+ .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
.build());
plans.add(SubscriptionPlan.Builder
.createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
.setTitle("G-Mobile, Charged after limit")
- .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+ .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
SubscriptionPlan.LIMIT_BEHAVIOR_BILLED)
- .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+ .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
ZonedDateTime.now().minusHours(36).toInstant().toEpochMilli())
.build());
} else if ("month_soft".equals(fake)) {
@@ -3495,25 +3493,25 @@
.setTitle("G-Mobile is the carriers name who this plan belongs to")
.setSummary("Crazy unlimited bandwidth plan with incredibly long title "
+ "that should be cut off to prevent UI from looking terrible")
- .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+ .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
- .setDataUsage(1 * TrafficStats.GB_IN_BYTES,
+ .setDataUsage(DataUnit.GIBIBYTES.toBytes(1),
ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
.build());
plans.add(SubscriptionPlan.Builder
.createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
.setTitle("G-Mobile, Throttled after limit")
- .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+ .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
- .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+ .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
.build());
plans.add(SubscriptionPlan.Builder
.createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
.setTitle("G-Mobile, No data connection after limit")
- .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+ .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
- .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+ .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
.build());
@@ -3521,25 +3519,25 @@
plans.add(SubscriptionPlan.Builder
.createRecurringMonthly(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"))
.setTitle("G-Mobile is the carriers name who this plan belongs to")
- .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+ .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
- .setDataUsage(6 * TrafficStats.GB_IN_BYTES,
+ .setDataUsage(DataUnit.GIBIBYTES.toBytes(6),
ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
.build());
plans.add(SubscriptionPlan.Builder
.createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
.setTitle("G-Mobile, Throttled after limit")
- .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+ .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
- .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+ .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
.build());
plans.add(SubscriptionPlan.Builder
.createRecurringMonthly(ZonedDateTime.parse("2017-03-14T00:00:00.000Z"))
.setTitle("G-Mobile, No data connection after limit")
- .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+ .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
- .setDataUsage(5 * TrafficStats.GB_IN_BYTES,
+ .setDataUsage(DataUnit.GIBIBYTES.toBytes(5),
ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
.build());
@@ -3553,9 +3551,9 @@
.createNonrecurring(ZonedDateTime.now().minusDays(20),
ZonedDateTime.now().plusDays(10))
.setTitle("G-Mobile")
- .setDataLimit(512 * TrafficStats.MB_IN_BYTES,
+ .setDataLimit(DataUnit.MEBIBYTES.toBytes(512),
SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
- .setDataUsage(100 * TrafficStats.MB_IN_BYTES,
+ .setDataUsage(DataUnit.MEBIBYTES.toBytes(100),
ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
.build());
} else if ("prepaid_crazy".equals(fake)) {
@@ -3563,9 +3561,9 @@
.createNonrecurring(ZonedDateTime.now().minusDays(20),
ZonedDateTime.now().plusDays(10))
.setTitle("G-Mobile Anytime")
- .setDataLimit(512 * TrafficStats.MB_IN_BYTES,
+ .setDataLimit(DataUnit.MEBIBYTES.toBytes(512),
SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
- .setDataUsage(100 * TrafficStats.MB_IN_BYTES,
+ .setDataUsage(DataUnit.MEBIBYTES.toBytes(100),
ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
.build());
plans.add(SubscriptionPlan.Builder
@@ -3573,9 +3571,9 @@
ZonedDateTime.now().plusDays(20))
.setTitle("G-Mobile Nickel Nights")
.setSummary("5¢/GB between 1-5AM")
- .setDataLimit(5 * TrafficStats.GB_IN_BYTES,
+ .setDataLimit(DataUnit.GIBIBYTES.toBytes(5),
SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
- .setDataUsage(15 * TrafficStats.MB_IN_BYTES,
+ .setDataUsage(DataUnit.MEBIBYTES.toBytes(15),
ZonedDateTime.now().minusHours(30).toInstant().toEpochMilli())
.build());
plans.add(SubscriptionPlan.Builder
@@ -3583,9 +3581,9 @@
ZonedDateTime.now().plusDays(20))
.setTitle("G-Mobile Bonus 3G")
.setSummary("Unlimited 3G data")
- .setDataLimit(1 * TrafficStats.GB_IN_BYTES,
+ .setDataLimit(DataUnit.GIBIBYTES.toBytes(1),
SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
- .setDataUsage(300 * TrafficStats.MB_IN_BYTES,
+ .setDataUsage(DataUnit.MEBIBYTES.toBytes(300),
ZonedDateTime.now().minusHours(1).toInstant().toEpochMilli())
.build());
} else if ("unlimited".equals(fake)) {
@@ -3595,7 +3593,7 @@
.setTitle("G-Mobile Awesome")
.setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
- .setDataUsage(50 * TrafficStats.MB_IN_BYTES,
+ .setDataUsage(DataUnit.MEBIBYTES.toBytes(50),
ZonedDateTime.now().minusHours(3).toInstant().toEpochMilli())
.build());
}
diff --git a/services/core/java/com/android/server/notification/VibratorHelper.java b/services/core/java/com/android/server/notification/VibratorHelper.java
index 54dd113..e5d07bc 100644
--- a/services/core/java/com/android/server/notification/VibratorHelper.java
+++ b/services/core/java/com/android/server/notification/VibratorHelper.java
@@ -16,6 +16,9 @@
package com.android.server.notification;
+import static android.os.VibrationEffect.VibrationParameter.targetAmplitude;
+import static android.os.VibrationEffect.VibrationParameter.targetFrequency;
+
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
@@ -30,6 +33,7 @@
import com.android.internal.R;
import com.android.server.pm.PackageManagerService;
+import java.time.Duration;
import java.util.Arrays;
/**
@@ -89,8 +93,7 @@
* Safely create a {@link VibrationEffect} from given waveform description.
*
* <p>The waveform is described by a sequence of values for target amplitude, frequency and
- * duration, that are forwarded to
- * {@link VibrationEffect.WaveformBuilder#addRamp(float, float, int)}.
+ * duration, that are forwarded to {@link VibrationEffect.WaveformBuilder#addTransition}.
*
* <p>This method returns {@code null} if the pattern is also {@code null} or invalid.
*
@@ -114,16 +117,17 @@
VibrationEffect.WaveformBuilder waveformBuilder = VibrationEffect.startWaveform();
for (int i = 0; i < length; i += 3) {
- waveformBuilder.addRamp(
- /* amplitude= */ values[i],
- /* frequencyHz= */ values[i + 1],
- /* duration= */ (int) values[i + 2]);
+ waveformBuilder.addTransition(Duration.ofMillis((int) values[i + 2]),
+ targetAmplitude(values[i]), targetFrequency(values[i + 1]));
}
+ VibrationEffect effect = waveformBuilder.build();
if (insistent) {
- return waveformBuilder.build(/* repeat= */ 0);
+ return VibrationEffect.startComposition()
+ .repeatEffectIndefinitely(effect)
+ .compose();
}
- return waveformBuilder.build();
+ return effect;
} catch (IllegalArgumentException e) {
Slog.e(TAG, "Error creating vibration PWLE waveform with pattern: "
+ Arrays.toString(values));
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index d9ade96..390dd3f 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -2264,10 +2264,6 @@
}
if (params.isStaged) {
- // TODO(b/136257624): CTS test fails if we don't send session finished broadcast, even
- // though ideally, we just need to send session committed broadcast.
- sendUpdateToRemoteStatusReceiver(INSTALL_SUCCEEDED, "Session staged", null);
-
mStagedSession.verifySession();
} else {
verify();
@@ -2514,6 +2510,7 @@
mStagedSession.notifyEndPreRebootVerification();
if (error == SessionInfo.SESSION_NO_ERROR) {
mStagingManager.commitSession(mStagedSession);
+ sendUpdateToRemoteStatusReceiver(INSTALL_SUCCEEDED, "Session staged", null);
} else {
dispatchSessionFinished(INSTALL_FAILED_VERIFICATION_FAILURE, msg, null);
maybeFinishChildSessions(INSTALL_FAILED_VERIFICATION_FAILURE, msg);
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index fd2256f..99f70b2 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -3563,18 +3563,27 @@
}
final LocalIntentReceiver receiver = new LocalIntentReceiver();
session.commit(receiver.getIntentSender());
- final Intent result = receiver.getResult();
- final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
- PackageInstaller.STATUS_FAILURE);
- if (status == PackageInstaller.STATUS_SUCCESS) {
+ if (!session.isStaged()) {
+ final Intent result = receiver.getResult();
+ final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
+ PackageInstaller.STATUS_FAILURE);
+ if (status == PackageInstaller.STATUS_SUCCESS) {
+ if (logSuccess) {
+ pw.println("Success");
+ }
+ } else {
+ pw.println("Failure ["
+ + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
+ }
+ return status;
+ } else {
+ // Return immediately without retrieving the result. The caller will decide
+ // whether to wait for the session to become ready.
if (logSuccess) {
pw.println("Success");
}
- } else {
- pw.println("Failure ["
- + result.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE) + "]");
+ return PackageInstaller.STATUS_SUCCESS;
}
- return status;
} finally {
IoUtils.closeQuietly(session);
}
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 15e64df..72db242 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -35,8 +35,8 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.LocusId;
-import android.content.pm.AppSearchPerson;
import android.content.pm.AppSearchShortcutInfo;
+import android.content.pm.AppSearchShortcutPerson;
import android.content.pm.PackageInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
@@ -965,7 +965,7 @@
*/
public ArraySet<String> getUsedBitmapFiles() {
final ArraySet<String> usedFiles = new ArraySet<>(1);
- forEachShortcut(AppSearchShortcutInfo.QUERY_HAS_BITMAP_PATH, si -> {
+ forEachShortcut(si -> {
if (si.getBitmapPath() != null) {
usedFiles.add(getFileName(si.getBitmapPath()));
}
@@ -1176,7 +1176,7 @@
// Keep the previous IDs.
final ArraySet<String> toDisableList = new ArraySet<>(1);
- forEachShortcut(AppSearchShortcutInfo.QUERY_IS_MANIFEST, si -> {
+ forEachShortcut(si -> {
if (si.isManifestShortcut()) {
toDisableList.add(si.getId());
}
@@ -1319,7 +1319,7 @@
private ArrayMap<ComponentName, ArrayList<ShortcutInfo>> sortShortcutsToActivities() {
final ArrayMap<ComponentName, ArrayList<ShortcutInfo>> activitiesToShortcuts
= new ArrayMap<>();
- forEachShortcut(AppSearchShortcutInfo.QUERY_IS_NOT_FLOATING, si -> {
+ forEachShortcut(si -> {
if (si.isFloating()) {
return; // Ignore floating shortcuts, which are not tied to any activities.
}
@@ -1369,14 +1369,7 @@
// (If it's for update, then don't count dynamic shortcuts, since they'll be replaced
// anyway.)
final ArrayMap<ComponentName, Integer> counts = new ArrayMap<>(4);
- final String query;
- if (operation != ShortcutService.OPERATION_SET) {
- query = AppSearchShortcutInfo.QUERY_IS_MANIFEST + " OR "
- + AppSearchShortcutInfo.QUERY_IS_DYNAMIC;
- } else {
- query = AppSearchShortcutInfo.QUERY_IS_MANIFEST;
- }
- forEachShortcut(query, shortcut -> {
+ forEachShortcut(shortcut -> {
if (shortcut.isManifestShortcut()) {
incrementCountForActivity(counts, shortcut.getActivity(), 1);
} else if (shortcut.isDynamic() && (operation != ShortcutService.OPERATION_SET)) {
@@ -1539,7 +1532,7 @@
/** @return true if there's any shortcuts that are not manifest shortcuts. */
public boolean hasNonManifestShortcuts() {
final boolean[] condition = new boolean[1];
- forEachShortcutStopWhen(AppSearchShortcutInfo.QUERY_IS_NOT_MANIFEST, si -> {
+ forEachShortcutStopWhen(si -> {
if (!si.isDeclaredInManifest()) {
condition[0] = true;
return true;
@@ -2287,12 +2280,7 @@
}
private void forEachShortcut(@NonNull final Consumer<ShortcutInfo> cb) {
- forEachShortcut("", cb);
- }
-
- private void forEachShortcut(
- @NonNull final String query, @NonNull final Consumer<ShortcutInfo> cb) {
- forEachShortcutStopWhen(query, si -> {
+ forEachShortcutStopWhen(si -> {
cb.accept(si);
return false;
});
@@ -2307,11 +2295,6 @@
private void forEachShortcutStopWhen(
@NonNull final Function<ShortcutInfo, Boolean> cb) {
- forEachShortcutStopWhen("", cb);
- }
-
- private void forEachShortcutStopWhen(
- @NonNull final String query, @NonNull final Function<ShortcutInfo, Boolean> cb) {
for (int i = mShortcuts.size() - 1; i >= 0; i--) {
final ShortcutInfo si = mShortcuts.valueAt(i);
if (cb.apply(si)) {
@@ -2328,12 +2311,12 @@
+ " pkg=" + getPackageName());
}
SetSchemaRequest.Builder schemaBuilder = new SetSchemaRequest.Builder()
- .addSchemas(AppSearchPerson.SCHEMA, AppSearchShortcutInfo.SCHEMA)
+ .addSchemas(AppSearchShortcutPerson.SCHEMA, AppSearchShortcutInfo.SCHEMA)
.setForceOverride(true);
for (PackageIdentifier pi : mPackageIdentifiers.values()) {
schemaBuilder = schemaBuilder
.setSchemaTypeVisibilityForPackage(
- AppSearchPerson.SCHEMA_TYPE, true, pi)
+ AppSearchShortcutPerson.SCHEMA_TYPE, true, pi)
.setSchemaTypeVisibilityForPackage(
AppSearchShortcutInfo.SCHEMA_TYPE, true, pi);
}
@@ -2403,8 +2386,8 @@
.addIds(ids).build(), mShortcutUser.mExecutor, result -> {
final List<ShortcutInfo> ret = result.getSuccesses().values()
.stream().map(doc ->
- new AppSearchShortcutInfo(doc)
- .toShortcutInfo(mShortcutUser.getUserId()))
+ ShortcutInfo.createFromGenericDocument(
+ mShortcutUser.getUserId(), doc))
.collect(Collectors.toList());
cb.accept(ret);
});
@@ -2480,8 +2463,8 @@
}
cb.complete(results.getResultValue().stream()
.map(SearchResult::getGenericDocument)
- .map(AppSearchShortcutInfo::new)
- .map(si -> si.toShortcutInfo(mShortcutUser.getUserId()))
+ .map(doc -> ShortcutInfo.createFromGenericDocument(
+ mShortcutUser.getUserId(), doc))
.collect(Collectors.toList()));
});
}));
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 057f8de..8393dee 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -41,7 +41,6 @@
import android.content.IntentSender.SendIntentException;
import android.content.LocusId;
import android.content.pm.ActivityInfo;
-import android.content.pm.AppSearchShortcutInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ComponentInfo;
import android.content.pm.IPackageManager;
@@ -2805,28 +2804,6 @@
}
}
- private String createQuery(final boolean matchDynamic, final boolean matchPinned,
- final boolean matchManifest, final boolean matchCached) {
-
- final List<String> queries = new ArrayList<>(1);
- if (matchDynamic) {
- queries.add(AppSearchShortcutInfo.QUERY_IS_DYNAMIC);
- }
- if (matchPinned) {
- queries.add(AppSearchShortcutInfo.QUERY_IS_PINNED);
- }
- if (matchManifest) {
- queries.add(AppSearchShortcutInfo.QUERY_IS_MANIFEST);
- }
- if (matchCached) {
- queries.add(AppSearchShortcutInfo.QUERY_IS_CACHED);
- }
- if (queries.isEmpty()) {
- return "";
- }
- return "(" + String.join(" OR ", queries) + ")";
- }
-
/**
* Remove all the information associated with a package. This will really remove all the
* information, including the restore information (i.e. it'll remove packages even if they're
diff --git a/services/core/java/com/android/server/power/PowerGroup.java b/services/core/java/com/android/server/power/PowerGroup.java
index 9127484..c1bfdf7 100644
--- a/services/core/java/com/android/server/power/PowerGroup.java
+++ b/services/core/java/com/android/server/power/PowerGroup.java
@@ -16,9 +16,16 @@
package com.android.server.power;
+import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
+import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
+import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
+import static android.os.PowerManagerInternal.isInteractive;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
+import android.os.PowerManager;
+import android.os.Trace;
+import android.util.Slog;
import android.view.Display;
/**
@@ -31,47 +38,66 @@
*/
public class PowerGroup {
private static final String TAG = PowerGroup.class.getSimpleName();
+ private static final boolean DEBUG = false;
private final DisplayPowerRequest mDisplayPowerRequest;
+ private final PowerGroupListener mWakefulnessListener;
private final boolean mSupportsSandman;
private final int mGroupId;
-
- // True if DisplayManagerService has applied all the latest display states that were requested
- // for this group
+ /** True if DisplayManagerService has applied all the latest display states that were requested
+ * for this group. */
private boolean mReady;
- // True if this group is in the process of powering on
+ /** True if this group is in the process of powering on */
private boolean mPoweringOn;
- // True if this group is about to dream
+ /** True if this group is about to dream */
private boolean mIsSandmanSummoned;
private int mUserActivitySummary;
- // The current wakefulness of this group
+ /** The current wakefulness of this group */
private int mWakefulness;
private int mWakeLockSummary;
private long mLastPowerOnTime;
private long mLastUserActivityTime;
private long mLastUserActivityTimeNoChangeLights;
+ /** Timestamp (milliseconds since boot) of the last time the power group was awoken.*/
+ private long mLastWakeTime;
+ /** Timestamp (milliseconds since boot) of the last time the power group was put to sleep. */
+ private long mLastSleepTime;
- PowerGroup(int groupId, DisplayPowerRequest displayPowerRequest, int wakefulness, boolean ready,
- boolean supportsSandman) {
- this.mGroupId = groupId;
- this.mDisplayPowerRequest = displayPowerRequest;
- this.mWakefulness = wakefulness;
- this.mReady = ready;
- this.mSupportsSandman = supportsSandman;
+ PowerGroup(int groupId, PowerGroupListener wakefulnessListener,
+ DisplayPowerRequest displayPowerRequest, int wakefulness, boolean ready,
+ boolean supportsSandman, long eventTime) {
+ mGroupId = groupId;
+ mWakefulnessListener = wakefulnessListener;
+ mDisplayPowerRequest = displayPowerRequest;
+ mWakefulness = wakefulness;
+ mReady = ready;
+ mSupportsSandman = supportsSandman;
+ mLastWakeTime = eventTime;
+ mLastSleepTime = eventTime;
}
- PowerGroup() {
- this.mGroupId = Display.DEFAULT_DISPLAY_GROUP;
- this.mDisplayPowerRequest = new DisplayPowerRequest();
- this.mWakefulness = WAKEFULNESS_AWAKE;
- this.mReady = false;
- this.mSupportsSandman = true;
- }
+ PowerGroup(int wakefulness, PowerGroupListener wakefulnessListener, long eventTime) {
+ mGroupId = Display.DEFAULT_DISPLAY_GROUP;
+ mWakefulnessListener = wakefulnessListener;
+ mDisplayPowerRequest = new DisplayPowerRequest();
+ mWakefulness = wakefulness;
+ mReady = false;
+ mSupportsSandman = true;
+ mLastWakeTime = eventTime;
+ mLastSleepTime = eventTime; }
DisplayPowerRequest getDisplayPowerRequestLocked() {
return mDisplayPowerRequest;
}
+ long getLastWakeTimeLocked() {
+ return mLastWakeTime;
+ }
+
+ long getLastSleepTimeLocked() {
+ return mLastSleepTime;
+ }
+
int getWakefulnessLocked() {
return mWakefulness;
}
@@ -85,9 +111,19 @@
*
* @return {@code true} if the wakefulness value was changed; {@code false} otherwise.
*/
- boolean setWakefulnessLocked(int newWakefulness) {
+ boolean setWakefulnessLocked(int newWakefulness, long eventTime, int uid, int reason, int opUid,
+ String opPackageName, String details) {
if (mWakefulness != newWakefulness) {
+ if (newWakefulness == WAKEFULNESS_AWAKE) {
+ setLastPowerOnTimeLocked(eventTime);
+ setIsPoweringOnLocked(true);
+ mLastWakeTime = eventTime;
+ } else if (isInteractive(mWakefulness) && !isInteractive(newWakefulness)) {
+ mLastSleepTime = eventTime;
+ }
mWakefulness = newWakefulness;
+ mWakefulnessListener.onWakefulnessChangedLocked(mGroupId, mWakefulness, eventTime,
+ reason, uid, opUid, opPackageName, details);
return true;
}
return false;
@@ -105,8 +141,9 @@
* Sets whether the displays of this group are all ready.
*
* <p>A display is ready if its reported
- * {@link DisplayManagerInternal.DisplayPowerCallbacks#onStateChanged() actual state} matches
- * its {@link DisplayManagerInternal#requestPowerState requested state}.
+ * {@link android.hardware.display.DisplayManagerInternal.DisplayPowerCallbacks#onStateChanged()
+ * actual state} matches its
+ * {@link android.hardware.display.DisplayManagerInternal#requestPowerState requested state}.
*
* @param isReady {@code true} if every display in the group is ready; otherwise {@code false}.
* @return {@code true} if the ready state changed; otherwise {@code false}.
@@ -148,6 +185,62 @@
mIsSandmanSummoned = isSandmanSummoned;
}
+ boolean dreamLocked(long eventTime, int uid) {
+ if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE) {
+ return false;
+ }
+
+ Trace.traceBegin(Trace.TRACE_TAG_POWER, "dreamPowerGroup" + getGroupId());
+ try {
+ Slog.i(TAG, "Napping power group (groupId=" + getGroupId() + ", uid=" + uid + ")...");
+ setSandmanSummonedLocked(true);
+ setWakefulnessLocked(WAKEFULNESS_DREAMING, eventTime, uid, /* reason= */0,
+ /* opUid= */ 0, /* opPackageName= */ null, /* details= */ null);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_POWER);
+ }
+ return true;
+ }
+
+ boolean dozeLocked(long eventTime, int uid, int reason) {
+ if (eventTime < getLastWakeTimeLocked() || !isInteractive(mWakefulness)) {
+ return false;
+ }
+
+ Trace.traceBegin(Trace.TRACE_TAG_POWER, "powerOffDisplay");
+ try {
+ reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX,
+ Math.max(reason, PowerManager.GO_TO_SLEEP_REASON_MIN));
+ Slog.i(TAG, "Powering off display group due to "
+ + PowerManager.sleepReasonToString(reason) + " (groupId= " + getGroupId()
+ + ", uid= " + uid + ")...");
+
+ setSandmanSummonedLocked(/* isSandmanSummoned= */ true);
+ setWakefulnessLocked(WAKEFULNESS_DOZING, eventTime, uid, reason, /* opUid= */ 0,
+ /* opPackageName= */ null, /* details= */ null);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_POWER);
+ }
+ return true;
+ }
+
+ boolean sleepLocked(long eventTime, int uid, int reason) {
+ if (eventTime < mLastWakeTime || getWakefulnessLocked() == WAKEFULNESS_ASLEEP) {
+ return false;
+ }
+
+ Trace.traceBegin(Trace.TRACE_TAG_POWER, "sleepPowerGroup");
+ try {
+ Slog.i(TAG, "Sleeping power group (groupId=" + getGroupId() + ", uid=" + uid + ")...");
+ setSandmanSummonedLocked(/* isSandmanSummoned= */ true);
+ setWakefulnessLocked(WAKEFULNESS_ASLEEP, eventTime, uid, reason, /* opUid= */0,
+ /* opPackageName= */ null, /* details= */ null);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_POWER);
+ }
+ return true;
+ }
+
long getLastUserActivityTimeLocked() {
return mLastUserActivityTime;
}
@@ -187,4 +280,22 @@
public boolean supportsSandmanLocked() {
return mSupportsSandman;
}
+
+ protected interface PowerGroupListener {
+ /**
+ * Informs the recipient about a wakefulness change of a {@link PowerGroup}.
+ *
+ * @param groupId The PowerGroup's id for which the wakefulness has changed.
+ * @param wakefulness The new wakefulness.
+ * @param eventTime The time of the event.
+ * @param reason The reason, any of {@link android.os.PowerManager.WakeReason} or
+ * {@link android.os.PowerManager.GoToSleepReason}.
+ * @param uid The uid which caused the wakefulness change.
+ * @param opUid The uid used for AppOps.
+ * @param opPackageName The Package name used for AppOps.
+ * @param details Details about the event.
+ */
+ void onWakefulnessChangedLocked(int groupId, int wakefulness, long eventTime, int reason,
+ int uid, int opUid, String opPackageName, String details);
+ }
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index abfa016..4185b2d9 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -29,6 +29,7 @@
import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
+import static android.os.PowerManagerInternal.isInteractive;
import static android.os.PowerManagerInternal.wakefulnessToString;
import static com.android.internal.util.LatencyTracker.ACTION_TURN_ON_SCREEN;
@@ -338,12 +339,12 @@
private boolean mRequestWaitForNegativeProximity;
// Timestamp of the last time the device was awoken or put to sleep.
- private long mLastWakeTime;
- private long mLastSleepTime;
+ private long mLastGlobalWakeTime;
+ private long mLastGlobalSleepTime;
// Last reason the device went to sleep.
- private @WakeReason int mLastWakeReason;
- private int mLastSleepReason;
+ private @WakeReason int mLastGlobalWakeReason;
+ private int mLastGlobalSleepReason;
// Timestamp of last time power boost interaction was sent.
private long mLastInteractivePowerHintTime;
@@ -352,6 +353,8 @@
private long mLastScreenBrightnessBoostTime;
private boolean mScreenBrightnessBoostInProgress;
+ private final PowerGroupWakefulnessChangeListener mPowerGroupWakefulnessChangeListener;
+
// The suspend blocker used to keep the CPU alive while the device is booting.
private final SuspendBlocker mBootingSuspendBlocker;
@@ -397,6 +400,10 @@
// The current battery level percentage.
private int mBatteryLevel;
+ // True if updatePowerStateLocked() is already in progress.
+ // TODO(b/215518989): Remove this once transactions are in place
+ private boolean mUpdatePowerStateInProgress;
+
/**
* The lock that should be held when interacting with {@link #mEnhancedDischargeTimeElapsed},
* {@link #mLastEnhancedDischargeTimeUpdatedElapsed}, and
@@ -640,6 +647,23 @@
// but the DreamService has not yet been told to start (it's an async process).
private boolean mDozeStartInProgress;
+ private final class PowerGroupWakefulnessChangeListener implements
+ PowerGroup.PowerGroupListener {
+ @GuardedBy("mLock")
+ @Override
+ public void onWakefulnessChangedLocked(int groupId, int wakefulness, long eventTime,
+ int reason, int uid, int opUid, String opPackageName, String details) {
+ if (wakefulness == WAKEFULNESS_AWAKE) {
+ // Kick user activity to prevent newly awake group from timing out instantly.
+ userActivityNoUpdateLocked(mPowerGroups.get(groupId), eventTime,
+ PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, uid);
+ }
+ mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS;
+ updateGlobalWakefulnessLocked(eventTime, reason, uid, opUid, opPackageName, details);
+ updatePowerStateLocked();
+ }
+ }
+
private final class DisplayGroupPowerChangeListener implements
DisplayManagerInternal.DisplayGroupListener {
@@ -658,10 +682,12 @@
final boolean supportsSandman = groupId == Display.DEFAULT_DISPLAY_GROUP;
final PowerGroup powerGroup = new PowerGroup(
groupId,
+ mPowerGroupWakefulnessChangeListener,
new DisplayPowerRequest(),
- getGlobalWakefulnessLocked(),
+ WAKEFULNESS_AWAKE,
/* ready= */ false,
- supportsSandman);
+ supportsSandman,
+ mClock.uptimeMillis());
mPowerGroups.append(groupId, powerGroup);
onPowerGroupEventLocked(DISPLAY_GROUP_ADDED, powerGroup);
}
@@ -992,6 +1018,8 @@
mInattentiveSleepWarningOverlayController =
mInjector.createInattentiveSleepWarningController();
+ mPowerGroupWakefulnessChangeListener = new PowerGroupWakefulnessChangeListener();
+
// Save brightness values:
// Get float values from config.
// Store float if valid
@@ -1144,10 +1172,10 @@
updatePowerStateLocked();
if (sQuiescent) {
- sleepDisplayGroupNoUpdateLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP),
+ sleepPowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP),
mClock.uptimeMillis(),
PowerManager.GO_TO_SLEEP_REASON_QUIESCENT,
- PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, Process.SYSTEM_UID);
+ Process.SYSTEM_UID);
}
mContext.getSystemService(DeviceStateManager.class).registerCallback(
@@ -1164,7 +1192,9 @@
mPolicy = getLocalService(WindowManagerPolicy.class);
mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);
mAttentionDetector.systemReady(mContext);
- mPowerGroups.append(Display.DEFAULT_DISPLAY_GROUP, new PowerGroup());
+ mPowerGroups.append(Display.DEFAULT_DISPLAY_GROUP,
+ new PowerGroup(WAKEFULNESS_AWAKE, mPowerGroupWakefulnessChangeListener,
+ mClock.uptimeMillis()));
DisplayGroupPowerChangeListener displayGroupPowerChangeListener =
new DisplayGroupPowerChangeListener();
mDisplayManagerInternal.registerDisplayGroupListener(displayGroupPowerChangeListener);
@@ -1503,7 +1533,7 @@
opUid = wakeLock.mOwnerUid;
}
for (int idx = 0; idx < mPowerGroups.size(); idx++) {
- wakeDisplayGroupNoUpdateLocked(mPowerGroups.valueAt(idx), mClock.uptimeMillis(),
+ wakePowerGroupLocked(mPowerGroups.valueAt(idx), mClock.uptimeMillis(),
PowerManager.WAKE_REASON_APPLICATION, wakeLock.mTag, opUid, opPackageName,
opUid);
}
@@ -1777,13 +1807,15 @@
@GuardedBy("mLock")
private boolean userActivityNoUpdateLocked(final PowerGroup powerGroup, long eventTime,
int event, int flags, int uid) {
+ final int groupId = powerGroup.getGroupId();
if (DEBUG_SPEW) {
- Slog.d(TAG, "userActivityNoUpdateLocked: groupId=" + powerGroup.getGroupId()
+ Slog.d(TAG, "userActivityNoUpdateLocked: groupId=" + groupId
+ ", eventTime=" + eventTime + ", event=" + event
+ ", flags=0x" + Integer.toHexString(flags) + ", uid=" + uid);
}
- if (eventTime < mLastSleepTime || eventTime < mLastWakeTime || !mSystemReady) {
+ if (eventTime < powerGroup.getLastSleepTimeLocked()
+ || eventTime < powerGroup.getLastWakeTimeLocked() || !mSystemReady) {
return false;
}
@@ -1801,7 +1833,6 @@
mUserInactiveOverrideFromWindowManager = false;
mOverriddenTimeout = -1;
}
-
final int wakefulness = powerGroup.getWakefulnessLocked();
if (wakefulness == WAKEFULNESS_ASLEEP
|| wakefulness == WAKEFULNESS_DOZING
@@ -1846,42 +1877,33 @@
}
}
- private void wakeDisplayGroup(int groupId, long eventTime, @WakeReason int reason,
- String details, int uid, String opPackageName, int opUid) {
- synchronized (mLock) {
- if (wakeDisplayGroupNoUpdateLocked(mPowerGroups.get(groupId), eventTime, reason,
- details, uid, opPackageName, opUid)) {
- updatePowerStateLocked();
- }
- }
- }
-
@GuardedBy("mLock")
- private boolean wakeDisplayGroupNoUpdateLocked(final PowerGroup powerGroup, long eventTime,
+ private void wakePowerGroupLocked(final PowerGroup powerGroup, long eventTime,
@WakeReason int reason, String details, int uid, String opPackageName, int opUid) {
final int groupId = powerGroup.getGroupId();
if (DEBUG_SPEW) {
- Slog.d(TAG, "wakeDisplayGroupNoUpdateLocked: eventTime=" + eventTime
+ Slog.d(TAG, "wakePowerGroupLocked: eventTime=" + eventTime
+ ", groupId=" + groupId + ", uid=" + uid);
}
- if (eventTime < mLastSleepTime || mForceSuspendActive || !mSystemReady) {
- return false;
+ if (eventTime < powerGroup.getLastSleepTimeLocked() || mForceSuspendActive
+ || !mSystemReady) {
+ return;
}
- final int currentState = powerGroup.getWakefulnessLocked();
- if (currentState == WAKEFULNESS_AWAKE) {
+ final int currentWakefulness = powerGroup.getWakefulnessLocked();
+ if (currentWakefulness == WAKEFULNESS_AWAKE) {
if (!mBootCompleted && sQuiescent) {
mDirty |= DIRTY_QUIESCENT;
- return true;
+ updatePowerStateLocked();
}
- return false;
+ return;
}
Trace.traceBegin(Trace.TRACE_TAG_POWER, "powerOnDisplay");
try {
- Slog.i(TAG, "Powering on display group from"
- + PowerManagerInternal.wakefulnessToString(currentState)
+ Slog.i(TAG, "Waking up power group from "
+ + PowerManagerInternal.wakefulnessToString(currentWakefulness)
+ " (groupId=" + groupId
+ ", uid=" + uid
+ ", reason=" + PowerManager.wakeReasonToString(reason)
@@ -1892,183 +1914,96 @@
LatencyTracker.getInstance(mContext)
.onActionStart(ACTION_TURN_ON_SCREEN, String.valueOf(groupId));
- setWakefulnessLocked(powerGroup, WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid,
+ powerGroup.setWakefulnessLocked(WAKEFULNESS_AWAKE, eventTime, uid, reason, opUid,
opPackageName, details);
- powerGroup.setLastPowerOnTimeLocked(eventTime);
- powerGroup.setIsPoweringOnLocked(true);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
-
- return true;
- }
-
- private void sleepDisplayGroup(int groupId, long eventTime, int reason, int flags,
- int uid) {
- synchronized (mLock) {
- if (sleepDisplayGroupNoUpdateLocked(mPowerGroups.get(groupId), eventTime, reason, flags,
- uid)) {
- updatePowerStateLocked();
- }
- }
}
@GuardedBy("mLock")
- private boolean sleepDisplayGroupNoUpdateLocked(final PowerGroup powerGroup, long eventTime,
- int reason, int flags, int uid) {
+ private boolean dreamPowerGroupLocked(PowerGroup powerGroup, long eventTime, int uid) {
+ if (DEBUG_SPEW) {
+ Slog.d(TAG, "dreamPowerGroup: groupId=" + powerGroup.getGroupId() + ", eventTime="
+ + eventTime + ", uid=" + uid);
+ }
+ if (!mBootCompleted || !mSystemReady) {
+ return false;
+ }
+ return powerGroup.dreamLocked(eventTime, uid);
+ }
+
+ @GuardedBy("mLock")
+ private boolean dozePowerGroupLocked(final PowerGroup powerGroup, long eventTime,
+ int reason, int uid) {
if (DEBUG_SPEW) {
Slog.d(TAG, "sleepDisplayGroupNoUpdateLocked: eventTime=" + eventTime
+ ", groupId=" + powerGroup.getGroupId() + ", reason=" + reason
- + ", flags=" + flags + ", uid=" + uid);
+ + ", uid=" + uid);
}
- if (eventTime < mLastWakeTime
- || !PowerManagerInternal.isInteractive(getWakefulnessLocked())
- || !mSystemReady
- || !mBootCompleted) {
+ if (!mSystemReady || !mBootCompleted) {
return false;
}
- final int wakefulness = powerGroup.getWakefulnessLocked();
- if (!PowerManagerInternal.isInteractive(wakefulness)) {
- return false;
- }
-
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "powerOffDisplay");
- try {
- reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX,
- Math.max(reason, PowerManager.GO_TO_SLEEP_REASON_MIN));
- Slog.i(TAG, "Powering off display group due to "
- + PowerManager.sleepReasonToString(reason)
- + " (groupId= " + powerGroup.getGroupId() + ", uid= " + uid + ")...");
-
- powerGroup.setSandmanSummonedLocked(/* isSandmanSummoned= */ true);
- setWakefulnessLocked(powerGroup, WAKEFULNESS_DOZING, eventTime, uid, reason,
- /* opUid= */ 0, /* opPackageName= */ null, /* details= */ null);
- if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {
- reallySleepDisplayGroupNoUpdateLocked(powerGroup, eventTime, uid);
- }
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- return true;
- }
-
- private void dreamDisplayGroup(int groupId, long eventTime, int uid) {
- synchronized (mLock) {
- if (dreamDisplayGroupNoUpdateLocked(mPowerGroups.get(groupId), eventTime, uid)) {
- updatePowerStateLocked();
- }
- }
+ return powerGroup.dozeLocked(eventTime, uid, reason);
}
@GuardedBy("mLock")
- private boolean dreamDisplayGroupNoUpdateLocked(final PowerGroup powerGroup, long eventTime,
+ private boolean sleepPowerGroupLocked(final PowerGroup powerGroup, long eventTime, int reason,
int uid) {
if (DEBUG_SPEW) {
- Slog.d(TAG, "dreamDisplayGroupNoUpdateLocked: eventTime=" + eventTime
- + ", uid=" + uid);
+ Slog.d(TAG, "sleepPowerGroup: eventTime=" + eventTime + ", uid=" + uid);
}
-
- if (eventTime < mLastWakeTime || getWakefulnessLocked() != WAKEFULNESS_AWAKE
- || !mBootCompleted || !mSystemReady) {
+ if (!mBootCompleted || !mSystemReady) {
return false;
}
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "napDisplayGroup");
- try {
- Slog.i(TAG, "Napping display group (groupId=" + powerGroup.getGroupId() + ", uid=" + uid
- + ")...");
-
- powerGroup.setSandmanSummonedLocked(/* isSandmanSummoned= */ true);
- setWakefulnessLocked(powerGroup, WAKEFULNESS_DREAMING, eventTime, uid,
- /* reason= */0, /* opUid= */ 0, /* opPackageName= */ null, /* details= */ null);
-
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- return true;
- }
-
- @GuardedBy("mLock")
- private boolean reallySleepDisplayGroupNoUpdateLocked(final PowerGroup powerGroup,
- long eventTime, int uid) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "reallySleepDisplayGroupNoUpdateLocked: eventTime=" + eventTime
- + ", uid=" + uid);
- }
-
- if (eventTime < mLastWakeTime || getWakefulnessLocked() == WAKEFULNESS_ASLEEP
- || !mBootCompleted || !mSystemReady
- || powerGroup.getWakefulnessLocked()
- == WAKEFULNESS_ASLEEP) {
- return false;
- }
-
- Trace.traceBegin(Trace.TRACE_TAG_POWER, "reallySleepDisplayGroup");
- try {
- Slog.i(TAG,
- "Sleeping display group (groupId=" + powerGroup.getGroupId() + ", uid=" + uid
- + ")...");
-
- setWakefulnessLocked(powerGroup, WAKEFULNESS_ASLEEP, eventTime, uid,
- PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, /* opUid= */ 0,
- /* opPackageName= */ null, /* details= */ null);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_POWER);
- }
- return true;
+ return powerGroup.sleepLocked(eventTime, uid, reason);
}
@VisibleForTesting
@GuardedBy("mLock")
void setWakefulnessLocked(int groupId, int wakefulness, long eventTime, int uid, int reason,
int opUid, String opPackageName, String details) {
- setWakefulnessLocked(mPowerGroups.get(groupId), wakefulness, eventTime, uid, reason, opUid,
+ mPowerGroups.get(groupId).setWakefulnessLocked(wakefulness, eventTime, uid, reason, opUid,
opPackageName, details);
}
- @GuardedBy("mLock")
- private void setWakefulnessLocked(final PowerGroup powerGroup, int wakefulness, long eventTime,
- int uid, int reason, int opUid, String opPackageName, String details) {
- if (powerGroup.setWakefulnessLocked(wakefulness)) {
- mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS;
- setGlobalWakefulnessLocked(getGlobalWakefulnessLocked(),
- eventTime, reason, uid, opUid, opPackageName, details);
- if (wakefulness == WAKEFULNESS_AWAKE) {
- // Kick user activity to prevent newly awake group from timing out instantly.
- userActivityNoUpdateLocked(powerGroup, eventTime,
- PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, uid);
- }
- }
- }
-
@SuppressWarnings("deprecation")
@GuardedBy("mLock")
- private void setGlobalWakefulnessLocked(int wakefulness, long eventTime, int reason, int uid,
+ private void updateGlobalWakefulnessLocked(long eventTime, int reason, int uid,
int opUid, String opPackageName, String details) {
- if (getWakefulnessLocked() == wakefulness) {
+ int newWakefulness = recalculateGlobalWakefulnessLocked();
+ int currentWakefulness = getGlobalWakefulnessLocked();
+ if (currentWakefulness == newWakefulness) {
return;
}
// Phase 1: Handle pre-wakefulness change bookkeeping.
final String traceMethodName;
- switch (wakefulness) {
+ switch (newWakefulness) {
case WAKEFULNESS_ASLEEP:
traceMethodName = "reallyGoToSleep";
Slog.i(TAG, "Sleeping (uid " + uid + ")...");
+ // TODO(b/215518989): Remove this once transactions are in place
+ if (currentWakefulness != WAKEFULNESS_DOZING) {
+ // in case we are going to sleep without dozing before
+ mLastGlobalSleepTime = eventTime;
+ mLastGlobalSleepReason = reason;
+ }
break;
case WAKEFULNESS_AWAKE:
traceMethodName = "wakeUp";
Slog.i(TAG, "Waking up from "
- + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())
+ + PowerManagerInternal.wakefulnessToString(currentWakefulness)
+ " (uid=" + uid
+ ", reason=" + PowerManager.wakeReasonToString(reason)
+ ", details=" + details
+ ")...");
- mLastWakeTime = eventTime;
- mLastWakeReason = reason;
+ mLastGlobalWakeTime = eventTime;
+ mLastGlobalWakeReason = reason;
break;
case WAKEFULNESS_DREAMING:
@@ -2081,13 +2016,13 @@
Slog.i(TAG, "Going to sleep due to " + PowerManager.sleepReasonToString(reason)
+ " (uid " + uid + ")...");
- mLastSleepTime = eventTime;
- mLastSleepReason = reason;
+ mLastGlobalSleepTime = eventTime;
+ mLastGlobalSleepReason = reason;
mDozeStartInProgress = true;
break;
default:
- throw new IllegalArgumentException("Unexpected wakefulness: " + wakefulness);
+ throw new IllegalArgumentException("Unexpected wakefulness: " + newWakefulness);
}
Trace.traceBegin(Trace.TRACE_TAG_POWER, traceMethodName);
@@ -2095,20 +2030,20 @@
// Phase 2: Handle wakefulness change and bookkeeping.
// Under lock, invalidate before set ensures caches won't return stale values.
mInjector.invalidateIsInteractiveCaches();
- mWakefulnessRaw = wakefulness;
+ mWakefulnessRaw = newWakefulness;
mWakefulnessChanging = true;
mDirty |= DIRTY_WAKEFULNESS;
// This is only valid while we are in wakefulness dozing. Set to false otherwise.
- mDozeStartInProgress &= (getWakefulnessLocked() == WAKEFULNESS_DOZING);
+ mDozeStartInProgress &= (newWakefulness == WAKEFULNESS_DOZING);
if (mNotifier != null) {
- mNotifier.onWakefulnessChangeStarted(wakefulness, reason, eventTime);
+ mNotifier.onWakefulnessChangeStarted(newWakefulness, reason, eventTime);
}
- mAttentionDetector.onWakefulnessChangeStarted(wakefulness);
+ mAttentionDetector.onWakefulnessChangeStarted(newWakefulness);
// Phase 3: Handle post-wakefulness change bookkeeping.
- switch (wakefulness) {
+ switch (newWakefulness) {
case WAKEFULNESS_AWAKE:
mNotifier.onWakeUp(reason, details, uid, opPackageName, opUid);
if (sQuiescent) {
@@ -2116,7 +2051,13 @@
}
break;
+ case WAKEFULNESS_ASLEEP:
+ // fallthrough
case WAKEFULNESS_DOZING:
+ if (!isInteractive(currentWakefulness)) {
+ // TODO(b/215518989): remove this once transactions are in place
+ break;
+ }
// Report the number of wake locks that will be cleared by going to sleep.
int numWakeLocksCleared = 0;
final int numWakeLocks = mWakeLocks.size();
@@ -2140,7 +2081,7 @@
@VisibleForTesting
@GuardedBy("mLock")
- int getWakefulnessLocked() {
+ int getGlobalWakefulnessLocked() {
return mWakefulnessRaw;
}
@@ -2163,10 +2104,9 @@
* </ol>
*/
@GuardedBy("mLock")
- int getGlobalWakefulnessLocked() {
- final int size = mPowerGroups.size();
+ int recalculateGlobalWakefulnessLocked() {
int deviceWakefulness = WAKEFULNESS_ASLEEP;
- for (int i = 0; i < size; i++) {
+ for (int i = 0; i < mPowerGroups.size(); i++) {
final int wakefulness = mPowerGroups.valueAt(i).getWakefulnessLocked();
if (wakefulness == WAKEFULNESS_AWAKE) {
return WAKEFULNESS_AWAKE;
@@ -2187,10 +2127,10 @@
void onPowerGroupEventLocked(int event, PowerGroup powerGroup) {
final int groupId = powerGroup.getGroupId();
if (event == DisplayGroupPowerChangeListener.DISPLAY_GROUP_REMOVED) {
- mPowerGroups.remove(groupId);
+ mPowerGroups.delete(groupId);
}
- final int oldWakefulness = getWakefulnessLocked();
- final int newWakefulness = getGlobalWakefulnessLocked();
+ final int oldWakefulness = getGlobalWakefulnessLocked();
+ final int newWakefulness = recalculateGlobalWakefulnessLocked();
if (event == DisplayGroupPowerChangeListener.DISPLAY_GROUP_ADDED
&& newWakefulness == WAKEFULNESS_AWAKE) {
@@ -2215,13 +2155,9 @@
default:
reason = 0;
}
-
- setGlobalWakefulnessLocked(
- getGlobalWakefulnessLocked(),
- mClock.uptimeMillis(), reason, Process.SYSTEM_UID, Process.SYSTEM_UID,
- mContext.getOpPackageName(), "groupId: " + groupId);
+ updateGlobalWakefulnessLocked(mClock.uptimeMillis(), reason, Process.SYSTEM_UID,
+ Process.SYSTEM_UID, mContext.getOpPackageName(), "groupId: " + groupId);
}
-
mDirty |= DIRTY_DISPLAY_GROUP_WAKEFULNESS;
updatePowerStateLocked();
}
@@ -2243,15 +2179,15 @@
@GuardedBy("mLock")
private void finishWakefulnessChangeIfNeededLocked() {
if (mWakefulnessChanging && areAllDisplaysReadyLocked()) {
- if (getWakefulnessLocked() == WAKEFULNESS_DOZING
+ if (getGlobalWakefulnessLocked() == WAKEFULNESS_DOZING
&& (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
return; // wait until dream has enabled dozing
} else {
// Doze wakelock acquired (doze started) or device is no longer dozing.
mDozeStartInProgress = false;
}
- if (getWakefulnessLocked() == WAKEFULNESS_DOZING
- || getWakefulnessLocked() == WAKEFULNESS_ASLEEP) {
+ if (getGlobalWakefulnessLocked() == WAKEFULNESS_DOZING
+ || getGlobalWakefulnessLocked() == WAKEFULNESS_ASLEEP) {
logSleepTimeoutRecapturedLocked();
}
mWakefulnessChanging = false;
@@ -2282,7 +2218,7 @@
*/
@GuardedBy("mLock")
private void updatePowerStateLocked() {
- if (!mSystemReady || mDirty == 0) {
+ if (!mSystemReady || mDirty == 0 || mUpdatePowerStateInProgress) {
return;
}
if (!Thread.holdsLock(mLock)) {
@@ -2290,6 +2226,7 @@
}
Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState");
+ mUpdatePowerStateInProgress = true;
try {
// Phase 0: Basic state updates.
updateIsPoweredLocked(mDirty);
@@ -2332,6 +2269,7 @@
updateSuspendBlockerLocked();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
+ mUpdatePowerStateInProgress = false;
}
}
@@ -2397,7 +2335,7 @@
final long now = mClock.uptimeMillis();
if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType,
dockedOnWirelessCharger)) {
- wakeDisplayGroupNoUpdateLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP),
+ wakePowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP),
now, PowerManager.WAKE_REASON_PLUGGED_IN,
"android.server.power:PLUGGED:" + mIsPowered, Process.SYSTEM_UID,
mContext.getOpPackageName(), Process.SYSTEM_UID);
@@ -2446,7 +2384,7 @@
}
// If already dreaming and becoming powered, then don't wake.
- if (mIsPowered && getWakefulnessLocked() == WAKEFULNESS_DREAMING) {
+ if (mIsPowered && getGlobalWakefulnessLocked() == WAKEFULNESS_DREAMING) {
return false;
}
@@ -2456,7 +2394,7 @@
}
// On Always On Display, SystemUI shows the charging indicator
- if (mAlwaysOnEnabled && getWakefulnessLocked() == WAKEFULNESS_DOZING) {
+ if (mAlwaysOnEnabled && getGlobalWakefulnessLocked() == WAKEFULNESS_DOZING) {
return false;
}
@@ -2540,24 +2478,23 @@
for (int idx = 0; idx < mPowerGroups.size(); idx++) {
final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
- final int wakeLockSummary = adjustWakeLockSummary(
- powerGroup.getWakefulnessLocked(),
+ final int wakeLockSummary = adjustWakeLockSummary(powerGroup.getWakefulnessLocked(),
invalidGroupWakeLockSummary | powerGroup.getWakeLockSummaryLocked());
powerGroup.setWakeLockSummaryLocked(wakeLockSummary);
}
- mWakeLockSummary = adjustWakeLockSummary(getWakefulnessLocked(),
+ mWakeLockSummary = adjustWakeLockSummary(getGlobalWakefulnessLocked(),
mWakeLockSummary);
for (int i = 0; i < numProfiles; i++) {
final ProfilePowerState profile = mProfilePowerState.valueAt(i);
- profile.mWakeLockSummary = adjustWakeLockSummary(getWakefulnessLocked(),
+ profile.mWakeLockSummary = adjustWakeLockSummary(getGlobalWakefulnessLocked(),
profile.mWakeLockSummary);
}
if (DEBUG_SPEW) {
Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
- + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())
+ + PowerManagerInternal.wakefulnessToString(getGlobalWakefulnessLocked())
+ ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
}
}
@@ -2706,11 +2643,12 @@
int groupUserActivitySummary = 0;
long groupNextTimeout = 0;
final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
- if (powerGroup.getWakefulnessLocked() != WAKEFULNESS_ASLEEP) {
+ final int wakefulness = powerGroup.getWakefulnessLocked();
+ if (wakefulness != WAKEFULNESS_ASLEEP) {
final long lastUserActivityTime = powerGroup.getLastUserActivityTimeLocked();
final long lastUserActivityTimeNoChangeLights =
powerGroup.getLastUserActivityTimeNoChangeLightsLocked();
- if (lastUserActivityTime >= mLastWakeTime) {
+ if (lastUserActivityTime >= powerGroup.getLastWakeTimeLocked()) {
groupNextTimeout = lastUserActivityTime + screenOffTimeout - screenDimDuration;
if (now < groupNextTimeout) {
groupUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
@@ -2721,8 +2659,8 @@
}
}
}
- if (groupUserActivitySummary == 0
- && lastUserActivityTimeNoChangeLights >= mLastWakeTime) {
+ if (groupUserActivitySummary == 0 && lastUserActivityTimeNoChangeLights
+ >= powerGroup.getLastWakeTimeLocked()) {
groupNextTimeout = lastUserActivityTimeNoChangeLights + screenOffTimeout;
if (now < groupNextTimeout) {
final DisplayPowerRequest displayPowerRequest =
@@ -2740,7 +2678,7 @@
if (sleepTimeout >= 0) {
final long anyUserActivity = Math.max(lastUserActivityTime,
lastUserActivityTimeNoChangeLights);
- if (anyUserActivity >= mLastWakeTime) {
+ if (anyUserActivity >= powerGroup.getLastWakeTimeLocked()) {
groupNextTimeout = anyUserActivity + sleepTimeout;
if (now < groupNextTimeout) {
groupUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
@@ -2786,7 +2724,7 @@
if (DEBUG_SPEW) {
Slog.d(TAG, "updateUserActivitySummaryLocked: groupId=" + powerGroup.getGroupId()
- + ", mWakefulness=" + wakefulnessToString(powerGroup.getWakefulnessLocked())
+ + ", mWakefulness=" + wakefulnessToString(wakefulness)
+ ", mUserActivitySummary=0x" + Integer.toHexString(
groupUserActivitySummary)
+ ", nextTimeout=" + TimeUtils.formatUptime(groupNextTimeout));
@@ -2884,7 +2822,7 @@
return false;
}
- if (getWakefulnessLocked() != WAKEFULNESS_AWAKE) {
+ if (getGlobalWakefulnessLocked() != WAKEFULNESS_AWAKE) {
mInattentiveSleepWarningOverlayController.dismiss(false);
return true;
} else if (attentiveTimeout < 0 || isBeingKeptFromInattentiveSleepLocked()
@@ -3024,14 +2962,13 @@
if (DEBUG) {
Slog.i(TAG, "Going to sleep now due to long user inactivity");
}
- changed = sleepDisplayGroupNoUpdateLocked(powerGroup, time,
- PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE,
- PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, Process.SYSTEM_UID);
+ changed = sleepPowerGroupLocked(powerGroup, time,
+ PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, Process.SYSTEM_UID);
} else if (shouldNapAtBedTimeLocked()) {
- changed = dreamDisplayGroupNoUpdateLocked(powerGroup, time, Process.SYSTEM_UID);
+ changed = dreamPowerGroupLocked(powerGroup, time, Process.SYSTEM_UID);
} else {
- changed = sleepDisplayGroupNoUpdateLocked(powerGroup, time,
- PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
+ changed = dozePowerGroupLocked(powerGroup, time,
+ PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, Process.SYSTEM_UID);
}
}
return changed;
@@ -3228,25 +3165,27 @@
// Dream has ended or will be stopped. Update the power state.
if (isItBedTimeYetLocked(powerGroup)) {
- final int flags = isAttentiveTimeoutExpired(powerGroup, now)
- ? PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE : 0;
- sleepDisplayGroupNoUpdateLocked(powerGroup, now,
- PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, flags, Process.SYSTEM_UID);
+ if (isAttentiveTimeoutExpired(powerGroup, now)) {
+ sleepPowerGroupLocked(powerGroup, now,
+ PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, Process.SYSTEM_UID);
+ } else {
+ dozePowerGroupLocked(powerGroup, now,
+ PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, Process.SYSTEM_UID);
+ }
} else {
- wakeDisplayGroupNoUpdateLocked(powerGroup, now,
+ wakePowerGroupLocked(powerGroup, now,
PowerManager.WAKE_REASON_UNKNOWN,
"android.server.power:DREAM_FINISHED", Process.SYSTEM_UID,
mContext.getOpPackageName(), Process.SYSTEM_UID);
}
- updatePowerStateLocked();
} else if (wakefulness == WAKEFULNESS_DOZING) {
if (isDreaming) {
return; // continue dozing
}
// Doze has ended or will be stopped. Update the power state.
- reallySleepDisplayGroupNoUpdateLocked(powerGroup, now, Process.SYSTEM_UID);
- updatePowerStateLocked();
+ sleepPowerGroupLocked(powerGroup, now, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,
+ Process.SYSTEM_UID);
}
}
@@ -3263,7 +3202,7 @@
private boolean canDreamLocked(final PowerGroup powerGroup) {
final DisplayPowerRequest displayPowerRequest = powerGroup.getDisplayPowerRequestLocked();
if (!mBootCompleted
- || getWakefulnessLocked() != WAKEFULNESS_DREAMING
+ || getGlobalWakefulnessLocked() != WAKEFULNESS_DREAMING
|| !mDreamsSupportedConfig
|| !mDreamsEnabledSetting
|| !displayPowerRequest.isBrightOrDim()
@@ -3294,7 +3233,7 @@
@GuardedBy("mLock")
private boolean canDozeLocked() {
// TODO (b/175764708): Support per-display doze.
- return getWakefulnessLocked() == WAKEFULNESS_DOZING;
+ return getGlobalWakefulnessLocked() == WAKEFULNESS_DOZING;
}
/**
@@ -3375,15 +3314,15 @@
final boolean ready = mDisplayManagerInternal.requestPowerState(groupId,
displayPowerRequest, mRequestWaitForNegativeProximity);
- mNotifier.onScreenPolicyUpdate(groupId, displayPowerRequest.policy);
+ mNotifier.onScreenPolicyUpdate(powerGroup.getGroupId(), displayPowerRequest.policy);
+ int wakefulness = powerGroup.getWakefulnessLocked();
if (DEBUG_SPEW) {
Slog.d(TAG, "updateDisplayPowerStateLocked: displayReady=" + ready
+ ", groupId=" + groupId
+ ", policy=" + policyToString(displayPowerRequest.policy)
+ ", mWakefulness="
- + PowerManagerInternal.wakefulnessToString(
- powerGroup.getWakefulnessLocked())
+ + PowerManagerInternal.wakefulnessToString(wakefulness)
+ ", mWakeLockSummary=0x" + Integer.toHexString(
powerGroup.getWakeLockSummaryLocked())
+ ", mUserActivitySummary=0x" + Integer.toHexString(
@@ -3401,7 +3340,7 @@
final boolean displayReadyStateChanged = powerGroup.setReadyLocked(ready);
final boolean poweringOn = powerGroup.isPoweringOnLocked();
if (ready && displayReadyStateChanged && poweringOn
- && powerGroup.getWakefulnessLocked() == WAKEFULNESS_AWAKE) {
+ && wakefulness == WAKEFULNESS_AWAKE) {
powerGroup.setIsPoweringOnLocked(false);
LatencyTracker.getInstance(mContext).onActionEnd(ACTION_TURN_ON_SCREEN);
Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, groupId);
@@ -3424,7 +3363,7 @@
if (mScreenBrightnessBoostInProgress) {
final long now = mClock.uptimeMillis();
mHandler.removeMessages(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
- if (mLastScreenBrightnessBoostTime > mLastSleepTime) {
+ if (mLastScreenBrightnessBoostTime > mLastGlobalSleepTime) {
final long boostTimeout = mLastScreenBrightnessBoostTime +
SCREEN_BRIGHTNESS_BOOST_TIMEOUT;
if (boostTimeout > now) {
@@ -3656,7 +3595,7 @@
// Here we wait for mWakefulnessChanging to become false since the wakefulness
// transition to DOZING isn't considered "changed" until the doze wake lock is
// acquired.
- if (getWakefulnessLocked() == WAKEFULNESS_DOZING && mDozeStartInProgress) {
+ if (getGlobalWakefulnessLocked() == WAKEFULNESS_DOZING && mDozeStartInProgress) {
return true;
}
@@ -3721,7 +3660,7 @@
private boolean isInteractiveInternal() {
synchronized (mLock) {
- return PowerManagerInternal.isInteractive(getWakefulnessLocked());
+ return PowerManagerInternal.isInteractive(getGlobalWakefulnessLocked());
}
}
@@ -4092,7 +4031,7 @@
private void boostScreenBrightnessInternal(long eventTime, int uid) {
synchronized (mLock) {
- if (!mSystemReady || getWakefulnessLocked() == WAKEFULNESS_ASLEEP
+ if (!mSystemReady || getGlobalWakefulnessLocked() == WAKEFULNESS_ASLEEP
|| eventTime < mLastScreenBrightnessBoostTime) {
return;
}
@@ -4225,14 +4164,9 @@
synchronized (mLock) {
mForceSuspendActive = true;
// Place the system in an non-interactive state
- boolean updatePowerState = false;
for (int idx = 0; idx < mPowerGroups.size(); idx++) {
- updatePowerState |= sleepDisplayGroupNoUpdateLocked(mPowerGroups.valueAt(idx),
- mClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_FORCE_SUSPEND,
- PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE, uid);
- }
- if (updatePowerState) {
- updatePowerStateLocked();
+ sleepPowerGroupLocked(mPowerGroups.valueAt(idx), mClock.uptimeMillis(),
+ PowerManager.GO_TO_SLEEP_REASON_FORCE_SUSPEND, uid);
}
// Disable all the partial wake locks as well
@@ -4331,7 +4265,7 @@
mConstants.dump(pw);
pw.println(" mDirty=0x" + Integer.toHexString(mDirty));
pw.println(" mWakefulness="
- + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked()));
+ + PowerManagerInternal.wakefulnessToString(getGlobalWakefulnessLocked()));
pw.println(" mWakefulnessChanging=" + mWakefulnessChanging);
pw.println(" mIsPowered=" + mIsPowered);
pw.println(" mPlugType=" + mPlugType);
@@ -4382,9 +4316,10 @@
pw.println(" mDeviceIdleMode=" + mDeviceIdleMode);
pw.println(" mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
pw.println(" mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
- pw.println(" mLastWakeTime=" + TimeUtils.formatUptime(mLastWakeTime));
- pw.println(" mLastSleepTime=" + TimeUtils.formatUptime(mLastSleepTime));
- pw.println(" mLastSleepReason=" + PowerManager.sleepReasonToString(mLastSleepReason));
+ pw.println(" mLastWakeTime=" + TimeUtils.formatUptime(mLastGlobalWakeTime));
+ pw.println(" mLastSleepTime=" + TimeUtils.formatUptime(mLastGlobalSleepTime));
+ pw.println(" mLastSleepReason=" + PowerManager.sleepReasonToString(
+ mLastGlobalSleepReason));
pw.println(" mLastInteractivePowerHintTime="
+ TimeUtils.formatUptime(mLastInteractivePowerHintTime));
pw.println(" mLastScreenBrightnessBoostTime="
@@ -4565,7 +4500,7 @@
synchronized (mLock) {
mConstants.dumpProto(proto);
proto.write(PowerManagerServiceDumpProto.DIRTY, mDirty);
- proto.write(PowerManagerServiceDumpProto.WAKEFULNESS, getWakefulnessLocked());
+ proto.write(PowerManagerServiceDumpProto.WAKEFULNESS, getGlobalWakefulnessLocked());
proto.write(PowerManagerServiceDumpProto.IS_WAKEFULNESS_CHANGING, mWakefulnessChanging);
proto.write(PowerManagerServiceDumpProto.IS_POWERED, mIsPowered);
proto.write(PowerManagerServiceDumpProto.PLUG_TYPE, mPlugType);
@@ -4664,8 +4599,8 @@
proto.write(PowerManagerServiceDumpProto.DEVICE_IDLE_TEMP_WHITELIST, id);
}
- proto.write(PowerManagerServiceDumpProto.LAST_WAKE_TIME_MS, mLastWakeTime);
- proto.write(PowerManagerServiceDumpProto.LAST_SLEEP_TIME_MS, mLastSleepTime);
+ proto.write(PowerManagerServiceDumpProto.LAST_WAKE_TIME_MS, mLastGlobalWakeTime);
+ proto.write(PowerManagerServiceDumpProto.LAST_SLEEP_TIME_MS, mLastGlobalSleepTime);
proto.write(
PowerManagerServiceDumpProto.LAST_INTERACTIVE_POWER_HINT_TIME_MS,
mLastInteractivePowerHintTime);
@@ -5505,8 +5440,10 @@
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
- wakeDisplayGroup(Display.DEFAULT_DISPLAY_GROUP, eventTime, reason, details, uid,
- opPackageName, uid);
+ synchronized (mLock) {
+ wakePowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP), eventTime,
+ reason, details, uid, opPackageName, uid);
+ }
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -5524,7 +5461,14 @@
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
- sleepDisplayGroup(Display.DEFAULT_DISPLAY_GROUP, eventTime, reason, flags, uid);
+ synchronized (mLock) {
+ PowerGroup defaultPowerGroup = mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP);
+ if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {
+ sleepPowerGroupLocked(defaultPowerGroup, eventTime, reason, uid);
+ } else {
+ dozePowerGroupLocked(defaultPowerGroup, eventTime, reason, uid);
+ }
+ }
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -5542,7 +5486,10 @@
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
- dreamDisplayGroup(Display.DEFAULT_DISPLAY_GROUP, eventTime, uid);
+ synchronized (mLock) {
+ dreamPowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP),
+ eventTime, uid);
+ }
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -6181,13 +6128,15 @@
private int getLastSleepReasonInternal() {
synchronized (mLock) {
- return mLastSleepReason;
+ return mLastGlobalSleepReason;
}
}
+ @VisibleForTesting
private PowerManager.WakeData getLastWakeupInternal() {
synchronized (mLock) {
- return new WakeData(mLastWakeTime, mLastWakeReason, mLastWakeTime - mLastSleepTime);
+ return new WakeData(mLastGlobalWakeTime, mLastGlobalWakeReason,
+ mLastGlobalWakeTime - mLastGlobalSleepTime);
}
}
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index e180032..277d802 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -23,13 +23,13 @@
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-import static android.net.NetworkIdentity.OEM_PAID;
-import static android.net.NetworkIdentity.OEM_PRIVATE;
import static android.net.NetworkStats.METERED_YES;
import static android.net.NetworkTemplate.MATCH_ETHERNET;
import static android.net.NetworkTemplate.MATCH_MOBILE;
import static android.net.NetworkTemplate.MATCH_WIFI;
import static android.net.NetworkTemplate.OEM_MANAGED_ALL;
+import static android.net.NetworkTemplate.OEM_MANAGED_PAID;
+import static android.net.NetworkTemplate.OEM_MANAGED_PRIVATE;
import static android.net.NetworkTemplate.getAllCollapsedRatTypes;
import static android.os.Debug.getIonHeapsSizeKb;
import static android.os.Process.LAST_SHARED_APPLICATION_GID;
@@ -1292,7 +1292,8 @@
new Pair(MATCH_MOBILE, TRANSPORT_CELLULAR),
new Pair(MATCH_WIFI, TRANSPORT_WIFI)
);
- final int[] oemManagedTypes = new int[] {OEM_PAID | OEM_PRIVATE, OEM_PAID, OEM_PRIVATE};
+ final int[] oemManagedTypes = new int[] {OEM_MANAGED_PAID | OEM_MANAGED_PRIVATE,
+ OEM_MANAGED_PAID, OEM_MANAGED_PRIVATE};
final List<NetworkStatsExt> ret = new ArrayList<>();
@@ -1368,12 +1369,12 @@
NetworkStatsUtils.fromPublicNetworkStats(queryNonTaggedStats);
if (!includeTags) return nonTaggedStats;
- final android.app.usage.NetworkStats quaryTaggedStats =
+ final android.app.usage.NetworkStats queryTaggedStats =
mNetworkStatsManager.queryTaggedSummary(template,
currentTimeInMillis - elapsedMillisSinceBoot - bucketDuration,
currentTimeInMillis);
final NetworkStats taggedStats =
- NetworkStatsUtils.fromPublicNetworkStats(quaryTaggedStats);
+ NetworkStatsUtils.fromPublicNetworkStats(queryTaggedStats);
return nonTaggedStats.add(taggedStats);
}
@@ -1470,7 +1471,7 @@
*/
@NonNull private NetworkStats sliceNetworkStats(@NonNull NetworkStats stats,
@NonNull Function<NetworkStats.Entry, NetworkStats.Entry> slicer) {
- NetworkStats ret = new NetworkStats(stats.getElapsedRealtime(), 1);
+ NetworkStats ret = new NetworkStats(0, 1);
NetworkStats.Entry entry = new NetworkStats.Entry();
for (NetworkStats.Entry e : stats) {
if (slicer != null) {
diff --git a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
index 468612f..53a9244 100644
--- a/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
+++ b/services/core/java/com/android/server/tv/interactive/TvInteractiveAppManagerService.java
@@ -2100,7 +2100,7 @@
@Override
public void onCommandRequest(
- @TvInteractiveAppService.InteractiveAppServiceCommandType String cmdType,
+ @TvInteractiveAppService.PlaybackCommandType String cmdType,
Bundle parameters) {
synchronized (mLock) {
if (DEBUG) {
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index eafd9d7..6c5d952 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -179,7 +179,7 @@
try {
ActivityManager.getService().registerUidObserver(mUidObserver,
ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
- ActivityManager.PROCESS_STATE_UNKNOWN, mContext.getOpPackageName());
+ ActivityManager.PROCESS_STATE_UNKNOWN, null);
} catch (RemoteException e) {
// ignored; both services live in system_server
}
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index a95b6c9..b2e34da 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -16,6 +16,9 @@
package com.android.server.vibrator;
+import static android.os.VibrationEffect.VibrationParameter.targetAmplitude;
+import static android.os.VibrationEffect.VibrationParameter.targetFrequency;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -65,6 +68,7 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
@@ -1711,7 +1715,8 @@
long duration = Long.parseLong(getNextArgRequired());
int amplitude = hasAmplitude ? Integer.parseInt(getNextArgRequired())
: VibrationEffect.DEFAULT_AMPLITUDE;
- composition.addEffect(VibrationEffect.createOneShot(duration, amplitude), delay);
+ composition.addOffDuration(Duration.ofMillis(delay));
+ composition.addEffect(VibrationEffect.createOneShot(duration, amplitude));
}
private void addWaveformToComposition(VibrationEffect.Composition composition) {
@@ -1762,23 +1767,44 @@
}
}
+ // Add delay before the waveform.
+ composition.addOffDuration(Duration.ofMillis(delay));
+
VibrationEffect.WaveformBuilder waveform = VibrationEffect.startWaveform();
for (int i = 0; i < durations.size(); i++) {
- if (isContinuous) {
- if (hasFrequencies) {
- waveform.addRamp(amplitudes.get(i), frequencies.get(i), durations.get(i));
- } else {
- waveform.addRamp(amplitudes.get(i), durations.get(i));
- }
+ Duration transitionDuration = isContinuous
+ ? Duration.ofMillis(durations.get(i))
+ : Duration.ZERO;
+
+ if (hasFrequencies) {
+ waveform.addTransition(transitionDuration, targetAmplitude(amplitudes.get(i)),
+ targetFrequency(frequencies.get(i)));
} else {
+ waveform.addTransition(transitionDuration, targetAmplitude(amplitudes.get(i)));
+ }
+ if (!isContinuous) {
+ waveform.addSustain(Duration.ofMillis(durations.get(i)));
+ }
+
+ if ((i > 0) && (i == repeat)) {
+ // Add segment that is not repeated to the composition and reset builder.
+ composition.addEffect(waveform.build());
+
if (hasFrequencies) {
- waveform.addStep(amplitudes.get(i), frequencies.get(i), durations.get(i));
+ waveform = VibrationEffect.startWaveform(targetAmplitude(amplitudes.get(i)),
+ targetFrequency(frequencies.get(i)));
} else {
- waveform.addStep(amplitudes.get(i), durations.get(i));
+ waveform = VibrationEffect.startWaveform(
+ targetAmplitude(amplitudes.get(i)));
}
}
}
- composition.addEffect(waveform.build(repeat), delay);
+ if (repeat < 0) {
+ composition.addEffect(waveform.build());
+ } else {
+ // The waveform was already split at the repeat index, just repeat what remains.
+ composition.repeatEffectIndefinitely(waveform.build());
+ }
}
private void addPrebakedToComposition(VibrationEffect.Composition composition) {
@@ -1796,7 +1822,8 @@
}
int effectId = Integer.parseInt(getNextArgRequired());
- composition.addEffect(VibrationEffect.get(effectId, shouldFallback), delay);
+ composition.addOffDuration(Duration.ofMillis(delay));
+ composition.addEffect(VibrationEffect.get(effectId, shouldFallback));
}
private void addPrimitivesToComposition(VibrationEffect.Composition composition) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 49d6a34..897549b 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -395,9 +395,9 @@
// How many activities have to be scheduled to stop to force a stop pass.
private static final int MAX_STOPPING_TO_FORCE = 3;
- private static final int STARTING_WINDOW_TYPE_NONE = 0;
- private static final int STARTING_WINDOW_TYPE_SNAPSHOT = 1;
- private static final int STARTING_WINDOW_TYPE_SPLASH_SCREEN = 2;
+ static final int STARTING_WINDOW_TYPE_NONE = 0;
+ static final int STARTING_WINDOW_TYPE_SNAPSHOT = 1;
+ static final int STARTING_WINDOW_TYPE_SPLASH_SCREEN = 2;
static final int INVALID_PID = -1;
@@ -2149,7 +2149,8 @@
final int typeParameter = StartingSurfaceController
.makeStartingWindowTypeParameter(newTask, taskSwitch, processRunning,
- allowTaskSnapshot, activityCreated, useEmpty, useLegacy, activityAllDrawn);
+ allowTaskSnapshot, activityCreated, useEmpty, useLegacy, activityAllDrawn,
+ type, packageName, mUserId);
if (type == STARTING_WINDOW_TYPE_SNAPSHOT) {
if (isActivityTypeHome()) {
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index e119a9a..5164bf0 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2924,7 +2924,7 @@
final boolean onTop =
(aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind;
return mRootWindowContainer.getLaunchRootTask(r, aOptions, task, mSourceRootTask, onTop,
- mLaunchParams, launchFlags, mRequest.realCallingPid, mRequest.realCallingUid);
+ mLaunchParams, launchFlags);
}
private boolean isLaunchModeOneOf(int mode1, int mode2) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index dd394ca..5d879ce 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -2224,25 +2224,9 @@
return;
}
- if (!task.supportsSplitScreenWindowingMode() || forceNonResizable) {
- if (task.mTransitionController.isShellTransitionsEnabled()) return;
- // Dismiss docked root task. If task appeared to be in docked root task but is not
- // resizable - we need to move it to top of fullscreen root task, otherwise it will
- // be covered.
- final TaskDisplayArea taskDisplayArea = task.getDisplayArea();
- if (taskDisplayArea.isSplitScreenModeActivated()) {
- // Display a warning toast that we tried to put an app that doesn't support
- // split-screen in split-screen.
- mService.getTaskChangeNotificationController()
- .notifyActivityDismissingDockedRootTask();
- taskDisplayArea.onSplitScreenModeDismissed(task);
- taskDisplayArea.mDisplayContent.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS,
- true /* notifyClients */);
- }
- return;
+ if (!forceNonResizable) {
+ handleForcedResizableTaskIfNeeded(task, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN);
}
-
- handleForcedResizableTaskIfNeeded(task, FORCED_RESIZEABLE_REASON_SPLIT_SCREEN);
}
/** Notifies that the top activity of the task is forced to be resizeable. */
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 5facc0d..a1c823e 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3043,13 +3043,6 @@
mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION);
}
amendWindowTapExcludeRegion(mTouchExcludeRegion);
- // TODO(multi-display): Support docked root tasks on secondary displays & task containers.
- if (mDisplayId == DEFAULT_DISPLAY
- && getDefaultTaskDisplayArea().isSplitScreenModeActivated()) {
- mDividerControllerLocked.getTouchRegion(mTmpRect);
- mTmpRegion.set(mTmpRect);
- mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
- }
mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion);
}
@@ -3440,12 +3433,6 @@
if (rootPinnedTask != null) {
pw.println(prefix + "rootPinnedTask=" + rootPinnedTask.getName());
}
- final Task rootSplitScreenPrimaryTask = getDefaultTaskDisplayArea()
- .getRootSplitScreenPrimaryTask();
- if (rootSplitScreenPrimaryTask != null) {
- pw.println(
- prefix + "rootSplitScreenPrimaryTask=" + rootSplitScreenPrimaryTask.getName());
- }
// TODO: Support recents on non-default task containers
final Task rootRecentsTask = getDefaultTaskDisplayArea().getRootTask(
WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_RECENTS);
@@ -4849,13 +4836,10 @@
}
private static boolean skipImeWindowsDuringTraversal(DisplayContent dc) {
- // We skip IME windows so they're processed just above their target, except
- // in split-screen mode where we process the IME containers above the docked divider.
+ // We skip IME windows so they're processed just above their target.
// Note that this method check should align with {@link
// WindowState#applyImeWindowsIfNeeded} in case of any state mismatch.
return dc.mImeLayeringTarget != null
- && (!dc.getDefaultTaskDisplayArea().isSplitScreenModeActivated()
- || dc.mImeLayeringTarget.getTask() == null)
// Make sure that the IME window won't be skipped to report that it has
// completed the orientation change.
&& !dc.mWmService.mDisplayFrozen;
diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
index e04e3a3..0e2d847 100644
--- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java
+++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
@@ -41,8 +41,6 @@
private static final String TAG = TAG_WITH_CLASS_NAME ? "EmbeddedWindowController" : TAG_WM;
/* maps input token to an embedded window */
private ArrayMap<IBinder /*input token */, EmbeddedWindow> mWindows = new ArrayMap<>();
- private ArrayMap<IBinder /*focus grant token */, EmbeddedWindow> mWindowsByFocusToken =
- new ArrayMap<>();
private final Object mGlobalLock;
private final ActivityTaskManagerService mAtmService;
@@ -61,13 +59,10 @@
void add(IBinder inputToken, EmbeddedWindow window) {
try {
mWindows.put(inputToken, window);
- final IBinder focusToken = window.getFocusGrantToken();
- mWindowsByFocusToken.put(focusToken, window);
updateProcessController(window);
window.mClient.asBinder().linkToDeath(()-> {
synchronized (mGlobalLock) {
mWindows.remove(inputToken);
- mWindowsByFocusToken.remove(focusToken);
}
}, 0);
} catch (RemoteException e) {
@@ -112,10 +107,8 @@
void remove(IWindow client) {
for (int i = mWindows.size() - 1; i >= 0; i--) {
- EmbeddedWindow ew = mWindows.valueAt(i);
- if (ew.mClient.asBinder() == client.asBinder()) {
+ if (mWindows.valueAt(i).mClient.asBinder() == client.asBinder()) {
mWindows.removeAt(i).onRemoved();
- mWindowsByFocusToken.remove(ew.getFocusGrantToken());
return;
}
}
@@ -123,10 +116,8 @@
void onWindowRemoved(WindowState host) {
for (int i = mWindows.size() - 1; i >= 0; i--) {
- EmbeddedWindow ew = mWindows.valueAt(i);
- if (ew.mHostWindowState == host) {
+ if (mWindows.valueAt(i).mHostWindowState == host) {
mWindows.removeAt(i).onRemoved();
- mWindowsByFocusToken.remove(ew.getFocusGrantToken());
}
}
}
@@ -135,10 +126,6 @@
return mWindows.get(inputToken);
}
- EmbeddedWindow getByFocusToken(IBinder focusGrantToken) {
- return mWindowsByFocusToken.get(focusGrantToken);
- }
-
void onActivityRemoved(ActivityRecord activityRecord) {
for (int i = mWindows.size() - 1; i >= 0; i--) {
final EmbeddedWindow window = mWindows.valueAt(i);
@@ -170,8 +157,6 @@
// and this variable is mostly used for tracking that.
boolean mIsOverlay = false;
- private IBinder mFocusGrantToken;
-
/**
* @param session calling session to check ownership of the window
* @param clientToken client token used to clean up the map if the embedding process dies
@@ -186,7 +171,7 @@
*/
EmbeddedWindow(Session session, WindowManagerService service, IWindow clientToken,
WindowState hostWindowState, int ownerUid, int ownerPid, int windowType,
- int displayId, IBinder focusGrantToken) {
+ int displayId) {
mSession = session;
mWmService = service;
mClient = clientToken;
@@ -197,7 +182,6 @@
mOwnerPid = ownerPid;
mWindowType = windowType;
mDisplayId = displayId;
- mFocusGrantToken = focusGrantToken;
}
@Override
@@ -258,17 +242,6 @@
return mIsOverlay;
}
- IBinder getFocusGrantToken() {
- return mFocusGrantToken;
- }
-
- IBinder getInputChannelToken() {
- if (mInputChannel != null) {
- return mInputChannel.getToken();
- }
- return null;
- }
-
/**
* System hosted overlays need the WM to invoke grantEmbeddedWindowFocus and
* so we need to participate inside handlePointerDownOutsideFocus logic
@@ -282,7 +255,7 @@
private void handleTap(boolean grantFocus) {
if (mInputChannel != null) {
- mWmService.grantEmbeddedWindowFocus(mSession, mFocusGrantToken, grantFocus);
+ mWmService.grantEmbeddedWindowFocus(mSession, mInputChannel.getToken(), grantFocus);
}
}
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index baf7f87..5c8502b 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -450,16 +450,6 @@
return;
}
- // Dismiss split screen
- // The lock screen is currently showing, but is occluded by a window that can
- // show on top of the lock screen. In this can we want to dismiss the docked
- // stack since it will be complicated/risky to try to put the activity on top
- // of the lock screen in the right fullscreen configuration.
- final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
- if (taskDisplayArea.isSplitScreenModeActivated()) {
- taskDisplayArea.onSplitScreenModeDismissed();
- }
-
// Dismiss freeform windowing mode
if (currentTaskControllingOcclusion == null) {
return;
diff --git a/services/core/java/com/android/server/wm/LaunchParamsController.java b/services/core/java/com/android/server/wm/LaunchParamsController.java
index 3793e4b..8e5d73f 100644
--- a/services/core/java/com/android/server/wm/LaunchParamsController.java
+++ b/services/core/java/com/android/server/wm/LaunchParamsController.java
@@ -150,10 +150,8 @@
if (mTmpParams.hasWindowingMode() && task.isRootTask()
&& mTmpParams.mWindowingMode != task.getWindowingMode()) {
- final int activityType = activity != null
- ? activity.getActivityType() : task.getActivityType();
task.setWindowingMode(task.getDisplayArea().validateWindowingMode(
- mTmpParams.mWindowingMode, activity, task, activityType));
+ mTmpParams.mWindowingMode, activity, task));
}
if (mTmpParams.mBounds.isEmpty()) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 4c72d02b..76a7981 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1907,10 +1907,6 @@
final Task topFocusedRootTask = getTopDisplayFocusedRootTask();
final int focusRootTaskId = topFocusedRootTask != null
? topFocusedRootTask.getRootTaskId() : INVALID_TASK_ID;
- // We dismiss the docked root task whenever we switch users.
- if (getDefaultTaskDisplayArea().isSplitScreenModeActivated()) {
- getDefaultTaskDisplayArea().onSplitScreenModeDismissed();
- }
// Also dismiss the pinned root task whenever we switch users. Removing the pinned root task
// will also cause all tasks to be moved to the fullscreen root task at a position that is
// appropriate.
@@ -2765,8 +2761,7 @@
Task getLaunchRootTask(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
@Nullable Task candidateTask, boolean onTop) {
return getLaunchRootTask(r, options, candidateTask, null /* sourceTask */, onTop,
- null /* launchParams */, 0 /* launchFlags */, -1 /* no realCallingPid */,
- -1 /* no realCallingUid */);
+ null /* launchParams */, 0 /* launchFlags */);
}
/**
@@ -2785,8 +2780,7 @@
Task getLaunchRootTask(@Nullable ActivityRecord r,
@Nullable ActivityOptions options, @Nullable Task candidateTask,
@Nullable Task sourceTask, boolean onTop,
- @Nullable LaunchParamsController.LaunchParams launchParams, int launchFlags,
- int realCallingPid, int realCallingUid) {
+ @Nullable LaunchParamsController.LaunchParams launchParams, int launchFlags) {
int taskId = INVALID_TASK_ID;
int displayId = INVALID_DISPLAY;
TaskDisplayArea taskDisplayArea = null;
@@ -2835,11 +2829,7 @@
if (taskDisplayArea != null) {
final int tdaDisplayId = taskDisplayArea.getDisplayId();
- final boolean canLaunchOnDisplayFromStartRequest =
- realCallingPid != 0 && realCallingUid > 0 && r != null
- && mTaskSupervisor.canPlaceEntityOnDisplay(tdaDisplayId,
- realCallingPid, realCallingUid, r.info);
- if (canLaunchOnDisplayFromStartRequest || canLaunchOnDisplay(r, tdaDisplayId)) {
+ if (canLaunchOnDisplay(r, tdaDisplayId)) {
if (r != null) {
final Task result = getValidLaunchRootTaskInTaskDisplayArea(
taskDisplayArea, r, candidateTask, options, launchParams);
@@ -2872,8 +2862,7 @@
container = rootTask.getDisplayArea();
if (container != null && canLaunchOnDisplay(r, container.mDisplayContent.mDisplayId)) {
if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
- windowingMode = container.resolveWindowingMode(r, options, candidateTask,
- activityType);
+ windowingMode = container.resolveWindowingMode(r, options, candidateTask);
}
// Always allow organized tasks that created by organizer since the activity type
// of an organized task is decided by the activity type of its top child, which
@@ -2889,8 +2878,7 @@
|| !canLaunchOnDisplay(r, container.mDisplayContent.mDisplayId)) {
container = getDefaultTaskDisplayArea();
if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
- windowingMode = container.resolveWindowingMode(r, options, candidateTask,
- activityType);
+ windowingMode = container.resolveWindowingMode(r, options, candidateTask);
}
}
@@ -2952,8 +2940,7 @@
windowingMode = options != null ? options.getLaunchWindowingMode()
: r.getWindowingMode();
}
- windowingMode = taskDisplayArea.validateWindowingMode(windowingMode, r, candidateTask,
- r.getActivityType());
+ windowingMode = taskDisplayArea.validateWindowingMode(windowingMode, r, candidateTask);
// Return the topmost valid root task on the display.
final int targetWindowingMode = windowingMode;
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 98acc46..9b94f44 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -813,7 +813,7 @@
@Override
public void grantInputChannel(int displayId, SurfaceControl surface,
IWindow window, IBinder hostInputToken, int flags, int privateFlags, int type,
- IBinder focusGrantToken, InputChannel outInputChannel) {
+ InputChannel outInputChannel) {
if (hostInputToken == null && !mCanAddInternalSystemWindow) {
// Callers without INTERNAL_SYSTEM_WINDOW permission cannot grant input channel to
// embedded windows without providing a host window input token
@@ -829,7 +829,7 @@
try {
mService.grantInputChannel(this, mUid, mPid, displayId, surface, window, hostInputToken,
flags, mCanAddInternalSystemWindow ? privateFlags : 0,
- mCanAddInternalSystemWindow ? type : 0, focusGrantToken, outInputChannel);
+ mCanAddInternalSystemWindow ? type : 0, outInputChannel);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/com/android/server/wm/ShellRoot.java b/services/core/java/com/android/server/wm/ShellRoot.java
index 6ed59e9..2eab3ba 100644
--- a/services/core/java/com/android/server/wm/ShellRoot.java
+++ b/services/core/java/com/android/server/wm/ShellRoot.java
@@ -141,8 +141,7 @@
&& mShellRootLayer != SHELL_ROOT_LAYER_PIP) {
return null;
}
- if (mShellRootLayer == SHELL_ROOT_LAYER_DIVIDER
- && !mDisplayContent.getDefaultTaskDisplayArea().isSplitScreenModeActivated()) {
+ if (mShellRootLayer == SHELL_ROOT_LAYER_DIVIDER) {
return null;
}
if (mShellRootLayer == SHELL_ROOT_LAYER_PIP
diff --git a/services/core/java/com/android/server/wm/StartingSurfaceController.java b/services/core/java/com/android/server/wm/StartingSurfaceController.java
index eb73cd8..2a3767f 100644
--- a/services/core/java/com/android/server/wm/StartingSurfaceController.java
+++ b/services/core/java/com/android/server/wm/StartingSurfaceController.java
@@ -18,6 +18,7 @@
import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_CREATED;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_DRAWN;
+import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_HANDLE_EMPTY_SCREEN;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_LEGACY_SPLASH_SCREEN;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_NEW_TASK;
@@ -25,12 +26,17 @@
import static android.window.StartingWindowInfo.TYPE_PARAMETER_TASK_SWITCH;
import static android.window.StartingWindowInfo.TYPE_PARAMETER_USE_EMPTY_SPLASH_SCREEN;
+import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_TYPE_SPLASH_SCREEN;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
import android.content.pm.ApplicationInfo;
+import android.os.UserHandle;
import android.util.Slog;
import android.window.TaskSnapshot;
@@ -43,6 +49,14 @@
public class StartingSurfaceController {
private static final String TAG = TAG_WITH_CLASS_NAME
? StartingSurfaceController.class.getSimpleName() : TAG_WM;
+ /**
+ * Allow the empty style splash screen view can be copy and transfer to another process if
+ * the app targeting to {@link android.os.Build.VERSION_CODES#TIRAMISU} or higher.
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.TIRAMISU)
+ private static final long ALLOW_COPY_EMPTY_VIEW = 205907456L;
+
private final WindowManagerService mService;
private final SplashScreenExceptionList mSplashScreenExceptionsList;
@@ -81,7 +95,8 @@
static int makeStartingWindowTypeParameter(boolean newTask, boolean taskSwitch,
boolean processRunning, boolean allowTaskSnapshot, boolean activityCreated,
- boolean useEmpty, boolean useLegacy, boolean activityDrawn) {
+ boolean useEmpty, boolean useLegacy, boolean activityDrawn, int startingWindowType,
+ String packageName, int userId) {
int parameter = 0;
if (newTask) {
parameter |= TYPE_PARAMETER_NEW_TASK;
@@ -107,6 +122,11 @@
if (activityDrawn) {
parameter |= TYPE_PARAMETER_ACTIVITY_DRAWN;
}
+ if (startingWindowType == STARTING_WINDOW_TYPE_SPLASH_SCREEN
+ && CompatChanges.isChangeEnabled(ALLOW_COPY_EMPTY_VIEW, packageName,
+ UserHandle.of(userId))) {
+ parameter |= TYPE_PARAMETER_ALLOW_HANDLE_EMPTY_SCREEN;
+ }
return parameter;
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index ff9d9f7..91c1374 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -4500,22 +4500,11 @@
// right mode.
if (!creating) {
if (!taskDisplayArea.isValidWindowingMode(windowingMode, null /* ActivityRecord */,
- topTask, getActivityType())) {
+ topTask)) {
windowingMode = WINDOWING_MODE_UNDEFINED;
}
}
- final boolean alreadyInSplitScreenMode = taskDisplayArea.isSplitScreenModeActivated();
-
- if (creating && alreadyInSplitScreenMode && windowingMode == WINDOWING_MODE_FULLSCREEN
- && isActivityTypeStandardOrUndefined()) {
- // If the root task is being created explicitly in fullscreen mode, dismiss split-screen
- // and display a warning toast about it.
- mAtmService.getTaskChangeNotificationController()
- .notifyActivityDismissingDockedRootTask();
- taskDisplayArea.onSplitScreenModeDismissed(this);
- }
-
if (currentMode == windowingMode) {
// You are already in the window mode, so we can skip most of the work below. However,
// it's possible that we have inherited the current windowing mode from a parent. So,
@@ -6501,9 +6490,8 @@
if (!TaskDisplayArea.isWindowingModeSupported(mWindowingMode,
mAtmService.mSupportsMultiWindow,
- mAtmService.mSupportsSplitScreenMultiWindow,
mAtmService.mSupportsFreeformWindowManagement,
- mAtmService.mSupportsPictureInPicture, mActivityType)) {
+ mAtmService.mSupportsPictureInPicture)) {
throw new IllegalArgumentException("Can't create root task for unsupported "
+ "windowingMode=" + mWindowingMode);
}
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index dfb559f..1bba103 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -24,8 +24,6 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
@@ -53,8 +51,6 @@
import android.util.Slog;
import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
-import android.window.WindowContainerToken;
-import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
@@ -114,7 +110,6 @@
// through the list to find them.
private Task mRootHomeTask;
private Task mRootPinnedTask;
- private Task mRootSplitScreenPrimaryTask;
// TODO(b/159029784): Remove when getStack() behavior is cleaned-up
private Task mRootRecentsTask;
@@ -232,8 +227,6 @@
}
if (windowingMode == WINDOWING_MODE_PINNED) {
return mRootPinnedTask;
- } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
- return mRootSplitScreenPrimaryTask;
}
return getRootTask(rootTask -> {
if (activityType == ACTIVITY_TYPE_UNDEFINED
@@ -265,21 +258,6 @@
return mRootPinnedTask;
}
- Task getRootSplitScreenPrimaryTask() {
- return mRootSplitScreenPrimaryTask;
- }
-
- Task getRootSplitScreenSecondaryTask() {
- // Only check the direct child Task for now, since the primary is also a direct child Task.
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final Task task = mChildren.get(i).asTask();
- if (task != null && task.inSplitScreenSecondaryWindowingMode()) {
- return task;
- }
- }
- return null;
- }
-
ArrayList<Task> getVisibleTasks() {
final ArrayList<Task> visibleTasks = new ArrayList<>();
forAllTasks(task -> {
@@ -333,14 +311,6 @@
+ " already exist on display=" + this + " rootTask=" + rootTask);
}
mRootPinnedTask = rootTask;
- } else if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
- if (mRootSplitScreenPrimaryTask != null) {
- throw new IllegalArgumentException(
- "addRootTaskReferenceIfNeeded: root split screen primary task="
- + mRootSplitScreenPrimaryTask
- + " already exist on display=" + this + " rootTask=" + rootTask);
- }
- mRootSplitScreenPrimaryTask = rootTask;
}
}
@@ -351,8 +321,6 @@
mRootRecentsTask = null;
} else if (rootTask == mRootPinnedTask) {
mRootPinnedTask = null;
- } else if (rootTask == mRootSplitScreenPrimaryTask) {
- mRootSplitScreenPrimaryTask = null;
}
}
@@ -708,39 +676,13 @@
}, SCREEN_ORIENTATION_UNSET);
}
- if (isRootTaskVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)) {
- // Apps and their containers are not allowed to specify an orientation while using
- // root tasks...except for the root home task if it is not resizable and currently
- // visible (top of) its root task.
- if (mRootHomeTask != null && !mRootHomeTask.isResizeable()) {
- // Manually nest one-level because because getOrientation() checks fillsParent()
- // which checks that requestedOverrideBounds() is empty. However, in this case,
- // it is not empty because it's been overridden to maintain the fullscreen size
- // within a smaller split-root.
- final Task topHomeTask = mRootHomeTask.getTopMostTask();
- final ActivityRecord topHomeActivity = topHomeTask.getTopNonFinishingActivity();
- // If a home activity is in the process of launching and isn't yet visible we
- // should still respect the root task's preferred orientation to ensure rotation
- // occurs before the home activity finishes launching.
- final boolean isHomeActivityLaunching = topHomeActivity != null
- && topHomeActivity.mVisibleRequested;
- if (topHomeTask.isVisible() || isHomeActivityLaunching) {
- final int orientation = topHomeTask.getOrientation();
- if (orientation != SCREEN_ORIENTATION_UNSET) {
- return orientation;
- }
- }
- }
+ // Apps and their containers are not allowed to specify an orientation of non floating
+ // visible tasks created by organizer. The organizer handles the orientation instead.
+ final Task nonFloatingTopTask =
+ getRootTask(t -> !t.getWindowConfiguration().tasksAreFloating());
+ if (nonFloatingTopTask != null && nonFloatingTopTask.mCreatedByOrganizer
+ && nonFloatingTopTask.isVisible()) {
return SCREEN_ORIENTATION_UNSPECIFIED;
- } else {
- // Apps and their containers are not allowed to specify an orientation of non floating
- // visible tasks created by organizer. The organizer handles the orientation instead.
- final Task nonFloatingTopTask =
- getRootTask(t -> !t.getWindowConfiguration().tasksAreFloating());
- if (nonFloatingTopTask != null && nonFloatingTopTask.mCreatedByOrganizer
- && nonFloatingTopTask.isVisible()) {
- return SCREEN_ORIENTATION_UNSPECIFIED;
- }
}
final int orientation = super.getOrientation(candidate);
@@ -845,7 +787,7 @@
&& child.inMultiWindowMode()
&& childTask.getRootTask().getAdjacentTaskFragment() != null;
- if (inAdjacentTask || child.inSplitScreenWindowingMode()) {
+ if (inAdjacentTask) {
hasAdjacentTask = true;
} else if (hasAdjacentTask && startLayer < SPLIT_DIVIDER_LAYER) {
// Task on top of adjacent tasks should be higher than split divider layer so
@@ -1086,7 +1028,7 @@
// Validate that our desired windowingMode will work under the current conditions.
// UNDEFINED windowing mode is a valid result and means that the new root task will inherit
// it's display's windowing mode.
- windowingMode = validateWindowingMode(windowingMode, r, candidateTask, activityType);
+ windowingMode = validateWindowingMode(windowingMode, r, candidateTask);
return getOrCreateRootTask(windowingMode, activityType, onTop, candidateTask, sourceTask,
options, launchFlags);
}
@@ -1283,23 +1225,6 @@
continue;
}
- if (currentWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
- && candidate == null && rootTask.inSplitScreenPrimaryWindowingMode()) {
- // If the currently focused root task is in split-screen secondary we save off the
- // top primary split-screen root task as a candidate for focus because we might
- // prefer focus to move to an other root task to avoid primary split-screen root
- // task overlapping with a fullscreen root task when a fullscreen root task is
- // higher in z than the next split-screen root task. Assistant root task, I am
- // looking at you...
- // We only move the focus to the primary-split screen root task if there isn't a
- // better alternative.
- candidate = rootTask;
- continue;
- }
- if (candidate != null && rootTask.inSplitScreenSecondaryWindowingMode()) {
- // Use the candidate root task since we are now at the secondary split-screen.
- return candidate;
- }
return rootTask;
}
return candidate;
@@ -1416,75 +1341,18 @@
return someActivityPaused[0] > 0;
}
- void onSplitScreenModeDismissed() {
- // The focused task could be a non-resizeable fullscreen root task that is on top of the
- // other split-screen tasks, therefore had to dismiss split-screen, make sure the current
- // focused root task can still be on top after dismissal
- final Task rootTask = getFocusedRootTask();
- final Task toTop =
- rootTask != null && !rootTask.inSplitScreenWindowingMode() ? rootTask : null;
- onSplitScreenModeDismissed(toTop);
- }
-
- void onSplitScreenModeDismissed(Task toTop) {
- mAtmService.deferWindowLayout();
- try {
- moveSplitScreenTasksToFullScreen();
- } finally {
- final Task topFullscreenRootTask = toTop != null
- ? toTop : getTopRootTaskInWindowingMode(WINDOWING_MODE_FULLSCREEN);
- final Task rootHomeTask = getOrCreateRootHomeTask();
- if (rootHomeTask != null && ((topFullscreenRootTask != null && !isTopRootTask(
- rootHomeTask)) || toTop != null)) {
- // Whenever split-screen is dismissed we want the root home task directly behind the
- // current top fullscreen root task so it shows up when the top root task is
- // finished. Or, if the caller specified a root task to be on top after
- // split-screen is dismissed.
- // TODO: Would be better to use ActivityDisplay.positionChildAt() for this, however
- // ActivityDisplay doesn't have a direct controller to WM side yet. We can switch
- // once we have that.
- rootHomeTask.moveToFront("onSplitScreenModeDismissed");
- topFullscreenRootTask.moveToFront("onSplitScreenModeDismissed");
- }
- mAtmService.continueWindowLayout();
- }
- }
-
- private void moveSplitScreenTasksToFullScreen() {
- final WindowContainerTransaction wct = new WindowContainerTransaction();
- mTmpTasks.clear();
- forAllTasks(task -> {
- if (task.mCreatedByOrganizer && task.inSplitScreenWindowingMode() && task.hasChild()) {
- mTmpTasks.add(task);
- }
- });
-
- for (int i = mTmpTasks.size() - 1; i >= 0; i--) {
- final Task root = mTmpTasks.get(i);
- for (int j = 0; j < root.getChildCount(); j++) {
- final WindowContainerToken token =
- root.getChildAt(j).mRemoteToken.toWindowContainerToken();
- wct.reparent(token, null, true /* toTop */);
- wct.setBounds(token, null);
- }
- }
- mAtmService.mWindowOrganizerController.applyTransaction(wct);
- }
/**
* Returns true if the {@param windowingMode} is supported based on other parameters passed in.
*
* @param windowingMode The windowing mode we are checking support for.
* @param supportsMultiWindow If we should consider support for multi-window mode in general.
- * @param supportsSplitScreen If we should consider support for split-screen multi-window.
* @param supportsFreeform If we should consider support for freeform multi-window.
* @param supportsPip If we should consider support for picture-in-picture mutli-window.
- * @param activityType The activity type under consideration.
* @return true if the windowing mode is supported.
*/
static boolean isWindowingModeSupported(int windowingMode, boolean supportsMultiWindow,
- boolean supportsSplitScreen, boolean supportsFreeform, boolean supportsPip,
- int activityType) {
+ boolean supportsFreeform, boolean supportsPip) {
if (windowingMode == WINDOWING_MODE_UNDEFINED
|| windowingMode == WINDOWING_MODE_FULLSCREEN) {
@@ -1498,12 +1366,6 @@
return true;
}
- if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY
- || windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
- return supportsSplitScreen
- && WindowConfiguration.supportSplitScreenWindowingMode(activityType);
- }
-
if (!supportsFreeform && windowingMode == WINDOWING_MODE_FREEFORM) {
return false;
}
@@ -1525,7 +1387,7 @@
* @return The resolved (not UNDEFINED) windowing-mode that the activity would be in.
*/
int resolveWindowingMode(@Nullable ActivityRecord r, @Nullable ActivityOptions options,
- @Nullable Task task, int activityType) {
+ @Nullable Task task) {
// First preference if the windowing mode in the activity options if set.
int windowingMode = (options != null)
@@ -1545,7 +1407,7 @@
windowingMode = getWindowingMode();
}
}
- windowingMode = validateWindowingMode(windowingMode, r, task, activityType);
+ windowingMode = validateWindowingMode(windowingMode, r, task);
return windowingMode != WINDOWING_MODE_UNDEFINED
? windowingMode : WINDOWING_MODE_FULLSCREEN;
}
@@ -1557,19 +1419,16 @@
* @param windowingMode The windowing-mode to validate.
* @param r The {@link ActivityRecord} to check against.
* @param task The {@link Task} to check against.
- * @param activityType An activity type.
* @return {@code true} if windowingMode is valid, {@code false} otherwise.
*/
- boolean isValidWindowingMode(int windowingMode, @Nullable ActivityRecord r, @Nullable Task task,
- int activityType) {
+ boolean isValidWindowingMode(int windowingMode, @Nullable ActivityRecord r, @Nullable Task task
+ ) {
// Make sure the windowing mode we are trying to use makes sense for what is supported.
boolean supportsMultiWindow = mAtmService.mSupportsMultiWindow;
- boolean supportsSplitScreen = mAtmService.mSupportsSplitScreenMultiWindow;
boolean supportsFreeform = mAtmService.mSupportsFreeformWindowManagement;
boolean supportsPip = mAtmService.mSupportsPictureInPicture;
if (supportsMultiWindow) {
if (task != null) {
- supportsSplitScreen = task.supportsSplitScreenWindowingModeInDisplayArea(this);
supportsFreeform = task.supportsFreeformInDisplayArea(this);
supportsMultiWindow = task.supportsMultiWindowInDisplayArea(this)
// When the activity needs to be moved to PIP while the Task is not in PIP,
@@ -1577,7 +1436,6 @@
// always valid for Task as long as the device supports it.
|| (windowingMode == WINDOWING_MODE_PINNED && supportsPip);
} else if (r != null) {
- supportsSplitScreen = r.supportsSplitScreenWindowingModeInDisplayArea(this);
supportsFreeform = r.supportsFreeformInDisplayArea(this);
supportsPip = r.supportsPictureInPicture();
supportsMultiWindow = r.supportsMultiWindowInDisplayArea(this);
@@ -1585,8 +1443,8 @@
}
return windowingMode != WINDOWING_MODE_UNDEFINED
- && isWindowingModeSupported(windowingMode, supportsMultiWindow, supportsSplitScreen,
- supportsFreeform, supportsPip, activityType);
+ && isWindowingModeSupported(windowingMode, supportsMultiWindow, supportsFreeform,
+ supportsPip);
}
/**
@@ -1596,20 +1454,10 @@
* @param windowingMode The windowing-mode to validate.
* @param r The {@link ActivityRecord} to check against.
* @param task The {@link Task} to check against.
- * @param activityType An activity type.
* @return The provided windowingMode or the closest valid mode which is appropriate.
*/
- int validateWindowingMode(int windowingMode, @Nullable ActivityRecord r, @Nullable Task task,
- int activityType) {
- final boolean inSplitScreenMode = isSplitScreenModeActivated();
- if (!inSplitScreenMode && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
- // Switch to the display's windowing mode if we are not in split-screen mode and we are
- // trying to launch in split-screen secondary.
- windowingMode = WINDOWING_MODE_UNDEFINED;
- } else if (inSplitScreenMode && windowingMode == WINDOWING_MODE_UNDEFINED) {
- windowingMode = WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
- }
- if (!isValidWindowingMode(windowingMode, r, task, activityType)) {
+ int validateWindowingMode(int windowingMode, @Nullable ActivityRecord r, @Nullable Task task) {
+ if (!isValidWindowingMode(windowingMode, r, task)) {
return WINDOWING_MODE_UNDEFINED;
}
return windowingMode;
@@ -1774,11 +1622,6 @@
return homeTask;
}
- boolean isSplitScreenModeActivated() {
- Task task = getRootSplitScreenPrimaryTask();
- return task != null && task.hasChild();
- }
-
/**
* Returns the topmost root task on the display that is compatible with the input windowing
* mode. Null is no compatible root task on the display.
@@ -1866,8 +1709,7 @@
continue;
}
final int winMode = s.getWindowingMode();
- final boolean isValidWindowingMode = winMode == WINDOWING_MODE_FULLSCREEN
- || winMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
+ final boolean isValidWindowingMode = winMode == WINDOWING_MODE_FULLSCREEN;
if (s.shouldBeVisible(null) && isValidWindowingMode) {
// Move the provided root task to behind this root task
final int position = Math.max(0, rootTaskNdx - 1);
@@ -1882,8 +1724,7 @@
private Task getBottomMostVisibleRootTask(Task excludeRootTask) {
return getRootTask(task -> {
final int winMode = task.getWindowingMode();
- final boolean isValidWindowingMode = winMode == WINDOWING_MODE_FULLSCREEN
- || winMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
+ final boolean isValidWindowingMode = winMode == WINDOWING_MODE_FULLSCREEN;
return task.shouldBeVisible(null) && isValidWindowingMode;
}, false /* traverseTopToBottom */);
}
@@ -2067,20 +1908,11 @@
numRootTasks = mChildren.size();
}
- if (lastReparentedRootTask != null) {
- if (toDisplayArea.isSplitScreenModeActivated()
- && !lastReparentedRootTask.supportsSplitScreenWindowingModeInDisplayArea(
- toDisplayArea)) {
- // Dismiss split screen if the last reparented root task doesn't support split mode.
- mAtmService.getTaskChangeNotificationController()
- .notifyActivityDismissingDockedRootTask();
- toDisplayArea.onSplitScreenModeDismissed(lastReparentedRootTask);
- } else if (!lastReparentedRootTask.isRootTask()) {
- // Update focus when the last reparented root task is not a root task anymore.
- // (For example, if it has been reparented to a split screen root task, move the
- // focus to the split root task)
- lastReparentedRootTask.getRootTask().moveToFront("display-removed");
- }
+ if (lastReparentedRootTask != null && !lastReparentedRootTask.isRootTask()) {
+ // Update focus when the last reparented root task is not a root task anymore.
+ // (For example, if it has been reparented to a split screen root task, move the
+ // focus to the split root task)
+ lastReparentedRootTask.getRootTask().moveToFront("display-removed");
}
mRemoved = true;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 71a24d7..eb1274c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -8276,8 +8276,7 @@
*/
void grantInputChannel(Session session, int callingUid, int callingPid, int displayId,
SurfaceControl surface, IWindow window, IBinder hostInputToken,
- int flags, int privateFlags, int type, IBinder focusGrantToken,
- InputChannel outInputChannel) {
+ int flags, int privateFlags, int type, InputChannel outInputChannel) {
final InputApplicationHandle applicationHandle;
final String name;
final InputChannel clientChannel;
@@ -8285,7 +8284,7 @@
EmbeddedWindowController.EmbeddedWindow win =
new EmbeddedWindowController.EmbeddedWindow(session, this, window,
mInputToWindowMap.get(hostInputToken), callingUid, callingPid, type,
- displayId, focusGrantToken);
+ displayId);
clientChannel = win.openInputChannel();
mEmbeddedWindowController.add(clientChannel.getToken(), win);
applicationHandle = win.getApplicationHandle();
@@ -8564,10 +8563,10 @@
}
}
- void grantEmbeddedWindowFocus(Session session, IBinder focusToken, boolean grantFocus) {
+ void grantEmbeddedWindowFocus(Session session, IBinder inputToken, boolean grantFocus) {
synchronized (mGlobalLock) {
final EmbeddedWindowController.EmbeddedWindow embeddedWindow =
- mEmbeddedWindowController.getByFocusToken(focusToken);
+ mEmbeddedWindowController.get(inputToken);
if (embeddedWindow == null) {
Slog.e(TAG, "Embedded window not found");
return;
@@ -8576,11 +8575,6 @@
Slog.e(TAG, "Window not in session:" + session);
return;
}
- IBinder inputToken = embeddedWindow.getInputChannelToken();
- if (inputToken == null) {
- Slog.e(TAG, "Focus token found but input channel token not found");
- return;
- }
SurfaceControl.Transaction t = mTransactionFactory.get();
final int displayId = embeddedWindow.mDisplayId;
if (grantFocus) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index a228d6a..8864b98 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1731,20 +1731,6 @@
} else {
intersectWithRootTaskBounds = false;
}
- if (inSplitScreenPrimaryWindowingMode()) {
- // If this is in the primary split and the root home task is the top visible task in
- // the secondary split, it means this is "minimized" and thus must prevent
- // overlapping with home.
- // TODO(b/158242495): get rid of this when drag/drop can use surface bounds.
- final Task rootSecondary =
- task.getDisplayArea().getRootSplitScreenSecondaryTask();
- if (rootSecondary.isActivityTypeHome() || rootSecondary.isActivityTypeRecents()) {
- final WindowContainer topTask = rootSecondary.getTopChild();
- if (topTask.isVisible()) {
- cutRect(mTmpRect, topTask.getBounds());
- }
- }
- }
}
bounds.set(mWindowFrames.mFrame);
@@ -4714,14 +4700,6 @@
if (!isImeLayeringTarget()) {
return false;
}
- // If we are in split screen which case we process the IME at the DisplayContent level to
- // ensure it is above the docked divider.
- // i.e. Like {@link DisplayContent.ImeContainer#skipImeWindowsDuringTraversal}, the IME
- // window will be ignored to traverse when the IME target is still in split-screen mode.
- if (mDisplayContent.getDefaultTaskDisplayArea().isSplitScreenModeActivated()
- && getTask() != null) {
- return false;
- }
// Note that we don't process IME window if the IME input target is not on the screen.
// In case some unexpected IME visibility cases happen like starting the remote
// animation on the keyguard but seeing the IME window that originally on the app
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 79a980f..95ef5f7 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -145,8 +145,8 @@
"libutils",
"libhwui",
"libbpf_android",
- "libnetdbpf",
"libnetdutils",
+ "libnetworkstats",
"libpsi",
"libdataloader",
"libincfs",
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index e0b6273..733cfcd 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -11042,7 +11042,8 @@
@Override
public int getLogoutUserId() {
- Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity()));
+ Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())
+ || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS));
return getLogoutUserIdUnchecked();
}
@@ -11057,16 +11058,7 @@
}
}
- @Override
- public void clearLogoutUser() {
- CallerIdentity caller = getCallerIdentity();
- Preconditions.checkCallAuthorization(canManageUsers(caller));
-
- Slogf.i(LOG_TAG, "Clearing logout user as requested by %s", caller);
- clearLogoutUserUnchecked();
- }
-
- private void clearLogoutUserUnchecked() {
+ private void clearLogoutUser() {
if (!mInjector.userManagerIsHeadlessSystemUserMode()) return; // ignore
synchronized (getLockObject()) {
@@ -11167,6 +11159,21 @@
return stopUserUnchecked(callingUserId);
}
+ return logoutUserUnchecked(/* userIdToStop= */ callingUserId);
+ }
+
+ @Override
+ public int logoutUserInternal() {
+ CallerIdentity caller = getCallerIdentity();
+ Preconditions.checkCallAuthorization(
+ canManageUsers(caller) || hasCallingOrSelfPermission(permission.CREATE_USERS));
+
+ int result = logoutUserUnchecked(getCurrentForegroundUserId());
+ Slogf.d(LOG_TAG, "logout called by uid %d. Result: %d", caller.getUid(), result);
+ return result;
+ }
+
+ private int logoutUserUnchecked(@UserIdInt int userIdToStop) {
int logoutUserId = getLogoutUserIdUnchecked();
if (logoutUserId == UserHandle.USER_NULL) {
// Could happen on devices using headless system user mode when called before calling
@@ -11182,7 +11189,7 @@
// This should never happen as target user is determined by getPreviousUserId()
return UserManager.USER_OPERATION_ERROR_UNKNOWN;
}
- clearLogoutUserUnchecked();
+ clearLogoutUser();
} catch (RemoteException e) {
// Same process, should not happen.
return UserManager.USER_OPERATION_ERROR_UNKNOWN;
@@ -11190,7 +11197,7 @@
mInjector.binderRestoreCallingIdentity(id);
}
- return stopUserUnchecked(callingUserId);
+ return stopUserUnchecked(userIdToStop);
}
private int stopUserUnchecked(@UserIdInt int userId) {
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 677f0f6..36c37c4 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -541,14 +541,11 @@
| ActivityManager.UID_OBSERVER_CAPABILITY
};
final IUidObserver[] observers = new IUidObserver.Stub[changesToObserve.length];
- doReturn(Process.myUid()).when(sPackageManagerInternal)
- .getPackageUid(mContext.getOpPackageName(), 0 /* flags */, mContext.getUserId());
for (int i = 0; i < observers.length; ++i) {
observers[i] = mock(IUidObserver.Stub.class);
when(observers[i].asBinder()).thenReturn((IBinder) observers[i]);
mAms.registerUidObserver(observers[i], changesToObserve[i] /* which */,
- ActivityManager.PROCESS_STATE_UNKNOWN /* cutpoint */,
- mContext.getOpPackageName());
+ ActivityManager.PROCESS_STATE_UNKNOWN /* cutpoint */, null /* caller */);
// When we invoke AMS.registerUidObserver, there are some interactions with observers[i]
// mock in RemoteCallbackList class. We don't want to test those interactions and
@@ -677,12 +674,10 @@
mockNoteOperation();
final IUidObserver observer = mock(IUidObserver.Stub.class);
+
when(observer.asBinder()).thenReturn((IBinder) observer);
- doReturn(Process.myUid()).when(sPackageManagerInternal)
- .getPackageUid(mContext.getOpPackageName(), 0 /* flags */, mContext.getUserId());
mAms.registerUidObserver(observer, ActivityManager.UID_OBSERVER_PROCSTATE /* which */,
- ActivityManager.PROCESS_STATE_SERVICE /* cutpoint */,
- mContext.getOpPackageName());
+ ActivityManager.PROCESS_STATE_SERVICE /* cutpoint */, null /* callingPackage */);
// When we invoke AMS.registerUidObserver, there are some interactions with observer
// mock in RemoteCallbackList class. We don't want to test those interactions and
// at the same time, we don't want those to interfere with verifyNoMoreInteractions.
@@ -776,9 +771,7 @@
final IUidObserver observer = mock(IUidObserver.Stub.class);
when(observer.asBinder()).thenReturn((IBinder) observer);
- doReturn(Process.myUid()).when(sPackageManagerInternal)
- .getPackageUid(mContext.getOpPackageName(), 0 /* flags */, mContext.getUserId());
- mAms.registerUidObserver(observer, 0, 0, mContext.getOpPackageName());
+ mAms.registerUidObserver(observer, 0, 0, null);
// Verify that when observers are registered, then validateUids is correctly updated.
addPendingUidChanges(pendingItemsForUids);
mAms.mUidObserverController.dispatchUidsChanged();
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java
index c675726..24a4751 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java
@@ -393,7 +393,8 @@
// Create an idle mode bms
// This will fail if it tries to fetch the wrong configuration.
- BrightnessMappingStrategy bms = BrightnessMappingStrategy.createForIdleMode(res, ddc);
+ BrightnessMappingStrategy bms = BrightnessMappingStrategy.createForIdleMode(res, ddc,
+ null);
assertNotNull("BrightnessMappingStrategy should not be null", bms);
// Ensure that the config is the one we set
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index eaa271a..1fb5898 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -33,6 +33,7 @@
import static org.mockito.Mockito.when;
import android.app.PropertyInvalidatedCache;
+import android.companion.virtual.IVirtualDevice;
import android.compat.testing.PlatformCompatChangeRule;
import android.content.Context;
import android.content.ContextWrapper;
@@ -73,6 +74,7 @@
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
import com.android.server.display.DisplayManagerService.SyncRoot;
import com.android.server.lights.LightsManager;
import com.android.server.sensors.SensorManagerInternal;
@@ -167,6 +169,7 @@
};
@Mock InputManagerInternal mMockInputManagerInternal;
+ @Mock VirtualDeviceManagerInternal mMockVirtualDeviceManagerInternal;
@Mock IVirtualDisplayCallback.Stub mMockAppToken;
@Mock IVirtualDisplayCallback.Stub mMockAppToken2;
@Mock WindowManagerInternal mMockWindowManagerInternal;
@@ -187,6 +190,9 @@
LocalServices.addService(LightsManager.class, mMockLightsManager);
LocalServices.removeServiceForTest(SensorManagerInternal.class);
LocalServices.addService(SensorManagerInternal.class, mMockSensorManagerInternal);
+ LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
+ LocalServices.addService(
+ VirtualDeviceManagerInternal.class, mMockVirtualDeviceManagerInternal);
mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
mDeviceConfig = new FakeDeviceConfigInterface();
@@ -661,6 +667,101 @@
}
/**
+ * Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is allowed when the permission
+ * ADD_TRUSTED_DISPLAY is granted.
+ */
+ @Test
+ public void testOwnDisplayGroup_allowCreationWithAddTrustedDisplayPermission() {
+ DisplayManagerService displayManager =
+ new DisplayManagerService(mContext, mBasicInjector);
+ registerDefaultDisplays(displayManager);
+
+ DisplayManagerService.BinderService bs = displayManager.new BinderService();
+ when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+
+ when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn(
+ PackageManager.PERMISSION_GRANTED);
+
+ final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
+ VIRTUAL_DISPLAY_NAME, 600, 800, 320);
+ builder.setFlags(DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP);
+ builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP");
+
+ int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
+ null /* projection */, null /* virtualDeviceToken */, PACKAGE_NAME);
+ displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
+ displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
+ DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
+ assertNotNull(ddi);
+ assertNotEquals(0, ddi.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP);
+ }
+
+ /**
+ * Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is blocked when the permission
+ * ADD_TRUSTED_DISPLAY is denied.
+ */
+ @Test
+ public void testOwnDisplayGroup_withoutAddTrustedDisplayPermission_throwsSecurityException() {
+ DisplayManagerService displayManager =
+ new DisplayManagerService(mContext, mBasicInjector);
+ registerDefaultDisplays(displayManager);
+
+ DisplayManagerService.BinderService bs = displayManager.new BinderService();
+ when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+
+ when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn(
+ PackageManager.PERMISSION_DENIED);
+
+ final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
+ VIRTUAL_DISPLAY_NAME, 600, 800, 320);
+ builder.setFlags(DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP);
+ builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP");
+
+ try {
+ bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
+ null /* projection */, null /* virtualDeviceToken */, PACKAGE_NAME);
+ fail("Creating virtual display with VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP without "
+ + "ADD_TRUSTED_DISPLAY permission should throw SecurityException.");
+ } catch (SecurityException e) {
+ // SecurityException is expected
+ }
+ }
+
+ /**
+ * Tests that specifying VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP is allowed when called with
+ * a virtual device, even if ADD_TRUSTED_DISPLAY is not granted.
+ */
+ @Test
+ public void testOwnDisplayGroup_allowCreationWithVirtualDevice() {
+ DisplayManagerService displayManager =
+ new DisplayManagerService(mContext, mBasicInjector);
+ registerDefaultDisplays(displayManager);
+
+ DisplayManagerService.BinderService bs = displayManager.new BinderService();
+ when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+
+ when(mContext.checkCallingPermission(ADD_TRUSTED_DISPLAY)).thenReturn(
+ PackageManager.PERMISSION_DENIED);
+
+ final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
+ VIRTUAL_DISPLAY_NAME, 600, 800, 320);
+ builder.setFlags(DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP);
+ builder.setUniqueId("uniqueId --- OWN_DISPLAY_GROUP");
+
+ IVirtualDevice virtualDevice = mock(IVirtualDevice.class);
+ when(mMockVirtualDeviceManagerInternal.isValidVirtualDevice(virtualDevice))
+ .thenReturn(true);
+
+ int displayId = bs.createVirtualDisplay(builder.build(), mMockAppToken /* callback */,
+ null /* projection */, virtualDevice /* virtualDeviceToken */, PACKAGE_NAME);
+ displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
+ displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
+ DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId);
+ assertNotNull(ddi);
+ assertNotEquals(0, ddi.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP);
+ }
+
+ /**
* Tests that there is a display change notification if the frame rate override
* list is updated.
*/
diff --git a/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java b/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java
index 2565ae3..0f3742f 100644
--- a/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java
@@ -21,6 +21,7 @@
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
@@ -37,7 +38,9 @@
import androidx.test.InstrumentationRegistry;
import com.android.internal.R;
+import com.android.server.LocalServices;
import com.android.server.display.TestUtils;
+import com.android.server.display.color.ColorDisplayService;
import com.android.server.display.utils.AmbientFilter;
import com.android.server.display.utils.AmbientFilterStubber;
@@ -75,6 +78,7 @@
@Mock private TypedArray mHighLightBiases;
@Mock private TypedArray mAmbientColorTemperatures;
@Mock private TypedArray mDisplayColorTemperatures;
+ @Mock private ColorDisplayService.ColorDisplayServiceInternal mColorDisplayServiceInternalMock;
@Before
public void setUp() throws Exception {
@@ -120,6 +124,18 @@
R.array.config_displayWhiteBalanceHighLightAmbientBiases))
.thenReturn(mHighLightBiases);
mockThrottler();
+ LocalServices.removeServiceForTest(ColorDisplayService.ColorDisplayServiceInternal.class);
+ LocalServices.addService(ColorDisplayService.ColorDisplayServiceInternal.class,
+ mColorDisplayServiceInternalMock);
+ }
+
+ @Test
+ public void testCalculateAdjustedBrightnessNits() {
+ doReturn(0.9f).when(mColorDisplayServiceInternalMock).getDisplayWhiteBalanceLuminance();
+ DisplayWhiteBalanceController controller =
+ DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+ final float adjustedNits = controller.calculateAdjustedBrightnessNits(500f);
+ assertEquals(/* expected= */ 550f, adjustedNits, /* delta= */ 0.001);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java b/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java
new file mode 100644
index 0000000..c59b58d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/power/PowerGroupTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2022 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.server.power;
+
+
+import static android.os.PowerManager.GO_TO_SLEEP_REASON_APPLICATION;
+import static android.os.PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN;
+import static android.os.PowerManager.GO_TO_SLEEP_REASON_TIMEOUT;
+import static android.os.PowerManager.WAKE_REASON_GESTURE;
+import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
+import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
+import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
+import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.verify;
+
+import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for {@link com.android.server.power.PowerGroup}.
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:PowerManagerServiceTest
+ */
+public class PowerGroupTest {
+
+ private static final int GROUP_ID = 0;
+ private static final long TIMESTAMP_CREATE = 1;
+ private static final long TIMESTAMP1 = 999;
+ private static final long TIMESTAMP2 = TIMESTAMP1 + 10;
+ private static final long TIMESTAMP3 = TIMESTAMP2 + 10;
+ private static final int UID = 11;
+
+ private PowerGroup mPowerGroup;
+ @Mock
+ private PowerGroup.PowerGroupListener mWakefulnessCallbackMock;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mPowerGroup = new PowerGroup(GROUP_ID, mWakefulnessCallbackMock, new DisplayPowerRequest(),
+ WAKEFULNESS_AWAKE, /* ready= */ true, /* supportsSandman= */true, TIMESTAMP_CREATE);
+ }
+
+ @Test
+ public void testDreamPowerGroupTriggersOnWakefulnessChangedCallback() {
+ mPowerGroup.dreamLocked(TIMESTAMP1, UID);
+ verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
+ eq(WAKEFULNESS_DREAMING), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_APPLICATION),
+ eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), /* details= */
+ isNull());
+ }
+
+ @Test
+ public void testLastWakeAndSleepTimeIsUpdated() {
+ assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP_CREATE);
+ assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP_CREATE);
+
+ // Verify that the transition to WAKEFULNESS_DOZING updates the last sleep time
+ String details = "PowerGroup1 Timeout";
+ mPowerGroup.setWakefulnessLocked(WAKEFULNESS_DOZING, TIMESTAMP1, UID,
+ GO_TO_SLEEP_REASON_TIMEOUT, /* opUid= */ 0, /* opPackageName= */ null, details);
+ assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP1);
+ assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP_CREATE);
+ assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+ verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
+ eq(WAKEFULNESS_DOZING), eq(TIMESTAMP1), eq(GO_TO_SLEEP_REASON_TIMEOUT),
+ eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), eq(details));
+
+ // Verify that the transition to WAKEFULNESS_ASLEEP after dozing does not update the last
+ // wake or sleep time
+ mPowerGroup.setWakefulnessLocked(WAKEFULNESS_ASLEEP, TIMESTAMP2, UID,
+ GO_TO_SLEEP_REASON_DEVICE_ADMIN, /* opUid= */ 0, /* opPackageName= */ null,
+ details);
+ assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP1);
+ assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP_CREATE);
+ assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
+ eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP2), eq(GO_TO_SLEEP_REASON_DEVICE_ADMIN),
+ eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), eq(details));
+
+ // Verify that waking up the power group only updates the last wake time
+ details = "PowerGroup1 Gesture";
+ mPowerGroup.setWakefulnessLocked(WAKEFULNESS_AWAKE, TIMESTAMP2, UID,
+ WAKE_REASON_GESTURE, /* opUid= */ 0, /* opPackageName= */ null, details);
+ assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP2);
+ assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP1);
+ assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
+ eq(WAKEFULNESS_AWAKE), eq(TIMESTAMP2), eq(WAKE_REASON_GESTURE),
+ eq(UID), /* opUid= */ anyInt(), /* opPackageName= */ isNull(), eq(details));
+
+ // Verify that a transition to WAKEFULNESS_ASLEEP from an interactive state updates the last
+ // sleep time
+ mPowerGroup.setWakefulnessLocked(WAKEFULNESS_ASLEEP, TIMESTAMP3, UID,
+ GO_TO_SLEEP_REASON_DEVICE_ADMIN, /* opUid= */ 0, /* opPackageName= */ null,
+ details);
+ assertThat(mPowerGroup.getLastSleepTimeLocked()).isEqualTo(TIMESTAMP3);
+ assertThat(mPowerGroup.getLastWakeTimeLocked()).isEqualTo(TIMESTAMP2);
+ assertThat(mPowerGroup.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ verify(mWakefulnessCallbackMock).onWakefulnessChangedLocked(eq(GROUP_ID),
+ eq(WAKEFULNESS_ASLEEP), eq(TIMESTAMP3), eq(GO_TO_SLEEP_REASON_DEVICE_ADMIN),
+ eq(UID), /* opUid= */anyInt(), /* opPackageName= */ isNull(), eq(details));
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index c832a3e..d35c679 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -111,6 +111,7 @@
* Build/Install/Run:
* atest FrameworksServicesTests:PowerManagerServiceTest
*/
+@SuppressWarnings("GuardedBy")
public class PowerManagerServiceTest {
private static final String SYSTEM_PROPERTY_QUIESCENT = "ro.boot.quiescent";
private static final String SYSTEM_PROPERTY_REBOOT_REASON = "sys.boot.reason";
@@ -437,7 +438,7 @@
@Test
public void testWakefulnessAwake_InitialValue() {
createService();
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
}
@Test
@@ -445,12 +446,12 @@
createService();
// Start with AWAKE state
startSystem();
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
// Take a nap and verify.
mService.getBinderServiceInstance().goToSleep(mClock.now(),
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
}
@Test
@@ -467,21 +468,21 @@
int flags = PowerManager.FULL_WAKE_LOCK;
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
// Ensure that the flag does *NOT* work with a partial wake lock.
flags = PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
// Verify that flag forces a wakeup when paired to a FULL_WAKE_LOCK
flags = PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
}
@@ -492,7 +493,7 @@
forceSleep();
mService.getBinderServiceInstance().wakeUp(mClock.now(),
PowerManager.WAKE_REASON_UNKNOWN, "testing IPowerManager.wakeUp()", "pkg.name");
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
}
/**
@@ -511,7 +512,7 @@
.thenReturn(false);
mService.readConfigurationLocked();
setPluggedIn(true);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
when(mResourcesSpy.getBoolean(com.android.internal.R.bool.config_unplugTurnsOnScreen))
.thenReturn(true);
mService.readConfigurationLocked();
@@ -526,20 +527,20 @@
when(mWirelessChargerDetectorMock.update(true /* isPowered */,
BatteryManager.BATTERY_PLUGGED_WIRELESS)).thenReturn(false);
setPluggedIn(true);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
// Test 3:
// Do not wake up if the phone is being REMOVED from a wireless charger
when(mBatteryManagerInternalMock.getPlugType()).thenReturn(0);
setPluggedIn(false);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
// Test 4:
// Do not wake if we are dreaming.
forceAwake(); // Needs to be awake first before it can dream.
forceDream();
setPluggedIn(true);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
forceSleep();
// Test 5:
@@ -552,7 +553,7 @@
com.android.internal.R.bool.config_allowTheaterModeWakeFromUnplug))
.thenReturn(false);
setPluggedIn(false);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
Settings.Global.putInt(
mContextSpy.getContentResolver(), Settings.Global.THEATER_MODE_ON, 0);
mUserSwitchedReceiver.onReceive(mContextSpy, new Intent(Intent.ACTION_USER_SWITCHED));
@@ -565,14 +566,14 @@
forceAwake();
forceDozing();
setPluggedIn(true);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
// Test 7:
// Finally, take away all the factors above and ensure the device wakes up!
forceAwake();
forceSleep();
setPluggedIn(false);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
}
@Test
@@ -580,12 +581,12 @@
createService();
// Start with AWAKE state
startSystem();
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
// Take a nap and verify.
mService.getBinderServiceInstance().goToSleep(mClock.now(),
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
}
@Test
@@ -616,12 +617,12 @@
mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
// Verify that we start awake
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
// Grab the wakefulness value when PowerManager finally calls into the
// native component to actually perform the suspend.
when(mNativeWrapperMock.nativeForceSuspend()).then(inv -> {
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
return true;
});
@@ -629,7 +630,7 @@
assertThat(retval).isTrue();
// Still asleep when the function returns.
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
}
@Test
@@ -662,7 +663,7 @@
mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
// Verify that we start awake
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
// Create a wakelock
mService.getBinderServiceInstance().acquireWakeLock(new Binder(), flags, tag, pkg,
@@ -718,7 +719,7 @@
// Start with AWAKE state
startSystem();
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
assertTrue(isAcquired[0]);
// Take a nap and verify we no longer hold the blocker
@@ -728,7 +729,7 @@
when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
mService.getBinderServiceInstance().goToSleep(mClock.now(),
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
assertFalse(isAcquired[0]);
// Override the display state by DreamManager and verify is reacquires the blocker.
@@ -841,9 +842,9 @@
verify(mInattentiveSleepWarningControllerMock, atLeastOnce()).show();
when(mInattentiveSleepWarningControllerMock.isShown()).thenReturn(true);
advanceTime(70);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
forceAwake();
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
verify(mInattentiveSleepWarningControllerMock, atLeastOnce()).dismiss(false);
}
@@ -862,7 +863,7 @@
createService();
startSystem();
advanceTime(20);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
assertThat(mService.getBinderServiceInstance().getLastSleepReason()).isEqualTo(
PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE);
}
@@ -882,9 +883,9 @@
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg,
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
advanceTime(60);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
assertThat(mService.getBinderServiceInstance().getLastSleepReason()).isEqualTo(
PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE);
}
@@ -912,7 +913,7 @@
mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
advanceTime(520);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
assertThat(mService.getBinderServiceInstance().getLastSleepReason()).isEqualTo(
PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE);
}
@@ -934,7 +935,7 @@
PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS);
advanceTime(520);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
assertThat(mService.getBinderServiceInstance().getLastSleepReason()).isEqualTo(
PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE);
}
@@ -955,7 +956,7 @@
PowerManager.USER_ACTIVITY_EVENT_OTHER, 0 /* flags */);
advanceTime(520);
- assertThat(mService.getWakefulnessLocked()).isNotEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isNotEqualTo(WAKEFULNESS_ASLEEP);
}
@Test
@@ -984,14 +985,14 @@
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg,
null /* workSource */, null /* historyTag */, Display.DEFAULT_DISPLAY);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
WAKEFULNESS_AWAKE);
assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
WAKEFULNESS_AWAKE);
advanceTime(15000);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
WAKEFULNESS_AWAKE);
assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
@@ -1024,14 +1025,14 @@
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg,
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
WAKEFULNESS_AWAKE);
assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
WAKEFULNESS_AWAKE);
advanceTime(15000);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
WAKEFULNESS_AWAKE);
assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
@@ -1069,14 +1070,14 @@
WAKEFULNESS_AWAKE);
assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo(
WAKEFULNESS_AWAKE);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
listener.get().onDisplayGroupRemoved(nonDefaultDisplayGroupId);
advanceTime(15000);
assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
WAKEFULNESS_DOZING);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
}
@Test
@@ -1084,7 +1085,7 @@
createService();
startSystem();
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
verify(mNotifierMock, never()).onWakefulnessChangeStarted(anyInt(), anyInt(), anyLong());
}
@@ -1103,7 +1104,7 @@
createService();
startSystem();
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
verify(mNotifierMock).onWakefulnessChangeStarted(eq(WAKEFULNESS_ASLEEP), anyInt(),
anyLong());
}
@@ -1137,7 +1138,7 @@
PowerManager.WAKE_REASON_UNKNOWN, "testing IPowerManager.wakeUp()", "pkg.name");
mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
assertThat(mService.getDesiredScreenPolicyLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
DisplayPowerRequest.POLICY_BRIGHT);
}
@@ -1418,23 +1419,23 @@
startSystem();
listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, 0, 0, 0, 0,
null, null);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
mService.setWakefulnessLocked(nonDefaultDisplayGroupId, WAKEFULNESS_ASLEEP, 0, 0, 0, 0,
null, null);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_AWAKE, 0, 0, 0, 0,
null, null);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
}
@Test
- public void testMultiDisplay_addDisplayGroup_preservesWakefulness() {
+ public void testMultiDisplay_addDisplayGroup_wakesDeviceUp() {
final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
new AtomicReference<>();
@@ -1446,15 +1447,15 @@
createService();
startSystem();
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, 0, 0, 0, 0,
null, null);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
}
@Test
@@ -1471,18 +1472,79 @@
startSystem();
listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, 0, 0, 0, 0,
null, null);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
listener.get().onDisplayGroupRemoved(nonDefaultDisplayGroupId);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_AWAKE, 0, 0, 0, 0,
null, null);
- assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ }
+
+ @Test
+ public void testMultiDisplay_updatesLastGlobalWakeTime() {
+ final int nonDefaultPowerGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
+ final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
+ new AtomicReference<>();
+ long eventTime1 = 10;
+ long eventTime2 = eventTime1 + 1;
+ long eventTime3 = eventTime2 + 1;
+ long eventTime4 = eventTime3 + 1;
+ doAnswer((Answer<Void>) invocation -> {
+ listener.set(invocation.getArgument(0));
+ return null;
+ }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
+
+ createService();
+ startSystem();
+ listener.get().onDisplayGroupAdded(nonDefaultPowerGroupId);
+
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+ mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_DOZING, eventTime1,
+ 0, PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, 0, null, null);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+ mService.setWakefulnessLocked(nonDefaultPowerGroupId, WAKEFULNESS_DOZING, eventTime2,
+ 0, PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+ assertThat(mService.getBinderServiceInstance().getLastSleepReason()).isEqualTo(
+ PowerManager.GO_TO_SLEEP_REASON_APPLICATION);
+
+ mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_AWAKE,
+ eventTime3, /* uid= */ 0, PowerManager.WAKE_REASON_PLUGGED_IN, /* opUid= */
+ 0, /* opPackageName= */ null, /* details= */ null);
+ PowerManager.WakeData wakeData = mService.getLocalServiceInstance().getLastWakeup();
+ assertThat(wakeData.wakeTime).isEqualTo(eventTime3);
+ assertThat(wakeData.wakeReason).isEqualTo(PowerManager.WAKE_REASON_PLUGGED_IN);
+ assertThat(wakeData.sleepDuration).isEqualTo(eventTime3 - eventTime2);
+
+ // The global wake time and reason as well as sleep duration shouldn't change when another
+ // PowerGroup wakes up.
+ mService.setWakefulnessLocked(nonDefaultPowerGroupId, WAKEFULNESS_AWAKE,
+ eventTime4, /* uid= */ 0, PowerManager.WAKE_REASON_CAMERA_LAUNCH, /* opUid= */
+ 0, /* opPackageName= */ null, /* details= */ null);
+ assertThat(wakeData.wakeTime).isEqualTo(eventTime3);
+ assertThat(wakeData.wakeReason).isEqualTo(PowerManager.WAKE_REASON_PLUGGED_IN);
+ assertThat(wakeData.sleepDuration).isEqualTo(eventTime3 - eventTime2);
+ }
+
+ @Test
+ public void testLastSleepTime_notUpdatedWhenDreaming() {
+ createService();
+ startSystem();
+
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ PowerManager.WakeData initialWakeData = mService.getLocalServiceInstance().getLastWakeup();
+
+ forceDream();
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
+ assertThat(mService.getLocalServiceInstance().getLastWakeup()).isEqualTo(initialWakeData);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
index 5dd44ff..020d9f8 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationThreadTest.java
@@ -16,6 +16,9 @@
package com.android.server.vibrator;
+import static android.os.VibrationEffect.VibrationParameter.targetAmplitude;
+import static android.os.VibrationEffect.VibrationParameter.targetFrequency;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -69,6 +72,7 @@
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
+import java.time.Duration;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -525,7 +529,8 @@
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_CLICK, 1f)
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 0.5f)
.addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
- .addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK), /* delay= */ 100)
+ .addOffDuration(Duration.ofMillis(100))
+ .addEffect(VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.compose();
VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
waitForCompletion(thread);
@@ -558,11 +563,12 @@
0.5f /* 100Hz*/, 1 /* 150Hz */, 0.6f /* 200Hz */);
long vibrationId = 1;
- VibrationEffect effect = VibrationEffect.startWaveform()
- .addStep(1, 10)
- .addRamp(0, 20)
- .addStep(0.8f, 100, 30)
- .addRamp(0.6f, 200, 40)
+ VibrationEffect effect = VibrationEffect.startWaveform(targetAmplitude(1))
+ .addSustain(Duration.ofMillis(10))
+ .addTransition(Duration.ofMillis(20), targetAmplitude(0))
+ .addTransition(Duration.ZERO, targetAmplitude(0.8f), targetFrequency(100))
+ .addSustain(Duration.ofMillis(30))
+ .addTransition(Duration.ofMillis(40), targetAmplitude(0.6f), targetFrequency(200))
.build();
VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
waitForCompletion(thread);
@@ -595,11 +601,12 @@
fakeVibrator.setPwleSizeMax(2);
long vibrationId = 1;
- VibrationEffect effect = VibrationEffect.startWaveform()
- .addStep(1, 10)
- .addRamp(0, 20)
- .addStep(0.8f, 10, 30)
- .addRamp(0.6f, 100, 40)
+ VibrationEffect effect = VibrationEffect.startWaveform(targetAmplitude(1))
+ .addSustain(Duration.ofMillis(10))
+ .addTransition(Duration.ofMillis(20), targetAmplitude(0))
+ .addTransition(Duration.ZERO, targetAmplitude(0.8f), targetFrequency(100))
+ .addSustain(Duration.ofMillis(30))
+ .addTransition(Duration.ofMillis(40), targetAmplitude(0.6f), targetFrequency(200))
.build();
VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
waitForCompletion(thread);
@@ -1261,7 +1268,9 @@
fakeVibrator.setPwleSizeMax(2);
long vibrationId = 1;
- VibrationEffect effect = VibrationEffect.startWaveform().addRamp(1, 1).build();
+ VibrationEffect effect = VibrationEffect.startWaveform()
+ .addTransition(Duration.ofMillis(1), targetAmplitude(1))
+ .build();
VibrationThread thread = startThreadAndDispatcher(vibrationId, effect);
waitForCompletion(thread);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index fdc8982..c58bf3b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -340,7 +340,7 @@
doReturn(stack).when(mRootWindowContainer)
.getLaunchRootTask(any(), any(), any(), anyBoolean());
doReturn(stack).when(mRootWindowContainer).getLaunchRootTask(any(), any(), any(), any(),
- anyBoolean(), any(), anyInt(), anyInt(), anyInt());
+ anyBoolean(), any(), anyInt());
}
// Set up mock package manager internal and make sure no unmocked methods are called
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index f4abf88..ee17f52 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -25,7 +25,6 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.Display.TYPE_VIRTUAL;
import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
@@ -935,39 +934,6 @@
assertEquals(infoFake1.activityInfo.name, resolvedInfo.first.name);
}
- /**
- * Test that {@link RootWindowContainer#getLaunchRootTask} with the real caller id will get the
- * expected root task when requesting the activity launch on the secondary display.
- */
- @Test
- public void testGetLaunchRootTaskWithRealCallerId() {
- // Create a non-system owned virtual display.
- final TestDisplayContent secondaryDisplay =
- new TestDisplayContent.Builder(mAtm, 1000, 1500)
- .setType(TYPE_VIRTUAL).setOwnerUid(100).build();
-
- // Create an activity with specify the original launch pid / uid.
- final ActivityRecord r = new ActivityBuilder(mAtm).setLaunchedFromPid(200)
- .setLaunchedFromUid(200).build();
-
- // Simulate ActivityStarter to find a launch root task for requesting the activity to launch
- // on the secondary display with realCallerId.
- final ActivityOptions options = ActivityOptions.makeBasic();
- options.setLaunchDisplayId(secondaryDisplay.mDisplayId);
- options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
- doReturn(true).when(mSupervisor).canPlaceEntityOnDisplay(secondaryDisplay.mDisplayId,
- 300 /* test realCallerPid */, 300 /* test realCallerUid */, r.info);
- final Task result = mRootWindowContainer.getLaunchRootTask(r, options,
- null /* task */, null /* sourceTask */, true /* onTop */, null /* launchParams */,
- 0 /* launchFlags */, 300 /* test realCallerPid */,
- 300 /* test realCallerUid */);
-
- // Assert that the root task is returned as expected.
- assertNotNull(result);
- assertEquals("The display ID of the root task should same as secondary display ",
- secondaryDisplay.mDisplayId, result.getDisplayId());
- }
-
@Test
public void testGetValidLaunchRootTaskOnDisplayWithCandidateRootTask() {
// Create a root task with an activity on secondary display.
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 65b79bf..d0825ba 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -503,6 +503,49 @@
return HAL_MODE_DFP;
}
+ /**
+ * Reset USB port.
+ *
+ * @param portId port identifier.
+ */
+ public boolean resetUsbPort(@NonNull String portId, int transactionId,
+ @NonNull IUsbOperationInternal callback, IndentingPrintWriter pw) {
+ synchronized (mLock) {
+ Objects.requireNonNull(callback);
+ Objects.requireNonNull(portId);
+ final PortInfo portInfo = mPorts.get(portId);
+ if (portInfo == null) {
+ logAndPrint(Log.ERROR, pw, "resetUsbPort: No such port: " + portId
+ + " opId:" + transactionId);
+ try {
+ callback.onOperationComplete(
+ USB_OPERATION_ERROR_PORT_MISMATCH);
+ } catch (RemoteException e) {
+ logAndPrintException(pw,
+ "resetUsbPort: Failed to call OperationComplete. opId:"
+ + transactionId, e);
+ }
+ return false;
+ }
+
+ try {
+ try {
+ return mUsbPortHal.resetUsbPort(portId, transactionId, callback);
+ } catch (Exception e) {
+ logAndPrintException(pw,
+ "reseetUsbPort: Failed to resetUsbPort. opId:"
+ + transactionId , e);
+ callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+ }
+ } catch (RemoteException e) {
+ logAndPrintException(pw,
+ "resetUsbPort: Failed to call onOperationComplete. opId:"
+ + transactionId, e);
+ }
+ return false;
+ }
+ }
+
public void setPortRoles(String portId, int newPowerRole, int newDataRole,
IndentingPrintWriter pw) {
synchronized (mLock) {
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 88ffc7d61..f3308bb 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -680,6 +680,35 @@
}
@Override
+ public boolean resetUsbPort(String portId, int operationId,
+ IUsbOperationInternal callback) {
+ Objects.requireNonNull(portId, "resetUsbPort: portId must not be null. opId:"
+ + operationId);
+ Objects.requireNonNull(callback, "resetUsbPort: callback must not be null. opId:"
+ + operationId);
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+
+ final long ident = Binder.clearCallingIdentity();
+ boolean wait;
+
+ try {
+ if (mPortManager != null) {
+ wait = mPortManager.resetUsbPort(portId, operationId, callback, null);
+ } else {
+ wait = false;
+ try {
+ callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "resetUsbPort: Failed to call onOperationComplete", e);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ return wait;
+ }
+
+ @Override
public List<ParcelableUsbPort> getPorts() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java
index 5582600..f468db3 100644
--- a/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java
+++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortAidl.java
@@ -238,6 +238,50 @@
}
@Override
+ public boolean resetUsbPort(String portName, long operationID,
+ IUsbOperationInternal callback) {
+ Objects.requireNonNull(portName);
+ Objects.requireNonNull(callback);
+ long key = operationID;
+ synchronized (mLock) {
+ try {
+ if (mProxy == null) {
+ logAndPrint(Log.ERROR, mPw,
+ "resetUsbPort: Proxy is null. Retry !opID:"
+ + operationID);
+ callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+ return false;
+ }
+ while (sCallbacks.get(key) != null) {
+ key = ThreadLocalRandom.current().nextInt();
+ }
+ if (key != operationID) {
+ logAndPrint(Log.INFO, mPw, "resetUsbPort: operationID exists ! opID:"
+ + operationID + " key:" + key);
+ }
+ try {
+ sCallbacks.put(operationID, callback);
+ mProxy.resetUsbPort(portName, operationID);
+ } catch (RemoteException e) {
+ logAndPrintException(mPw,
+ "resetUsbPort: Failed to resetUsbPort: portID="
+ + portName + "opId:" + operationID, e);
+ callback.onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+ sCallbacks.remove(key);
+ return false;
+ }
+ } catch (RemoteException e) {
+ logAndPrintException(mPw,
+ "resetUsbPort: Failed to call onOperationComplete portID="
+ + portName + "opID:" + operationID, e);
+ sCallbacks.remove(key);
+ return false;
+ }
+ return true;
+ }
+ }
+
+ @Override
public boolean enableUsbData(String portName, boolean enable, long operationID,
IUsbOperationInternal callback) {
Objects.requireNonNull(portName);
@@ -605,5 +649,27 @@
e);
}
}
+
+ @Override
+ public void notifyResetUsbPortStatus(String portName, int retval,
+ long operationID) {
+ if (retval == Status.SUCCESS) {
+ UsbPortManager.logAndPrint(Log.INFO, mPw, "notifyResetUsbPortStatus:"
+ + portName + ": opID:" + operationID);
+ } else {
+ UsbPortManager.logAndPrint(Log.ERROR, mPw, portName
+ + "notifyEnableUsbDataStatus: opID:"
+ + operationID + " failed. err:" + retval);
+ }
+ try {
+ sCallbacks.get(operationID).onOperationComplete(retval == Status.SUCCESS
+ ? USB_OPERATION_SUCCESS
+ : USB_OPERATION_ERROR_INTERNAL);
+ } catch (RemoteException e) {
+ logAndPrintException(mPw,
+ "notifyResetUsbPortStatus: Failed to call onOperationComplete",
+ e);
+ }
+ }
}
}
diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java
index abfdd6f..4fa296d 100644
--- a/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java
+++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortHal.java
@@ -193,4 +193,18 @@
*/
public void enableLimitPowerTransfer(String portName, boolean limit, long transactionId,
IUsbOperationInternal callback);
+
+ /**
+ * Invoked to reset UsbData on the specified port.
+ *
+ * @param portName Port Identifier.
+ * @param transactionId Used for tracking the current request and is passed down to the HAL
+ * implementation as needed.
+ * @param callback callback object to be invoked to invoke the status of the operation upon
+ * completion.
+ * @param callback callback object to be invoked to invoke the status of the operation upon
+ * completion.
+ */
+ public boolean resetUsbPort(String portName, long transactionId,
+ IUsbOperationInternal callback);
}
diff --git a/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java b/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java
index c1d7635..64e8adc 100644
--- a/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java
+++ b/services/usb/java/com/android/server/usb/hal/port/UsbPortHidl.java
@@ -318,6 +318,19 @@
}
@Override
+ public boolean resetUsbPort(String portName, long transactionId,
+ IUsbOperationInternal callback) {
+ try {
+ callback.onOperationComplete(USB_OPERATION_ERROR_NOT_SUPPORTED);
+ } catch (RemoteException e) {
+ logAndPrintException(mPw, "Failed to call onOperationComplete. opID:"
+ + transactionId
+ + " portId:" + portName, e);
+ }
+ return false;
+ }
+
+ @Override
public boolean enableUsbData(String portName, boolean enable, long transactionId,
IUsbOperationInternal callback) {
int halVersion;
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index e332d3f..ec18c6a 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -380,7 +380,45 @@
*/
public static final int CAPABILITY_CALL_COMPOSER = 0x8000;
- /* NEXT CAPABILITY: 0x10000 */
+ /**
+ * Flag indicating that this {@link PhoneAccount} provides SIM-based voice calls, potentially as
+ * an over-the-top solution such as wi-fi calling.
+ *
+ * <p>Similar to {@link #CAPABILITY_SUPPORTS_VIDEO_CALLING}, this capability indicates this
+ * {@link PhoneAccount} has the ability to make voice calls (but not necessarily at this time).
+ * Whether this {@link PhoneAccount} can make a voice call is ultimately controlled by {@link
+ * #CAPABILITY_VOICE_CALLING_AVAILABLE}, which indicates whether this {@link PhoneAccount} is
+ * currently capable of making a voice call. Consider a case where, for example, a {@link
+ * PhoneAccount} supports making voice calls (e.g. {@link
+ * #CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS}), but a current lack of network connectivity
+ * prevents voice calls from being made (e.g. {@link #CAPABILITY_VOICE_CALLING_AVAILABLE}).
+ *
+ * <p>In order to declare this capability, this {@link PhoneAccount} must also declare {@link
+ * #CAPABILITY_SIM_SUBSCRIPTION} or {@link #CAPABILITY_CONNECTION_MANAGER} and satisfy the
+ * associated requirements.
+ *
+ * @see #CAPABILITY_VOICE_CALLING_AVAILABLE
+ * @see #getCapabilities
+ */
+ public static final int CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS = 0x10000;
+
+ /**
+ * Flag indicating that this {@link PhoneAccount} is <em>currently</em> able to place SIM-based
+ * voice calls, similar to {@link #CAPABILITY_VIDEO_CALLING}.
+ *
+ * <p>See also {@link #CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS}, which indicates whether
+ * the {@code PhoneAccount} supports placing SIM-based voice calls or not.
+ *
+ * <p>In order to declare this capability, this {@link PhoneAccount} must also declare {@link
+ * #CAPABILITY_SIM_SUBSCRIPTION} or {@link #CAPABILITY_CONNECTION_MANAGER} and satisfy the
+ * associated requirements.
+ *
+ * @see #CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS
+ * @see #getCapabilities
+ */
+ public static final int CAPABILITY_VOICE_CALLING_AVAILABLE = 0x20000;
+
+ /* NEXT CAPABILITY: 0x40000 */
/**
* URI scheme for telephone number URIs.
@@ -1102,14 +1140,20 @@
sb.append("SimSub ");
}
if (hasCapabilities(CAPABILITY_RTT)) {
- sb.append("Rtt");
+ sb.append("Rtt ");
}
if (hasCapabilities(CAPABILITY_ADHOC_CONFERENCE_CALLING)) {
- sb.append("AdhocConf");
+ sb.append("AdhocConf ");
}
if (hasCapabilities(CAPABILITY_CALL_COMPOSER)) {
sb.append("CallComposer ");
}
+ if (hasCapabilities(CAPABILITY_SUPPORTS_VOICE_CALLING_INDICATIONS)) {
+ sb.append("SuppVoice ");
+ }
+ if (hasCapabilities(CAPABILITY_VOICE_CALLING_AVAILABLE)) {
+ sb.append("Voice ");
+ }
return sb.toString();
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index d5c846d..7ba4b11 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -5186,6 +5186,20 @@
public static final int E911_RTP_INACTIVITY_ON_CONNECTED = 4;
/**
+ * List of different RAT technologies on which IMS
+ * is supported.
+ *
+ * <p>Possible values are,
+ * {@link AccessNetworkConstants.AccessNetworkType#NGRAN}
+ * {@link AccessNetworkConstants.AccessNetworkType#EUTRAN}
+ * {@link AccessNetworkConstants.AccessNetworkType#IWLAN}
+ * {@link AccessNetworkConstants.AccessNetworkType#UTRAN}
+ * {@link AccessNetworkConstants.AccessNetworkType#GERAN}
+ */
+ public static final String KEY_SUPPORTED_RATS_INT_ARRAY =
+ KEY_PREFIX + "supported_rats_int_array";
+
+ /**
* A bundle which specifies the MMTEL capability and registration technology
* that requires provisioning. If a tuple is not present, the
* framework will not require that the tuple requires provisioning before
@@ -5375,6 +5389,13 @@
new int[] {
GEOLOCATION_PIDF_FOR_EMERGENCY_ON_WIFI
});
+ defaults.putIntArray(
+ KEY_SUPPORTED_RATS_INT_ARRAY,
+ new int[] {
+ AccessNetworkType.NGRAN,
+ AccessNetworkType.EUTRAN,
+ AccessNetworkType.IWLAN
+ });
defaults.putString(KEY_PHONE_CONTEXT_DOMAIN_NAME_STRING, "");
defaults.putString(KEY_IMS_USER_AGENT_STRING,
@@ -5499,6 +5520,44 @@
public static final String KEY_SESSION_REFRESHER_TYPE_INT =
KEY_PREFIX + "session_refresher_type_int";
+
+ /** @hide */
+ @IntDef({
+ SESSION_PRIVACY_TYPE_HEADER,
+ SESSION_PRIVACY_TYPE_NONE,
+ SESSION_PRIVACY_TYPE_ID
+ })
+
+ public @interface SessionPrivacyType {}
+
+ /**
+ * Session privacy type is HEADER as per RFC 3323 Section 4.2.
+ */
+ public static final int SESSION_PRIVACY_TYPE_HEADER = 0;
+
+ /**
+ * Session privacy type is NONE as per RFC 3323 Section 4.2.
+ */
+ public static final int SESSION_PRIVACY_TYPE_NONE = 1;
+
+ /**
+ * Session privacy type is ID as per RFC 3325 Section 9.3.
+ */
+ public static final int SESSION_PRIVACY_TYPE_ID = 2;
+
+ /**
+ * Specify the session privacy type.
+ *
+ * <p>Reference: RFC 3323 Section 4.2, RFC 3325 Section 9.3.
+ *
+ * <p>Possible values are,
+ * {@link #SESSION_PRIVACY_TYPE_HEADER},
+ * {@link #SESSION_PRIVACY_TYPE_NONE},
+ * {@link #SESSION_PRIVACY_TYPE_ID}
+ */
+ public static final String KEY_SESSION_PRIVACY_TYPE_INT =
+ KEY_PREFIX + "session_privacy_type_int";
+
/**
* Flag indicating whether PRACK must be enabled for all 18x messages.
*
@@ -6320,6 +6379,7 @@
defaults.putBoolean(KEY_VOICE_ON_DEFAULT_BEARER_SUPPORTED_BOOL, false);
defaults.putInt(KEY_SESSION_REFRESHER_TYPE_INT, SESSION_REFRESHER_TYPE_UNKNOWN);
+ defaults.putInt(KEY_SESSION_PRIVACY_TYPE_INT, SESSION_PRIVACY_TYPE_HEADER);
defaults.putInt(KEY_SESSION_REFRESH_METHOD_INT,
SESSION_REFRESH_METHOD_UPDATE_PREFERRED);
defaults.putInt(KEY_CONFERENCE_SUBSCRIBE_TYPE_INT,
@@ -6567,22 +6627,6 @@
KEY_PREFIX + "text_rr_bandwidth_bps_int";
/**
- * List of various reasons for RTT call to end due to
- * media inactivity.
- *
- * <p>Possible values are,
- * <UL>
- * <LI>{@link Ims#RTCP_INACTIVITY_ON_HOLD}</LI>
- * <LI>{@link Ims#RTCP_INACTIVITY_ON_CONNECTED}</LI>
- * <LI>{@link Ims#RTP_INACTIVITY_ON_CONNECTED}</LI>
- * <LI>{@link Ims#E911_RTCP_INACTIVITY_ON_CONNECTED}</LI>
- * <LI>{@link Ims#E911_RTP_INACTIVITY_ON_CONNECTED}</LI>
- * </UL>
- */
- public static final String KEY_TEXT_INACTIVITY_CALL_END_REASONS_INT_ARRAY =
- KEY_PREFIX + "text_inactivity_call_end_reasons_int_array";
-
- /**
* Specifies the Text Codec capability.
*
* <p>Possible keys in this bundle are,
@@ -6617,13 +6661,6 @@
defaults.putInt(KEY_TEXT_RS_BANDWIDTH_BPS_INT, 100);
defaults.putInt(KEY_TEXT_RR_BANDWIDTH_BPS_INT, 300);
- defaults.putIntArray(
- KEY_TEXT_INACTIVITY_CALL_END_REASONS_INT_ARRAY,
- new int[] {
- Ims.RTCP_INACTIVITY_ON_CONNECTED,
- Ims.RTP_INACTIVITY_ON_CONNECTED
- });
-
PersistableBundle text_codec_capability_payload_types = new PersistableBundle();
text_codec_capability_payload_types.putInt(
@@ -6707,6 +6744,13 @@
public static final String KEY_EMERGENCY_REGISTRATION_TIMER_MILLIS_INT =
KEY_PREFIX + "emergency_registration_timer_millis_int";
+ /**
+ * This setting will be specify the wait time for refreshing
+ * geolocation information before dialing emergency call.
+ */
+ public static final String KEY_REFRESH_GEOLOCATION_TIMEOUT_MILLIS_INT =
+ KEY_PREFIX + "refresh_geolocation_timeout_millis_int";
+
private static PersistableBundle getDefaults() {
PersistableBundle defaults = new PersistableBundle();
defaults.putBoolean(KEY_RETRY_EMERGENCY_ON_IMS_PDN_BOOL, false);
@@ -6721,6 +6765,7 @@
});
defaults.putInt(KEY_EMERGENCY_REGISTRATION_TIMER_MILLIS_INT, 20000);
+ defaults.putInt(KEY_REFRESH_GEOLOCATION_TIMEOUT_MILLIS_INT, 5000);
return defaults;
}
@@ -7035,6 +7080,17 @@
KEY_PREFIX + "ut_requires_ims_registration_bool";
/**
+ * Flag that controls whether XCAP over UT is supported
+ * when on roaming network.
+ *
+ * <p>If {@code true}: XCAP over UT is supported when on
+ * roaming network.
+ * {@code false} otherwise.
+ */
+ public static final String KEY_UT_SUPPORTED_WHEN_ROAMING_BOOL =
+ KEY_PREFIX + "ut_supported_when_roaming_bool";
+
+ /**
* Flag that controls whether Circuit Switched Fallback (CSFB)
* option is available when XCAP over UT fails.
*
@@ -7385,6 +7441,7 @@
defaults.putBoolean(KEY_USE_CSFB_ON_XCAP_OVER_UT_FAILURE_BOOL, true);
defaults.putBoolean(KEY_UT_SUPPORTED_WHEN_PS_DATA_OFF_BOOL, true);
defaults.putBoolean(KEY_NETWORK_INITIATED_USSD_OVER_IMS_SUPPORTED_BOOL, true);
+ defaults.putBoolean(KEY_UT_SUPPORTED_WHEN_ROAMING_BOOL, true);
defaults.putInt(KEY_UT_IPTYPE_HOME_INT, ApnSetting.PROTOCOL_IPV4V6);
defaults.putInt(KEY_UT_IPTYPE_ROAMING_INT, ApnSetting.PROTOCOL_IPV4V6);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 536517c..edb817e 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -150,7 +150,6 @@
import java.util.stream.Collectors;
import java.util.stream.IntStream;
-
/**
* Provides access to information about the telephony services on
* the device. Applications can use the methods in this class to
@@ -16805,4 +16804,37 @@
}
mTelephonyRegistryMgr.removeCarrierPrivilegesListener(listener);
}
+
+ /**
+ * Sets a voice service state override from telecom based on the current {@link PhoneAccount}s
+ * registered. See {@link PhoneAccount#CAPABILITY_VOICE_CALLING_AVAILABLE}.
+ *
+ * <p>Currently, this API is only called to indicate over-the-top voice calling capability of
+ * the SIM call manager, which will get merged into {@link ServiceState#getState} and propagated
+ * to interested callers via {@link #getServiceState} and {@link
+ * TelephonyCallback.ServiceStateListener}.
+ *
+ * <p>If callers are truly interested in the actual device <-> tower connection status and not
+ * an overall "device can make voice calls" boolean, they can use {@link
+ * ServiceState#getNetworkRegistrationInfo} to check CS registration state.
+ *
+ * <p>TODO(b/215240050) In the future, this API will be removed and replaced with a new superset
+ * API to disentangle the "true" {@link ServiceState} meaning of "this is the connection status
+ * to the tower" from IMS registration state and over-the-top voice calling capabilities.
+ *
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(Manifest.permission.BIND_TELECOM_CONNECTION_SERVICE)
+ public void setVoiceServiceStateOverride(boolean hasService) {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony == null) {
+ throw new IllegalStateException("Telephony service is null");
+ }
+ telephony.setVoiceServiceStateOverride(getSubId(), hasService, getOpPackageName());
+ } catch (RemoteException ex) {
+ ex.rethrowAsRuntimeException();
+ }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index bce7a24..dc96b35 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2543,4 +2543,10 @@
* registration technology specified, false if it is not required.
*/
boolean isRcsProvisioningRequiredForCapability(int subId, int capability, int tech);
+
+ /**
+ * Sets a voice service state from telecom based on the current PhoneAccounts registered. See
+ * PhoneAccount#CAPABILITY_VOICE_CALLING_AVAILABLE.
+ */
+ void setVoiceServiceStateOverride(int subId, boolean hasService, String callingPackage);
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
index 8de38f6..294a220 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
@@ -27,6 +27,7 @@
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import org.junit.Assume.assumeFalse
+import org.junit.Assume.assumeTrue
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -91,6 +92,13 @@
super.statusBarLayerRotatesScales()
}
+ @FlakyTest(bugId = 214452854)
+ @Test
+ fun statusBarLayerRotatesScales_shellTransit() {
+ assumeTrue(isShellTransitionsEnabled)
+ super.statusBarLayerRotatesScales()
+ }
+
/** {@inheritDoc} */
@Presubmit
@Test
@@ -100,6 +108,13 @@
super.launcherLayerReplacesApp()
}
+ @FlakyTest(bugId = 214452854)
+ @Test
+ fun launcherLayerReplacesApp_shellTransit() {
+ assumeTrue(isShellTransitionsEnabled)
+ super.launcherLayerReplacesApp()
+ }
+
/** {@inheritDoc} */
@Presubmit
@Test
@@ -109,6 +124,13 @@
super.entireScreenCovered()
}
+ @FlakyTest(bugId = 214452854)
+ @Test
+ fun entireScreenCovered_shellTransit() {
+ assumeTrue(isShellTransitionsEnabled)
+ super.entireScreenCovered()
+ }
+
companion object {
/**
* Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
index d960e94..519bd56 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
@@ -26,6 +26,7 @@
import com.android.server.wm.flicker.dsl.FlickerBuilder
import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
import org.junit.Assume.assumeFalse
+import org.junit.Assume.assumeTrue
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -90,6 +91,13 @@
super.statusBarLayerRotatesScales()
}
+ @FlakyTest(bugId = 214452854)
+ @Test
+ fun statusBarLayerRotatesScales_shellTransit() {
+ assumeTrue(isShellTransitionsEnabled)
+ super.statusBarLayerRotatesScales()
+ }
+
/** {@inheritDoc} */
@Presubmit
@Test
@@ -99,6 +107,13 @@
super.launcherLayerReplacesApp()
}
+ @FlakyTest(bugId = 214452854)
+ @Test
+ fun launcherLayerReplacesApp_shellTransit() {
+ assumeTrue(isShellTransitionsEnabled)
+ super.launcherLayerReplacesApp()
+ }
+
/** {@inheritDoc} */
@Presubmit
@Test
@@ -108,6 +123,13 @@
super.entireScreenCovered()
}
+ @FlakyTest(bugId = 214452854)
+ @Test
+ fun entireScreenCovered_shellTransit() {
+ assumeTrue(isShellTransitionsEnabled)
+ super.entireScreenCovered()
+ }
+
/** {@inheritDoc} */
@Presubmit
@Test
@@ -117,6 +139,13 @@
super.visibleLayersShownMoreThanOneConsecutiveEntry()
}
+ @FlakyTest(bugId = 214452854)
+ @Test
+ fun visibleLayersShownMoreThanOneConsecutiveEntry_shellTransit() {
+ assumeTrue(isShellTransitionsEnabled)
+ super.visibleLayersShownMoreThanOneConsecutiveEntry()
+ }
+
companion object {
/**
* Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
index 01fce05..42941c2 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
@@ -40,6 +40,7 @@
import com.android.server.wm.traces.common.FlickerComponentName
import com.android.server.wm.traces.common.Rect
import org.junit.Assume
+import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -62,7 +63,7 @@
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@Group1
-class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTestParameter) {
+open class QuickSwitchBetweenTwoAppsForwardTest(private val testSpec: FlickerTestParameter) {
private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
private val testApp1 = SimpleAppHelper(instrumentation)
@@ -85,9 +86,9 @@
?: error("Display not found")
// Swipe right from bottom to quick switch back
- // NOTE: We don't perform an edge-to-edge swipe but instead only swipe in the middle
- // as to not accidentally trigger a swipe back or forward action which would result
- // in the same behavior but not testing quick swap.
+ // NOTE: We don't perform an edge-to-edge swipe but instead only swipe in the
+ // middle as to not accidentally trigger a swipe back or forward action which
+ // would result in the same behavior but not testing quick swap.
device.swipe(
startDisplayBounds.right / 3,
startDisplayBounds.bottom,
@@ -126,15 +127,19 @@
}
}
+ @Before
+ open fun setup() {
+ // This test doesn't work in shell transitions because of b/213867585
+ Assume.assumeFalse(isShellTransitionsEnabled)
+ }
+
/**
* Checks that the transition starts with [testApp1]'s windows filling/covering exactly the
* entirety of the display.
*/
@Presubmit
@Test
- fun startsWithApp1WindowsCoverFullScreen() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun startsWithApp1WindowsCoverFullScreen() {
testSpec.assertWmStart {
this.frameRegion(testApp1.component, FlickerComponentName.LETTERBOX)
.coversExactly(startDisplayBounds)
@@ -147,9 +152,7 @@
*/
@Presubmit
@Test
- fun startsWithApp1LayersCoverFullScreen() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun startsWithApp1LayersCoverFullScreen() {
testSpec.assertLayersStart {
this.visibleRegion(testApp1.component).coversExactly(startDisplayBounds)
}
@@ -160,23 +163,19 @@
*/
@Presubmit
@Test
- fun startsWithApp1WindowBeingOnTop() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun startsWithApp1WindowBeingOnTop() {
testSpec.assertWmStart {
this.isAppWindowOnTop(testApp1.component)
}
}
/**
- * Checks that [testApp2] windows fill the entire screen (i.e. is "fullscreen") at the end of the
- * transition once we have fully quick switched from [testApp1] back to the [testApp2].
+ * Checks that [testApp2] windows fill the entire screen (i.e. is "fullscreen") at the end of
+ * the transition once we have fully quick switched from [testApp1] back to the [testApp2].
*/
@Presubmit
@Test
- fun endsWithApp2WindowsCoveringFullScreen() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun endsWithApp2WindowsCoveringFullScreen() {
testSpec.assertWmEnd {
this.frameRegion(testApp2.component).coversExactly(startDisplayBounds)
}
@@ -188,9 +187,7 @@
*/
@Presubmit
@Test
- fun endsWithApp2LayersCoveringFullScreen() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun endsWithApp2LayersCoveringFullScreen() {
testSpec.assertLayersEnd {
this.visibleRegion(testApp2.component, FlickerComponentName.LETTERBOX)
.coversExactly(startDisplayBounds)
@@ -198,14 +195,12 @@
}
/**
- * Checks that [testApp2] is the top window at the end of the transition once we have fully quick
- * switched from [testApp1] back to the [testApp2].
+ * Checks that [testApp2] is the top window at the end of the transition once we have fully
+ * quick switched from [testApp1] back to the [testApp2].
*/
@Presubmit
@Test
- fun endsWithApp2BeingOnTop() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun endsWithApp2BeingOnTop() {
testSpec.assertWmEnd {
this.isAppWindowOnTop(testApp2.component)
}
@@ -217,9 +212,7 @@
*/
@Presubmit
@Test
- fun app2WindowBecomesAndStaysVisible() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun app2WindowBecomesAndStaysVisible() {
testSpec.assertWm {
this.isAppWindowInvisible(testApp2.component)
.then()
@@ -235,9 +228,7 @@
*/
@Presubmit
@Test
- fun app2LayerBecomesAndStaysVisible() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun app2LayerBecomesAndStaysVisible() {
testSpec.assertLayers {
this.isInvisible(testApp2.component)
.then()
@@ -251,9 +242,7 @@
*/
@Presubmit
@Test
- fun app1WindowBecomesAndStaysInvisible() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun app1WindowBecomesAndStaysInvisible() {
testSpec.assertWm {
this.isAppWindowVisible(testApp1.component)
.then()
@@ -267,9 +256,7 @@
*/
@Presubmit
@Test
- fun app1LayerBecomesAndStaysInvisible() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun app1LayerBecomesAndStaysInvisible() {
testSpec.assertLayers {
this.isVisible(testApp1.component)
.then()
@@ -284,9 +271,7 @@
*/
@Presubmit
@Test
- fun app2WindowIsVisibleOnceApp1WindowIsInvisible() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun app2WindowIsVisibleOnceApp1WindowIsInvisible() {
testSpec.assertWm {
this.isAppWindowVisible(testApp1.component)
.then()
@@ -305,9 +290,7 @@
*/
@Presubmit
@Test
- fun app2LayerIsVisibleOnceApp1LayerIsInvisible() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun app2LayerIsVisibleOnceApp1LayerIsInvisible() {
testSpec.assertLayers {
this.isVisible(testApp1.component)
.then()
@@ -324,9 +307,7 @@
*/
@Presubmit
@Test
- fun navBarWindowIsAlwaysVisible() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun navBarWindowIsAlwaysVisible() {
testSpec.navBarWindowIsVisible()
}
@@ -335,9 +316,7 @@
*/
@Presubmit
@Test
- fun navBarLayerAlwaysIsVisible() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun navBarLayerAlwaysIsVisible() {
testSpec.navBarLayerIsVisible()
}
@@ -348,9 +327,7 @@
*/
@Presubmit
@Test
- fun navbarIsAlwaysInRightPosition() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun navbarIsAlwaysInRightPosition() {
testSpec.navBarLayerRotatesAndScales()
}
@@ -359,9 +336,7 @@
*/
@Presubmit
@Test
- fun statusBarWindowIsAlwaysVisible() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun statusBarWindowIsAlwaysVisible() {
testSpec.statusBarWindowIsVisible()
}
@@ -370,9 +345,7 @@
*/
@Presubmit
@Test
- fun statusBarLayerIsAlwaysVisible() {
- // This test doesn't work in shell transitions because of b/209936664
- Assume.assumeFalse(isShellTransitionsEnabled)
+ open fun statusBarLayerIsAlwaysVisible() {
testSpec.statusBarLayerIsVisible()
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTestShellTransit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTestShellTransit.kt
new file mode 100644
index 0000000..49b9733
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTestShellTransit.kt
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.quickswitch
+
+import android.platform.test.annotations.RequiresDevice
+import androidx.test.filters.FlakyTest
+import com.android.server.wm.flicker.FlickerParametersRunnerFactory
+import com.android.server.wm.flicker.FlickerTestParameter
+import com.android.server.wm.flicker.annotation.Group1
+import com.android.server.wm.flicker.helpers.isShellTransitionsEnabled
+import org.junit.Assume
+import org.junit.Before
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test quick switching back to previous app from last opened app
+ *
+ * To run this test: `atest FlickerTests:QuickSwitchBetweenTwoAppsForwardTestShellTransit`
+ *
+ * Actions:
+ * Launch an app [testApp1]
+ * Launch another app [testApp2]
+ * Swipe right from the bottom of the screen to quick switch back to the first app [testApp1]
+ * Swipe left from the bottom of the screen to quick switch forward to the second app [testApp2]
+ */
+@RequiresDevice
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@Group1
+class QuickSwitchBetweenTwoAppsForwardTestShellTransit(private val testSpec: FlickerTestParameter)
+ : QuickSwitchBetweenTwoAppsForwardTest(testSpec) {
+
+ @Before
+ override fun setup() {
+ // This test class should be removed after b/213867585 is fixed.
+ Assume.assumeTrue(isShellTransitionsEnabled)
+ }
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun startsWithApp1WindowsCoverFullScreen() =
+ super.startsWithApp1WindowsCoverFullScreen()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun startsWithApp1LayersCoverFullScreen() = super.startsWithApp1LayersCoverFullScreen()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun startsWithApp1WindowBeingOnTop() = super.startsWithApp1WindowBeingOnTop()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun endsWithApp2WindowsCoveringFullScreen() =
+ super.endsWithApp2WindowsCoveringFullScreen()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun endsWithApp2LayersCoveringFullScreen() =
+ super.endsWithApp2LayersCoveringFullScreen()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun endsWithApp2BeingOnTop() = super.endsWithApp2BeingOnTop()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun app2WindowBecomesAndStaysVisible() = super.app2WindowBecomesAndStaysVisible()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun app2LayerBecomesAndStaysVisible() = super.app2LayerBecomesAndStaysVisible()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun app1WindowBecomesAndStaysInvisible() = super.app1WindowBecomesAndStaysInvisible()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun app1LayerBecomesAndStaysInvisible() = super.app1LayerBecomesAndStaysInvisible()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun app2WindowIsVisibleOnceApp1WindowIsInvisible() =
+ super.app2WindowIsVisibleOnceApp1WindowIsInvisible()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun app2LayerIsVisibleOnceApp1LayerIsInvisible() =
+ super.app2LayerIsVisibleOnceApp1LayerIsInvisible()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun navBarWindowIsAlwaysVisible() = super.navBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun navBarLayerAlwaysIsVisible() = super.navBarLayerAlwaysIsVisible()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun navbarIsAlwaysInRightPosition() = super.navbarIsAlwaysInRightPosition()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() = super.statusBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 214452854)
+ @Test
+ override fun statusBarLayerIsAlwaysVisible() = super.statusBarLayerIsAlwaysVisible()
+}
\ No newline at end of file