Merge "Move UserWakeupStore initialization to happen before it is used" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 1233fa1..85323c3 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -159,7 +159,6 @@
aconfig_declarations {
name: "com.android.window.flags.window-aconfig",
package: "com.android.window.flags",
- container: "system",
srcs: ["core/java/android/window/flags/*.aconfig"],
}
@@ -173,7 +172,6 @@
aconfig_declarations {
name: "android.hardware.devicestate.feature.flags-aconfig",
package: "android.hardware.devicestate.feature.flags",
- container: "system",
srcs: ["core/java/android/hardware/devicestate/feature/*.aconfig"],
}
@@ -187,7 +185,6 @@
aconfig_declarations {
name: "com.android.hardware.input.input-aconfig",
package: "com.android.hardware.input",
- container: "system",
srcs: ["core/java/android/hardware/input/*.aconfig"],
}
@@ -207,7 +204,6 @@
aconfig_declarations {
name: "com.android.text.flags-aconfig",
package: "com.android.text.flags",
- container: "system",
srcs: ["core/java/android/text/flags/*.aconfig"],
}
@@ -226,7 +222,6 @@
aconfig_declarations {
name: "android.location.flags-aconfig",
package: "android.location.flags",
- container: "system",
srcs: [
"location/java/android/location/flags/*.aconfig",
],
@@ -248,7 +243,6 @@
aconfig_declarations {
name: "android.nfc.flags-aconfig",
package: "android.nfc",
- container: "system",
srcs: ["nfc/java/android/nfc/*.aconfig"],
}
@@ -279,7 +273,6 @@
aconfig_declarations {
name: "android.security.flags-aconfig",
package: "android.security",
- container: "system",
srcs: ["core/java/android/security/*.aconfig"],
}
@@ -300,7 +293,6 @@
aconfig_declarations {
name: "android.app.usage.flags-aconfig",
package: "android.app.usage",
- container: "system",
srcs: ["core/java/android/app/usage/*.aconfig"],
}
@@ -384,7 +376,6 @@
aconfig_declarations {
name: "android.companion.virtualdevice.flags-aconfig",
package: "android.companion.virtualdevice.flags",
- container: "system",
srcs: ["core/java/android/companion/virtual/flags/*.aconfig"],
}
@@ -397,7 +388,6 @@
aconfig_declarations {
name: "android.companion.virtual.flags-aconfig",
package: "android.companion.virtual.flags",
- container: "system",
srcs: ["core/java/android/companion/virtual/*.aconfig"],
}
@@ -405,7 +395,6 @@
aconfig_declarations {
name: "android.view.inputmethod.flags-aconfig",
package: "android.view.inputmethod",
- container: "system",
srcs: ["core/java/android/view/inputmethod/flags.aconfig"],
}
@@ -419,7 +408,6 @@
aconfig_declarations {
name: "android.os.vibrator.flags-aconfig",
package: "android.os.vibrator",
- container: "system",
srcs: ["core/java/android/os/vibrator/*.aconfig"],
}
@@ -433,7 +421,6 @@
aconfig_declarations {
name: "android.view.flags-aconfig",
package: "android.view.flags",
- container: "system",
srcs: ["core/java/android/view/flags/*.aconfig"],
}
@@ -452,7 +439,6 @@
aconfig_declarations {
name: "android.view.accessibility.flags-aconfig",
package: "android.view.accessibility",
- container: "system",
srcs: ["core/java/android/view/accessibility/flags/*.aconfig"],
}
@@ -471,7 +457,6 @@
aconfig_declarations {
name: "android.hardware.flags-aconfig",
package: "android.hardware.flags",
- container: "system",
srcs: ["core/java/android/hardware/flags/*.aconfig"],
}
@@ -485,7 +470,6 @@
aconfig_declarations {
name: "android.widget.flags-aconfig",
package: "android.widget.flags",
- container: "system",
srcs: ["core/java/android/widget/flags/*.aconfig"],
}
@@ -505,7 +489,6 @@
aconfig_declarations {
name: "android.content.pm.flags-aconfig",
package: "android.content.pm",
- container: "system",
srcs: ["core/java/android/content/pm/flags.aconfig"],
}
@@ -526,7 +509,6 @@
aconfig_declarations {
name: "android.content.res.flags-aconfig",
package: "android.content.res",
- container: "system",
srcs: ["core/java/android/content/res/*.aconfig"],
}
@@ -547,7 +529,6 @@
aconfig_declarations {
name: "com.android.media.flags.bettertogether-aconfig",
package: "com.android.media.flags",
- container: "system",
srcs: ["media/java/android/media/flags/media_better_together.aconfig"],
}
@@ -568,7 +549,6 @@
aconfig_declarations {
name: "com.android.media.flags.editing-aconfig",
package: "com.android.media.editing.flags",
- container: "system",
srcs: [
"media/java/android/media/flags/editing.aconfig",
],
@@ -584,7 +564,6 @@
aconfig_declarations {
name: "com.android.media.flags.projection-aconfig",
package: "com.android.media.projection.flags",
- container: "system",
srcs: [
"media/java/android/media/flags/projection.aconfig",
],
@@ -615,7 +594,6 @@
aconfig_declarations {
name: "android.media.tv.flags-aconfig",
package: "android.media.tv.flags",
- container: "system",
srcs: ["media/java/android/media/tv/flags/media_tv.aconfig"],
}
@@ -629,7 +607,6 @@
aconfig_declarations {
name: "android.app.ondeviceintelligence-aconfig",
package: "android.app.ondeviceintelligence.flags",
- container: "system",
srcs: ["core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig"],
}
@@ -643,7 +620,6 @@
aconfig_declarations {
name: "android.permission.flags-aconfig",
package: "android.permission.flags",
- container: "system",
srcs: ["core/java/android/permission/flags.aconfig"],
}
@@ -663,7 +639,6 @@
aconfig_declarations {
name: "android.database.sqlite-aconfig",
package: "android.database.sqlite",
- container: "system",
srcs: ["core/java/android/database/sqlite/*.aconfig"],
}
@@ -683,7 +658,6 @@
aconfig_declarations {
name: "android.hardware.biometrics.flags-aconfig",
package: "android.hardware.biometrics",
- container: "system",
srcs: ["core/java/android/hardware/biometrics/flags.aconfig"],
}
@@ -735,7 +709,6 @@
aconfig_declarations {
name: "android.multiuser.flags-aconfig",
package: "android.multiuser",
- container: "system",
srcs: ["core/java/android/content/pm/multiuser.aconfig"],
}
@@ -749,7 +722,6 @@
aconfig_declarations {
name: "android.app.flags-aconfig",
package: "android.app",
- container: "system",
srcs: ["core/java/android/app/*.aconfig"],
}
@@ -763,7 +735,6 @@
aconfig_declarations {
name: "android.hardware.radio.flags-aconfig",
package: "android.hardware.radio",
- container: "system",
srcs: ["core/java/android/hardware/radio/*.aconfig"],
}
@@ -777,7 +748,6 @@
aconfig_declarations {
name: "android.credentials.flags-aconfig",
package: "android.credentials.flags",
- container: "system",
srcs: ["core/java/android/credentials/flags.aconfig"],
exportable: true,
}
@@ -799,7 +769,6 @@
aconfig_declarations {
name: "android.view.contentprotection.flags-aconfig",
package: "android.view.contentprotection.flags",
- container: "system",
srcs: ["core/java/android/view/contentprotection/flags/*.aconfig"],
}
@@ -813,7 +782,6 @@
aconfig_declarations {
name: "com.android.server.flags.services-aconfig",
package: "com.android.server.flags",
- container: "system",
srcs: ["services/core/java/com/android/server/flags/*.aconfig"],
}
@@ -827,7 +795,6 @@
aconfig_declarations {
name: "android.service.appprediction.flags-aconfig",
package: "android.service.appprediction.flags",
- container: "system",
srcs: ["core/java/android/service/appprediction/flags/*.aconfig"],
}
@@ -841,7 +808,6 @@
aconfig_declarations {
name: "android.service.controls.flags-aconfig",
package: "android.service.controls.flags",
- container: "system",
srcs: ["core/java/android/service/controls/flags/*.aconfig"],
}
@@ -855,7 +821,6 @@
aconfig_declarations {
name: "android.service.voice.flags-aconfig",
package: "android.service.voice.flags",
- container: "system",
srcs: ["core/java/android/service/voice/flags/*.aconfig"],
}
@@ -869,7 +834,6 @@
aconfig_declarations {
name: "android.service.autofill.flags-aconfig",
package: "android.service.autofill",
- container: "system",
srcs: [
"services/autofill/bugfixes.aconfig",
"services/autofill/features.aconfig",
@@ -886,7 +850,6 @@
aconfig_declarations {
name: "android.companion.flags-aconfig",
package: "android.companion",
- container: "system",
srcs: ["core/java/android/companion/*.aconfig"],
}
@@ -900,7 +863,6 @@
aconfig_declarations {
name: "android.net.platform.flags-aconfig",
package: "android.net.platform.flags",
- container: "system",
srcs: ["core/java/android/net/flags.aconfig"],
visibility: [":__subpackages__"],
}
@@ -909,7 +871,6 @@
aconfig_declarations {
name: "com.android.net.thread.platform.flags-aconfig",
package: "com.android.net.thread.platform.flags",
- container: "system",
srcs: ["core/java/android/net/thread/flags.aconfig"],
}
@@ -930,7 +891,6 @@
aconfig_declarations {
name: "android.media.playback.flags-aconfig",
package: "com.android.media.playback.flags",
- container: "system",
srcs: ["media/jni/playback_flags.aconfig"],
}
@@ -949,7 +909,6 @@
aconfig_declarations {
name: "android.net.vcn.flags-aconfig",
package: "android.net.vcn",
- container: "system",
srcs: ["core/java/android/net/vcn/*.aconfig"],
}
@@ -963,7 +922,6 @@
aconfig_declarations {
name: "device_policy_aconfig_flags",
package: "android.app.admin.flags",
- container: "system",
srcs: [
"core/java/android/app/admin/flags/flags.aconfig",
],
@@ -991,7 +949,6 @@
aconfig_declarations {
name: "android.service.chooser.flags-aconfig",
package: "android.service.chooser",
- container: "system",
srcs: ["core/java/android/service/chooser/flags.aconfig"],
}
@@ -1010,7 +967,6 @@
aconfig_declarations {
name: "framework-jobscheduler-job.flags-aconfig",
package: "android.app.job",
- container: "system",
srcs: ["apex/jobscheduler/framework/aconfig/job.aconfig"],
}
@@ -1024,7 +980,6 @@
aconfig_declarations {
name: "android.service.dreams.flags-aconfig",
package: "android.service.dreams",
- container: "system",
srcs: ["core/java/android/service/dreams/flags.aconfig"],
}
@@ -1065,7 +1020,6 @@
aconfig_declarations {
name: "android.app.contextualsearch.flags-aconfig",
package: "android.app.contextualsearch.flags",
- container: "system",
srcs: ["core/java/android/app/contextualsearch/flags.aconfig"],
}
@@ -1079,7 +1033,6 @@
aconfig_declarations {
name: "android.app.smartspace.flags-aconfig",
package: "android.app.smartspace.flags",
- container: "system",
srcs: ["core/java/android/app/smartspace/flags.aconfig"],
}
@@ -1100,7 +1053,6 @@
aconfig_declarations {
name: "android.view.contentcapture.flags-aconfig",
package: "android.view.contentcapture.flags",
- container: "system",
srcs: ["core/java/android/view/contentcapture/flags/*.aconfig"],
}
@@ -1114,7 +1066,6 @@
aconfig_declarations {
name: "android.hardware.usb.flags-aconfig",
package: "android.hardware.usb.flags",
- container: "system",
srcs: ["core/java/android/hardware/usb/flags/*.aconfig"],
}
@@ -1135,7 +1086,6 @@
aconfig_declarations {
name: "android.tracing.flags-aconfig",
package: "android.tracing",
- container: "system",
srcs: ["core/java/android/tracing/flags.aconfig"],
}
@@ -1154,7 +1104,6 @@
aconfig_declarations {
name: "android.appwidget.flags-aconfig",
package: "android.appwidget.flags",
- container: "system",
srcs: ["core/java/android/appwidget/flags.aconfig"],
}
@@ -1168,7 +1117,6 @@
aconfig_declarations {
name: "android.server.app.flags-aconfig",
package: "android.server.app",
- container: "system",
srcs: ["services/core/java/com/android/server/app/flags.aconfig"],
}
@@ -1182,7 +1130,6 @@
aconfig_declarations {
name: "android.webkit.flags-aconfig",
package: "android.webkit",
- container: "system",
srcs: [
"core/java/android/webkit/*.aconfig",
"services/core/java/com/android/server/webkit/*.aconfig",
@@ -1199,7 +1146,6 @@
aconfig_declarations {
name: "android.provider.flags-aconfig",
package: "android.provider",
- container: "system",
srcs: ["core/java/android/provider/*.aconfig"],
}
@@ -1220,7 +1166,6 @@
aconfig_declarations {
name: "android.speech.flags-aconfig",
package: "android.speech.flags",
- container: "system",
srcs: ["core/java/android/speech/flags/*.aconfig"],
}
@@ -1241,7 +1186,6 @@
aconfig_declarations {
name: "android.content.flags-aconfig",
package: "android.content.flags",
- container: "system",
srcs: ["core/java/android/content/flags/flags.aconfig"],
}
@@ -1255,7 +1199,6 @@
aconfig_declarations {
name: "android.adaptiveauth.flags-aconfig",
package: "android.adaptiveauth",
- container: "system",
srcs: ["core/java/android/adaptiveauth/*.aconfig"],
}
@@ -1269,7 +1212,6 @@
aconfig_declarations {
name: "android.crashrecovery.flags-aconfig",
package: "android.crashrecovery.flags",
- container: "system",
srcs: ["packages/CrashRecovery/aconfig/flags.aconfig"],
}
@@ -1290,7 +1232,6 @@
aconfig_declarations {
name: "android.net.wifi.flags-aconfig",
package: "android.net.wifi.flags",
- container: "system",
srcs: ["wifi/*.aconfig"],
}
@@ -1309,7 +1250,6 @@
aconfig_declarations {
name: "android.app.wearable.flags-aconfig",
package: "android.app.wearable",
- container: "system",
srcs: ["core/java/android/app/wearable/*.aconfig"],
}
@@ -1322,7 +1262,6 @@
aconfig_declarations {
name: "com.android.internal.pm.pkg.component.flags-aconfig",
package: "com.android.internal.pm.pkg.component.flags",
- container: "system",
srcs: ["core/java/com/android/internal/pm/pkg/component/flags/flags.aconfig"],
}
@@ -1343,7 +1282,6 @@
aconfig_declarations {
name: "android.systemserver.flags-aconfig",
package: "android.server",
- container: "system",
srcs: ["services/java/com/android/server/flags.aconfig"],
}
diff --git a/apex/jobscheduler/framework/aconfig/job.aconfig b/apex/jobscheduler/framework/aconfig/job.aconfig
index 80db264..2c1a853 100644
--- a/apex/jobscheduler/framework/aconfig/job.aconfig
+++ b/apex/jobscheduler/framework/aconfig/job.aconfig
@@ -1,5 +1,4 @@
package: "android.app.job"
-container: "system"
flag {
name: "enforce_minimum_time_windows"
diff --git a/apex/jobscheduler/service/Android.bp b/apex/jobscheduler/service/Android.bp
index ace56d4..06c7d64 100644
--- a/apex/jobscheduler/service/Android.bp
+++ b/apex/jobscheduler/service/Android.bp
@@ -24,6 +24,7 @@
"app-compat-annotations",
"error_prone_annotations",
"framework",
+ "keepanno-annotations",
"services.core",
"unsupportedappusage",
],
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 19bc716..613678b 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -130,6 +130,8 @@
import com.android.server.LocalServices;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.usage.AppIdleHistory.AppUsageHistory;
+import com.android.tools.r8.keepanno.annotations.KeepItemKind;
+import com.android.tools.r8.keepanno.annotations.UsedByReflection;
import libcore.util.EmptyArray;
@@ -588,6 +590,8 @@
}
}
+ // This constructor is reflectively invoked from framework code in AppStandbyInternal.
+ @UsedByReflection(kind = KeepItemKind.CLASS_AND_METHODS)
public AppStandbyController(Context context) {
this(new Injector(context, AppSchedulingModuleThread.get().getLooper()));
}
diff --git a/apex/jobscheduler/service/jni/Android.bp b/apex/jobscheduler/service/jni/Android.bp
index 34a1fa2..e8acff7 100644
--- a/apex/jobscheduler/service/jni/Android.bp
+++ b/apex/jobscheduler/service/jni/Android.bp
@@ -28,4 +28,8 @@
"liblog",
"libbase",
],
+ visibility: [
+ "//frameworks/base/apex:__subpackages__",
+ "//visibility:any_system_partition",
+ ],
}
diff --git a/cmds/locksettings/TEST_MAPPING b/cmds/locksettings/TEST_MAPPING
index 7a449ef..af54a2d 100644
--- a/cmds/locksettings/TEST_MAPPING
+++ b/cmds/locksettings/TEST_MAPPING
@@ -11,5 +11,10 @@
}
]
}
+ ],
+ "postsubmit": [
+ {
+ "name": "CtsDevicePolicyManagerTestCases_LockSettings_NoFlakes"
+ }
]
}
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 80578e4..3b988e1 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1765,19 +1765,22 @@
public final class InputManager {
method public void addUniqueIdAssociation(@NonNull String, @NonNull String);
method @RequiresPermission(android.Manifest.permission.REMAP_MODIFIER_KEYS) public void clearAllModifierKeyRemappings();
- method @Nullable public String getCurrentKeyboardLayoutForInputDevice(@NonNull android.hardware.input.InputDeviceIdentifier);
- method @NonNull public java.util.List<java.lang.String> getKeyboardLayoutDescriptorsForInputDevice(@NonNull android.view.InputDevice);
+ method @NonNull public java.util.List<java.lang.String> getKeyboardLayoutDescriptors();
method @NonNull public String getKeyboardLayoutTypeForLayoutDescriptor(@NonNull String);
method @NonNull @RequiresPermission(android.Manifest.permission.REMAP_MODIFIER_KEYS) public java.util.Map<java.lang.Integer,java.lang.Integer> getModifierKeyRemapping();
method public int getMousePointerSpeed();
method @RequiresPermission(android.Manifest.permission.REMAP_MODIFIER_KEYS) public void remapModifierKey(int, int);
- method @RequiresPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT) public void removeKeyboardLayoutForInputDevice(@NonNull android.hardware.input.InputDeviceIdentifier, @NonNull String);
method public void removeUniqueIdAssociation(@NonNull String);
- method @RequiresPermission(android.Manifest.permission.SET_KEYBOARD_LAYOUT) public void setCurrentKeyboardLayoutForInputDevice(@NonNull android.hardware.input.InputDeviceIdentifier, @NonNull String);
field public static final long BLOCK_UNTRUSTED_TOUCHES = 158002302L; // 0x96aec7eL
}
public class InputSettings {
+ method @FlaggedApi("com.android.hardware.input.keyboard_a11y_bounce_keys_flag") public static int getAccessibilityBounceKeysThreshold(@NonNull android.content.Context);
+ method @FlaggedApi("com.android.hardware.input.keyboard_a11y_slow_keys_flag") public static int getAccessibilitySlowKeysThreshold(@NonNull android.content.Context);
+ method @FlaggedApi("com.android.hardware.input.keyboard_a11y_sticky_keys_flag") public static boolean isAccessibilityStickyKeysEnabled(@NonNull android.content.Context);
+ method @FlaggedApi("com.android.hardware.input.keyboard_a11y_bounce_keys_flag") @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public static void setAccessibilityBounceKeysThreshold(@NonNull android.content.Context, int);
+ method @FlaggedApi("com.android.hardware.input.keyboard_a11y_slow_keys_flag") @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public static void setAccessibilitySlowKeysThreshold(@NonNull android.content.Context, int);
+ method @FlaggedApi("com.android.hardware.input.keyboard_a11y_sticky_keys_flag") @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS) public static void setAccessibilityStickyKeysEnabled(@NonNull android.content.Context, boolean);
method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static void setMaximumObscuringOpacityForTouch(@NonNull android.content.Context, @FloatRange(from=0, to=1) float);
field public static final int DEFAULT_POINTER_SPEED = 0; // 0x0
}
diff --git a/core/java/android/adaptiveauth/flags.aconfig b/core/java/android/adaptiveauth/flags.aconfig
index b9cf29c..de4e607 100644
--- a/core/java/android/adaptiveauth/flags.aconfig
+++ b/core/java/android/adaptiveauth/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.adaptiveauth"
-container: "system"
flag {
name: "enable_adaptive_auth"
diff --git a/core/java/android/app/activity_manager.aconfig b/core/java/android/app/activity_manager.aconfig
index e4425ca..e751bd2 100644
--- a/core/java/android/app/activity_manager.aconfig
+++ b/core/java/android/app/activity_manager.aconfig
@@ -1,5 +1,4 @@
package: "android.app"
-container: "system"
flag {
namespace: "system_performance"
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index 56fb4aa..fe2f764 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -2,7 +2,6 @@
# proto-message: flag_declarations
package: "android.app.admin.flags"
-container: "system"
flag {
name: "policy_engine_migration_v2_enabled"
diff --git a/core/java/android/app/background_install_control_manager.aconfig b/core/java/android/app/background_install_control_manager.aconfig
index d29c5b5..5f3bb07 100644
--- a/core/java/android/app/background_install_control_manager.aconfig
+++ b/core/java/android/app/background_install_control_manager.aconfig
@@ -1,5 +1,4 @@
package: "android.app"
-container: "system"
flag {
namespace: "preload_safety"
diff --git a/core/java/android/app/contextualsearch/flags.aconfig b/core/java/android/app/contextualsearch/flags.aconfig
index 3385b2b..5ab0762 100644
--- a/core/java/android/app/contextualsearch/flags.aconfig
+++ b/core/java/android/app/contextualsearch/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.app.contextualsearch.flags"
-container: "system"
flag {
name: "enable_service"
diff --git a/core/java/android/app/grammatical_inflection_manager.aconfig b/core/java/android/app/grammatical_inflection_manager.aconfig
index ea494f4..0d7bf65 100644
--- a/core/java/android/app/grammatical_inflection_manager.aconfig
+++ b/core/java/android/app/grammatical_inflection_manager.aconfig
@@ -1,5 +1,4 @@
package: "android.app"
-container: "system"
flag {
name: "system_terms_of_address_enabled"
diff --git a/core/java/android/app/multitasking.aconfig b/core/java/android/app/multitasking.aconfig
index 9a64519..dbf3173 100644
--- a/core/java/android/app/multitasking.aconfig
+++ b/core/java/android/app/multitasking.aconfig
@@ -1,5 +1,4 @@
package: "android.app"
-container: "system"
flag {
name: "enable_pip_ui_state_callback_on_entering"
diff --git a/core/java/android/app/network-policy.aconfig b/core/java/android/app/network-policy.aconfig
index e7b02a7..88f386f 100644
--- a/core/java/android/app/network-policy.aconfig
+++ b/core/java/android/app/network-policy.aconfig
@@ -1,5 +1,4 @@
package: "android.app"
-container: "system"
flag {
namespace: "backstage_power"
diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig
index 0082732..0214d40 100644
--- a/core/java/android/app/notification.aconfig
+++ b/core/java/android/app/notification.aconfig
@@ -1,5 +1,4 @@
package: "android.app"
-container: "system"
flag {
name: "modes_api"
diff --git a/core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig b/core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig
index 8b6441a..dd9210f 100644
--- a/core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig
+++ b/core/java/android/app/ondeviceintelligence/flags/ondevice_intelligence.aconfig
@@ -1,5 +1,4 @@
package: "android.app.ondeviceintelligence.flags"
-container: "system"
flag {
name: "enable_on_device_intelligence"
diff --git a/core/java/android/app/pinner-client.aconfig b/core/java/android/app/pinner-client.aconfig
index 696fd38..0f7fa14 100644
--- a/core/java/android/app/pinner-client.aconfig
+++ b/core/java/android/app/pinner-client.aconfig
@@ -1,5 +1,4 @@
package: "android.app"
-container: "system"
flag {
namespace: "system_performance"
diff --git a/core/java/android/app/smartspace/flags.aconfig b/core/java/android/app/smartspace/flags.aconfig
index df71924..e90ba67 100644
--- a/core/java/android/app/smartspace/flags.aconfig
+++ b/core/java/android/app/smartspace/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.app.smartspace.flags"
-container: "system"
flag {
name: "remote_views"
diff --git a/core/java/android/app/ui_mode_manager.aconfig b/core/java/android/app/ui_mode_manager.aconfig
index 9f44a4d..27a38cc 100644
--- a/core/java/android/app/ui_mode_manager.aconfig
+++ b/core/java/android/app/ui_mode_manager.aconfig
@@ -1,5 +1,4 @@
package: "android.app"
-container: "system"
flag {
namespace: "systemui"
diff --git a/core/java/android/app/usage/flags.aconfig b/core/java/android/app/usage/flags.aconfig
index c7b168a..9a2d2e5 100644
--- a/core/java/android/app/usage/flags.aconfig
+++ b/core/java/android/app/usage/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.app.usage"
-container: "system"
flag {
name: "user_interaction_type_api"
diff --git a/core/java/android/app/wearable/flags.aconfig b/core/java/android/app/wearable/flags.aconfig
index b68bafe..d1d7b5d 100644
--- a/core/java/android/app/wearable/flags.aconfig
+++ b/core/java/android/app/wearable/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.app.wearable"
-container: "system"
flag {
name: "enable_unsupported_operation_status_code"
diff --git a/core/java/android/appwidget/flags.aconfig b/core/java/android/appwidget/flags.aconfig
index 3bcc7c7..4511954 100644
--- a/core/java/android/appwidget/flags.aconfig
+++ b/core/java/android/appwidget/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.appwidget.flags"
-container: "system"
flag {
name: "generated_previews"
diff --git a/core/java/android/companion/flags.aconfig b/core/java/android/companion/flags.aconfig
index 8458857..ecc5e1b 100644
--- a/core/java/android/companion/flags.aconfig
+++ b/core/java/android/companion/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.companion"
-container: "system"
flag {
name: "new_association_builder"
diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig
index 18c81a2..a6a4f5e 100644
--- a/core/java/android/companion/virtual/flags.aconfig
+++ b/core/java/android/companion/virtual/flags.aconfig
@@ -8,7 +8,6 @@
# instead.
package: "android.companion.virtual.flags"
-container: "system"
flag {
name: "enable_native_vdm"
diff --git a/core/java/android/companion/virtual/flags/flags.aconfig b/core/java/android/companion/virtual/flags/flags.aconfig
index 006226e..2904e7c 100644
--- a/core/java/android/companion/virtual/flags/flags.aconfig
+++ b/core/java/android/companion/virtual/flags/flags.aconfig
@@ -14,7 +14,6 @@
# limitations under the License.
package: "android.companion.virtualdevice.flags"
-container: "system"
flag {
namespace: "virtual_devices"
diff --git a/core/java/android/content/flags/flags.aconfig b/core/java/android/content/flags/flags.aconfig
index aac04b3a..27bce5b 100644
--- a/core/java/android/content/flags/flags.aconfig
+++ b/core/java/android/content/flags/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.content.flags"
-container: "system"
flag {
name: "enable_bind_package_isolated_process"
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index 6158917..cde565b 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.content.pm"
-container: "system"
flag {
name: "quarantined_enabled"
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index 0c0da31..4963a4f 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -1,5 +1,4 @@
package: "android.multiuser"
-container: "system"
flag {
name: "save_global_and_guest_restrictions_on_system_user_xml"
diff --git a/core/java/android/content/res/flags.aconfig b/core/java/android/content/res/flags.aconfig
index a475cc8..8f5c912 100644
--- a/core/java/android/content/res/flags.aconfig
+++ b/core/java/android/content/res/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.content.res"
-container: "system"
flag {
name: "default_locale"
diff --git a/core/java/android/credentials/flags.aconfig b/core/java/android/credentials/flags.aconfig
index d243575..d077329 100644
--- a/core/java/android/credentials/flags.aconfig
+++ b/core/java/android/credentials/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.credentials.flags"
-container: "system"
flag {
namespace: "credential_manager"
diff --git a/core/java/android/database/sqlite/flags.aconfig b/core/java/android/database/sqlite/flags.aconfig
index 3073e25..7ecffaf 100644
--- a/core/java/android/database/sqlite/flags.aconfig
+++ b/core/java/android/database/sqlite/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.database.sqlite"
-container: "system"
flag {
name: "sqlite_apis_35"
diff --git a/core/java/android/hardware/biometrics/flags.aconfig b/core/java/android/hardware/biometrics/flags.aconfig
index 4284ad0..9836eec 100644
--- a/core/java/android/hardware/biometrics/flags.aconfig
+++ b/core/java/android/hardware/biometrics/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.hardware.biometrics"
-container: "system"
flag {
name: "last_authentication_time"
diff --git a/core/java/android/hardware/devicestate/feature/flags.aconfig b/core/java/android/hardware/devicestate/feature/flags.aconfig
index 12d3f94..e474603 100644
--- a/core/java/android/hardware/devicestate/feature/flags.aconfig
+++ b/core/java/android/hardware/devicestate/feature/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.hardware.devicestate.feature.flags"
-container: "system"
flag {
name: "device_state_property_api"
diff --git a/core/java/android/hardware/flags/overlayproperties_flags.aconfig b/core/java/android/hardware/flags/overlayproperties_flags.aconfig
index 6c86108..1165e65 100644
--- a/core/java/android/hardware/flags/overlayproperties_flags.aconfig
+++ b/core/java/android/hardware/flags/overlayproperties_flags.aconfig
@@ -1,5 +1,4 @@
package: "android.hardware.flags"
-container: "system"
flag {
name: "overlayproperties_class_api"
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 2816f77..1c37aa2 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -94,33 +94,8 @@
// Keyboard layouts configuration.
KeyboardLayout[] getKeyboardLayouts();
- KeyboardLayout[] getKeyboardLayoutsForInputDevice(in InputDeviceIdentifier identifier);
-
KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor);
- String getCurrentKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier);
-
- @EnforcePermission("SET_KEYBOARD_LAYOUT")
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
- + "android.Manifest.permission.SET_KEYBOARD_LAYOUT)")
- void setCurrentKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier,
- String keyboardLayoutDescriptor);
-
- String[] getEnabledKeyboardLayoutsForInputDevice(in InputDeviceIdentifier identifier);
-
- @EnforcePermission("SET_KEYBOARD_LAYOUT")
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
- + "android.Manifest.permission.SET_KEYBOARD_LAYOUT)")
- void addKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier,
- String keyboardLayoutDescriptor);
-
- @EnforcePermission("SET_KEYBOARD_LAYOUT")
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(value = "
- + "android.Manifest.permission.SET_KEYBOARD_LAYOUT)")
- void removeKeyboardLayoutForInputDevice(in InputDeviceIdentifier identifier,
- String keyboardLayoutDescriptor);
-
- // New Keyboard layout config APIs
KeyboardLayoutSelectionResult getKeyboardLayoutForInputDevice(
in InputDeviceIdentifier identifier, int userId, in InputMethodInfo imeInfo,
in InputMethodSubtype imeSubtype);
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index a1242fb..f949158 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -473,22 +473,21 @@
}
/**
- * Returns the descriptors of all supported keyboard layouts appropriate for the specified
- * input device.
+ * Returns the descriptors of all supported keyboard layouts.
* <p>
* The input manager consults the built-in keyboard layouts as well as all keyboard layouts
* advertised by applications using a {@link #ACTION_QUERY_KEYBOARD_LAYOUTS} broadcast receiver.
* </p>
*
- * @param device The input device to query.
* @return The ids of all keyboard layouts which are supported by the specified input device.
*
* @hide
*/
@TestApi
@NonNull
- public List<String> getKeyboardLayoutDescriptorsForInputDevice(@NonNull InputDevice device) {
- KeyboardLayout[] layouts = getKeyboardLayoutsForInputDevice(device.getIdentifier());
+ @SuppressLint("UnflaggedApi")
+ public List<String> getKeyboardLayoutDescriptors() {
+ KeyboardLayout[] layouts = getKeyboardLayouts();
List<String> res = new ArrayList<>();
for (KeyboardLayout kl : layouts) {
res.add(kl.getDescriptor());
@@ -511,33 +510,18 @@
@TestApi
@NonNull
public String getKeyboardLayoutTypeForLayoutDescriptor(@NonNull String layoutDescriptor) {
- KeyboardLayout[] layouts = getKeyboardLayouts();
- for (KeyboardLayout kl : layouts) {
- if (layoutDescriptor.equals(kl.getDescriptor())) {
- return kl.getLayoutType();
- }
- }
- return "";
+ KeyboardLayout layout = getKeyboardLayout(layoutDescriptor);
+ return layout == null ? "" : layout.getLayoutType();
}
/**
- * Gets information about all supported keyboard layouts appropriate
- * for a specific input device.
- * <p>
- * The input manager consults the built-in keyboard layouts as well
- * as all keyboard layouts advertised by applications using a
- * {@link #ACTION_QUERY_KEYBOARD_LAYOUTS} broadcast receiver.
- * </p>
- *
- * @return A list of all supported keyboard layouts for a specific
- * input device.
- *
+ * TODO(b/330517633): Cleanup the unsupported API
* @hide
*/
@NonNull
public KeyboardLayout[] getKeyboardLayoutsForInputDevice(
@NonNull InputDeviceIdentifier identifier) {
- return mGlobal.getKeyboardLayoutsForInputDevice(identifier);
+ return new KeyboardLayout[0];
}
/**
@@ -549,6 +533,7 @@
*
* @hide
*/
+ @Nullable
public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) {
if (keyboardLayoutDescriptor == null) {
throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null");
@@ -562,121 +547,45 @@
}
/**
- * Gets the current keyboard layout descriptor for the specified input device.
- *
- * @param identifier Identifier for the input device
- * @return The keyboard layout descriptor, or null if no keyboard layout has been set.
- *
+ * TODO(b/330517633): Cleanup the unsupported API
* @hide
*/
- @TestApi
@Nullable
public String getCurrentKeyboardLayoutForInputDevice(
@NonNull InputDeviceIdentifier identifier) {
- try {
- return mIm.getCurrentKeyboardLayoutForInputDevice(identifier);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ return null;
}
/**
- * Sets the current keyboard layout descriptor for the specified input device.
- * <p>
- * This method may have the side-effect of causing the input device in question to be
- * reconfigured.
- * </p>
- *
- * @param identifier The identifier for the input device.
- * @param keyboardLayoutDescriptor The keyboard layout descriptor to use, must not be null.
- *
+ * TODO(b/330517633): Cleanup the unsupported API
* @hide
*/
- @TestApi
- @RequiresPermission(Manifest.permission.SET_KEYBOARD_LAYOUT)
public void setCurrentKeyboardLayoutForInputDevice(@NonNull InputDeviceIdentifier identifier,
- @NonNull String keyboardLayoutDescriptor) {
- mGlobal.setCurrentKeyboardLayoutForInputDevice(identifier,
- keyboardLayoutDescriptor);
- }
+ @NonNull String keyboardLayoutDescriptor) {}
/**
- * Gets all keyboard layout descriptors that are enabled for the specified input device.
- *
- * @param identifier The identifier for the input device.
- * @return The keyboard layout descriptors.
- *
+ * TODO(b/330517633): Cleanup the unsupported API
* @hide
*/
public String[] getEnabledKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) {
- if (identifier == null) {
- throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
- }
-
- try {
- return mIm.getEnabledKeyboardLayoutsForInputDevice(identifier);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ return new String[0];
}
/**
- * Adds the keyboard layout descriptor for the specified input device.
- * <p>
- * This method may have the side-effect of causing the input device in question to be
- * reconfigured.
- * </p>
- *
- * @param identifier The identifier for the input device.
- * @param keyboardLayoutDescriptor The descriptor of the keyboard layout to add.
- *
+ * TODO(b/330517633): Cleanup the unsupported API
* @hide
*/
- @RequiresPermission(Manifest.permission.SET_KEYBOARD_LAYOUT)
public void addKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
String keyboardLayoutDescriptor) {
- if (identifier == null) {
- throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
- }
- if (keyboardLayoutDescriptor == null) {
- throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null");
- }
-
- try {
- mIm.addKeyboardLayoutForInputDevice(identifier, keyboardLayoutDescriptor);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
}
/**
- * Removes the keyboard layout descriptor for the specified input device.
- * <p>
- * This method may have the side-effect of causing the input device in question to be
- * reconfigured.
- * </p>
- *
- * @param identifier The identifier for the input device.
- * @param keyboardLayoutDescriptor The descriptor of the keyboard layout to remove.
- *
+ * TODO(b/330517633): Cleanup the unsupported API
* @hide
*/
- @TestApi
@RequiresPermission(Manifest.permission.SET_KEYBOARD_LAYOUT)
public void removeKeyboardLayoutForInputDevice(@NonNull InputDeviceIdentifier identifier,
@NonNull String keyboardLayoutDescriptor) {
- if (identifier == null) {
- throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
- }
- if (keyboardLayoutDescriptor == null) {
- throw new IllegalArgumentException("keyboardLayoutDescriptor must not be null");
- }
-
- try {
- mIm.removeKeyboardLayoutForInputDevice(identifier, keyboardLayoutDescriptor);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
}
/**
diff --git a/core/java/android/hardware/input/InputManagerGlobal.java b/core/java/android/hardware/input/InputManagerGlobal.java
index 7c104a0..7b29666 100644
--- a/core/java/android/hardware/input/InputManagerGlobal.java
+++ b/core/java/android/hardware/input/InputManagerGlobal.java
@@ -1068,36 +1068,21 @@
}
/**
- * @see InputManager#getKeyboardLayoutsForInputDevice(InputDeviceIdentifier)
+ * TODO(b/330517633): Cleanup the unsupported API
*/
@NonNull
public KeyboardLayout[] getKeyboardLayoutsForInputDevice(
@NonNull InputDeviceIdentifier identifier) {
- try {
- return mIm.getKeyboardLayoutsForInputDevice(identifier);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ return new KeyboardLayout[0];
}
/**
- * @see InputManager#setCurrentKeyboardLayoutForInputDevice
- * (InputDeviceIdentifier, String)
+ * TODO(b/330517633): Cleanup the unsupported API
*/
- @RequiresPermission(Manifest.permission.SET_KEYBOARD_LAYOUT)
public void setCurrentKeyboardLayoutForInputDevice(
@NonNull InputDeviceIdentifier identifier,
- @NonNull String keyboardLayoutDescriptor) {
- Objects.requireNonNull(identifier, "identifier must not be null");
- Objects.requireNonNull(keyboardLayoutDescriptor,
- "keyboardLayoutDescriptor must not be null");
- try {
- mIm.setCurrentKeyboardLayoutForInputDevice(identifier,
- keyboardLayoutDescriptor);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
- }
+ @NonNull String keyboardLayoutDescriptor) {}
+
/**
* @see InputDevice#getSensorManager()
diff --git a/core/java/android/hardware/input/InputSettings.java b/core/java/android/hardware/input/InputSettings.java
index 4328d9f..4c5ebe7 100644
--- a/core/java/android/hardware/input/InputSettings.java
+++ b/core/java/android/hardware/input/InputSettings.java
@@ -16,6 +16,9 @@
package android.hardware.input;
+import static com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_BOUNCE_KEYS_FLAG;
+import static com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_SLOW_KEYS_FLAG;
+import static com.android.hardware.input.Flags.FLAG_KEYBOARD_A11Y_STICKY_KEYS_FLAG;
import static com.android.hardware.input.Flags.keyboardA11yBounceKeysFlag;
import static com.android.hardware.input.Flags.keyboardA11ySlowKeysFlag;
import static com.android.hardware.input.Flags.keyboardA11yStickyKeysFlag;
@@ -23,6 +26,7 @@
import static com.android.input.flags.Flags.enableInputFilterRustImpl;
import android.Manifest;
+import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
@@ -465,6 +469,8 @@
*
* @hide
*/
+ @TestApi
+ @FlaggedApi(FLAG_KEYBOARD_A11Y_BOUNCE_KEYS_FLAG)
public static int getAccessibilityBounceKeysThreshold(@NonNull Context context) {
if (!isAccessibilityBounceKeysFeatureEnabled()) {
return 0;
@@ -487,6 +493,8 @@
*
* @hide
*/
+ @TestApi
+ @FlaggedApi(FLAG_KEYBOARD_A11Y_BOUNCE_KEYS_FLAG)
@RequiresPermission(Manifest.permission.WRITE_SETTINGS)
public static void setAccessibilityBounceKeysThreshold(@NonNull Context context,
int thresholdTimeMillis) {
@@ -545,6 +553,8 @@
*
* @hide
*/
+ @TestApi
+ @FlaggedApi(FLAG_KEYBOARD_A11Y_SLOW_KEYS_FLAG)
public static int getAccessibilitySlowKeysThreshold(@NonNull Context context) {
if (!isAccessibilitySlowKeysFeatureFlagEnabled()) {
return 0;
@@ -567,6 +577,8 @@
*
* @hide
*/
+ @TestApi
+ @FlaggedApi(FLAG_KEYBOARD_A11Y_SLOW_KEYS_FLAG)
@RequiresPermission(Manifest.permission.WRITE_SETTINGS)
public static void setAccessibilitySlowKeysThreshold(@NonNull Context context,
int thresholdTimeMillis) {
@@ -614,6 +626,8 @@
*
* @hide
*/
+ @TestApi
+ @FlaggedApi(FLAG_KEYBOARD_A11Y_STICKY_KEYS_FLAG)
public static boolean isAccessibilityStickyKeysEnabled(@NonNull Context context) {
if (!isAccessibilityStickyKeysFeatureEnabled()) {
return false;
@@ -635,6 +649,8 @@
*
* @hide
*/
+ @TestApi
+ @FlaggedApi(FLAG_KEYBOARD_A11Y_STICKY_KEYS_FLAG)
@RequiresPermission(Manifest.permission.WRITE_SETTINGS)
public static void setAccessibilityStickyKeysEnabled(@NonNull Context context,
boolean enabled) {
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
index ed536ce..9684e64 100644
--- a/core/java/android/hardware/input/input_framework.aconfig
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -1,5 +1,4 @@
package: "com.android.hardware.input"
-container: "system"
# Project link: https://gantry.corp.google.com/projects/android_platform_input_native/changes
diff --git a/core/java/android/hardware/radio/flags.aconfig b/core/java/android/hardware/radio/flags.aconfig
index c9ab62d..d0d10c1 100644
--- a/core/java/android/hardware/radio/flags.aconfig
+++ b/core/java/android/hardware/radio/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.hardware.radio"
-container: "system"
flag {
name: "hd_radio_improved"
diff --git a/core/java/android/hardware/usb/flags/system_sw_usb_flags.aconfig b/core/java/android/hardware/usb/flags/system_sw_usb_flags.aconfig
index 967fc42..fac02ce 100644
--- a/core/java/android/hardware/usb/flags/system_sw_usb_flags.aconfig
+++ b/core/java/android/hardware/usb/flags/system_sw_usb_flags.aconfig
@@ -1,5 +1,4 @@
package: "android.hardware.usb.flags"
-container: "system"
flag {
name: "enable_usb_data_compliance_warning"
diff --git a/core/java/android/hardware/usb/flags/usb_framework_flags.aconfig b/core/java/android/hardware/usb/flags/usb_framework_flags.aconfig
index 94df160..3dd746c 100644
--- a/core/java/android/hardware/usb/flags/usb_framework_flags.aconfig
+++ b/core/java/android/hardware/usb/flags/usb_framework_flags.aconfig
@@ -1,5 +1,4 @@
package: "android.hardware.usb.flags"
-container: "system"
flag {
name: "enable_is_pd_compliant_api"
diff --git a/core/java/android/net/flags.aconfig b/core/java/android/net/flags.aconfig
index 048c50e..3544a69 100644
--- a/core/java/android/net/flags.aconfig
+++ b/core/java/android/net/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.net.platform.flags"
-container: "system"
# This file contains aconfig flags used from platform code
# Flags used for module APIs must be in aconfig files under each modules
diff --git a/core/java/android/net/thread/flags.aconfig b/core/java/android/net/thread/flags.aconfig
index afb982b..ef798ad 100644
--- a/core/java/android/net/thread/flags.aconfig
+++ b/core/java/android/net/thread/flags.aconfig
@@ -1,5 +1,4 @@
package: "com.android.net.thread.platform.flags"
-container: "system"
# This file contains aconfig flags used from platform code
# Flags used for module APIs must be in aconfig files under each modules
diff --git a/core/java/android/net/vcn/flags.aconfig b/core/java/android/net/vcn/flags.aconfig
index 15d671d..e64823a 100644
--- a/core/java/android/net/vcn/flags.aconfig
+++ b/core/java/android/net/vcn/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.net.vcn"
-container: "system"
flag {
name: "safe_mode_config"
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index fd955e2..f26a797 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -1,6 +1,5 @@
package: "android.os"
container: "system"
-container: "system"
flag {
name: "android_os_build_vanilla_ice_cream"
diff --git a/core/java/android/os/storage/ICeStorageLockEventListener.java b/core/java/android/os/storage/ICeStorageLockEventListener.java
new file mode 100644
index 0000000..f16a7fe
--- /dev/null
+++ b/core/java/android/os/storage/ICeStorageLockEventListener.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.storage;
+
+
+/**
+ * Callback class for receiving CE storage lock events from StorageManagerService.
+ * @hide
+ */
+public interface ICeStorageLockEventListener {
+
+ /**
+ * Called when the CE storage corresponding to the userId is locked
+ */
+ void onStorageLocked(int userId);
+}
diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java
index 6995ea8..8ba2fa4 100644
--- a/core/java/android/os/storage/StorageManagerInternal.java
+++ b/core/java/android/os/storage/StorageManagerInternal.java
@@ -16,10 +16,12 @@
package android.os.storage;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.pm.UserInfo;
+import android.multiuser.Flags;
import android.os.IInstalld;
import android.os.IVold;
import android.os.ParcelFileDescriptor;
@@ -201,4 +203,18 @@
*/
public abstract int enableFsverity(IInstalld.IFsveritySetupAuthToken authToken, String filePath,
String packageName) throws IOException;
+
+ /**
+ * Registers a {@link ICeStorageLockEventListener} for receiving CE storage lock events.
+ */
+ @FlaggedApi(Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE)
+ public abstract void registerStorageLockEventListener(
+ @NonNull ICeStorageLockEventListener listener);
+
+ /**
+ * Unregisters the {@link ICeStorageLockEventListener} which was registered previously
+ */
+ @FlaggedApi(Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE)
+ public abstract void unregisterStorageLockEventListener(
+ @NonNull ICeStorageLockEventListener listener);
}
diff --git a/core/java/android/os/vibrator/flags.aconfig b/core/java/android/os/vibrator/flags.aconfig
index eda755c..229d119 100644
--- a/core/java/android/os/vibrator/flags.aconfig
+++ b/core/java/android/os/vibrator/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.os.vibrator"
-container: "system"
flag {
namespace: "haptics"
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index c26f351..ec3c978 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.permission.flags"
-container: "system"
flag {
name: "device_aware_permission_apis_enabled"
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b7d421a..dd93972 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8005,6 +8005,7 @@
*
* @hide
*/
+ @Readable
public static final String ACCESSIBILITY_BOUNCE_KEYS = "accessibility_bounce_keys";
/**
@@ -8016,6 +8017,7 @@
*
* @hide
*/
+ @Readable
public static final String ACCESSIBILITY_SLOW_KEYS = "accessibility_slow_keys";
/**
@@ -8025,6 +8027,7 @@
*
* @hide
*/
+ @Readable
public static final String ACCESSIBILITY_STICKY_KEYS = "accessibility_sticky_keys";
/**
@@ -10977,7 +10980,7 @@
"biometric_debug_enabled";
/**
- * Whether or not virtual sensors are enabled.
+ * Whether or not both fingerprint and face virtual sensors are enabled.
* @hide
*/
@TestApi
@@ -10985,6 +10988,22 @@
public static final String BIOMETRIC_VIRTUAL_ENABLED = "biometric_virtual_enabled";
/**
+ * Whether or not fingerprint virtual sensors are enabled.
+ * @hide
+ */
+ @FlaggedApi("com.android.server.biometrics.face_vhal_feature")
+ public static final String BIOMETRIC_FINGERPRINT_VIRTUAL_ENABLED =
+ "biometric_fingerprint_virtual_enabled";
+
+ /**
+ * Whether or not face virtual sensors are enabled.
+ * @hide
+ */
+ @FlaggedApi("com.android.server.biometrics.face_vhal_feature")
+ public static final String BIOMETRIC_FACE_VIRTUAL_ENABLED =
+ "biometric_face_virtual_enabled";
+
+ /**
* Whether or not biometric is allowed on Keyguard.
* @hide
*/
diff --git a/core/java/android/provider/flags.aconfig b/core/java/android/provider/flags.aconfig
index 77353c2..d0cef83 100644
--- a/core/java/android/provider/flags.aconfig
+++ b/core/java/android/provider/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.provider"
-container: "system"
flag {
name: "a11y_standalone_fab_enabled"
diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig
index 02e787b..7f5b550 100644
--- a/core/java/android/security/flags.aconfig
+++ b/core/java/android/security/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.security"
-container: "system"
flag {
name: "certificate_transparency_configuration"
diff --git a/core/java/android/security/responsible_apis_flags.aconfig b/core/java/android/security/responsible_apis_flags.aconfig
index c7d951b..548f8aa 100644
--- a/core/java/android/security/responsible_apis_flags.aconfig
+++ b/core/java/android/security/responsible_apis_flags.aconfig
@@ -1,5 +1,4 @@
package: "android.security"
-container: "system"
flag {
name: "extend_ecm_to_all_settings"
diff --git a/core/java/android/service/appprediction/flags/flags.aconfig b/core/java/android/service/appprediction/flags/flags.aconfig
index 953bc44..7f9764e 100644
--- a/core/java/android/service/appprediction/flags/flags.aconfig
+++ b/core/java/android/service/appprediction/flags/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.service.appprediction.flags"
-container: "system"
flag {
name: "service_features_api"
diff --git a/core/java/android/service/chooser/flags.aconfig b/core/java/android/service/chooser/flags.aconfig
index d6425c3..a3eff3b 100644
--- a/core/java/android/service/chooser/flags.aconfig
+++ b/core/java/android/service/chooser/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.service.chooser"
-container: "system"
flag {
name: "chooser_album_text"
diff --git a/core/java/android/service/controls/flags/flags.aconfig b/core/java/android/service/controls/flags/flags.aconfig
index 6f3a67d..197f1bc 100644
--- a/core/java/android/service/controls/flags/flags.aconfig
+++ b/core/java/android/service/controls/flags/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.service.controls.flags"
-container: "system"
flag {
name: "home_panel_dream"
diff --git a/core/java/android/service/dreams/flags.aconfig b/core/java/android/service/dreams/flags.aconfig
index 2f45f34..cca4937 100644
--- a/core/java/android/service/dreams/flags.aconfig
+++ b/core/java/android/service/dreams/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.service.dreams"
-container: "system"
flag {
name: "dream_overlay_host"
@@ -11,7 +10,7 @@
flag {
name: "dream_handles_confirm_keys"
- namespace: "dreams"
+ namespace: "communal"
description: "This flag enables dreams processing confirm keys to show the bouncer or dismiss "
"the keyguard"
bug: "326975875"
diff --git a/core/java/android/service/notification/flags.aconfig b/core/java/android/service/notification/flags.aconfig
index b0c55a9..35cd3ed 100644
--- a/core/java/android/service/notification/flags.aconfig
+++ b/core/java/android/service/notification/flags.aconfig
@@ -1,6 +1,5 @@
package: "android.service.notification"
container: "system"
-container: "system"
flag {
name: "ranking_update_ashmem"
diff --git a/core/java/android/service/voice/flags/flags.aconfig b/core/java/android/service/voice/flags/flags.aconfig
index 357cb47..1ae7d8c 100644
--- a/core/java/android/service/voice/flags/flags.aconfig
+++ b/core/java/android/service/voice/flags/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.service.voice.flags"
-container: "system"
flag {
name: "allow_training_data_egress_from_hds"
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 0fc51e7..582c90f 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -27,12 +27,15 @@
import static android.view.View.SYSTEM_UI_FLAG_VISIBLE;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static com.android.window.flags.Flags.FLAG_OFFLOAD_COLOR_EXTRACTION;
import static com.android.window.flags.Flags.noConsecutiveVisibilityEvents;
+import static com.android.window.flags.Flags.offloadColorExtraction;
import android.animation.AnimationHandler;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
+import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.MainThread;
import android.annotation.NonNull;
@@ -832,6 +835,15 @@
}
/**
+ * Called when the dim amount of the wallpaper changed. This can be used to recompute the
+ * wallpaper colors based on the new dim, and call {@link #notifyColorsChanged()}.
+ * @hide
+ */
+ @FlaggedApi(FLAG_OFFLOAD_COLOR_EXTRACTION)
+ public void onDimAmountChanged(float dimAmount) {
+ }
+
+ /**
* Called when an application has changed the desired virtual size of
* the wallpaper.
*/
@@ -1043,6 +1055,10 @@
}
mPreviousWallpaperDimAmount = mWallpaperDimAmount;
+
+ // after the dim changes, allow colors to be immediately recomputed
+ mLastColorInvalidation = 0;
+ if (offloadColorExtraction()) onDimAmountChanged(mWallpaperDimAmount);
}
/**
diff --git a/core/java/android/speech/flags/speech_flags.aconfig b/core/java/android/speech/flags/speech_flags.aconfig
index 2a42357..fa33592 100644
--- a/core/java/android/speech/flags/speech_flags.aconfig
+++ b/core/java/android/speech/flags/speech_flags.aconfig
@@ -1,5 +1,4 @@
package: "android.speech.flags"
-container: "system"
flag {
name: "multilang_extra_launch"
diff --git a/core/java/android/text/flags/flags.aconfig b/core/java/android/text/flags/flags.aconfig
index a8a0c5b..24035af 100644
--- a/core/java/android/text/flags/flags.aconfig
+++ b/core/java/android/text/flags/flags.aconfig
@@ -1,5 +1,4 @@
package: "com.android.text.flags"
-container: "system"
flag {
name: "vendor_custom_locale_fallback"
diff --git a/core/java/android/tracing/flags.aconfig b/core/java/android/tracing/flags.aconfig
index c50c384..1815f14 100644
--- a/core/java/android/tracing/flags.aconfig
+++ b/core/java/android/tracing/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.tracing"
-container: "system"
flag {
name: "perfetto_transition_tracing"
diff --git a/core/java/android/tracing/perfetto/DataSource.java b/core/java/android/tracing/perfetto/DataSource.java
index d0c719b..c33fa7d 100644
--- a/core/java/android/tracing/perfetto/DataSource.java
+++ b/core/java/android/tracing/perfetto/DataSource.java
@@ -20,6 +20,8 @@
import com.android.internal.annotations.VisibleForTesting;
+import dalvik.annotation.optimization.CriticalNative;
+
/**
* Templated base class meant to be derived by embedders to create a custom data
* source.
@@ -71,9 +73,24 @@
* @param fun The tracing lambda that will be called with the tracing contexts of each active
* tracing instance.
*/
- public final void trace(
- TraceFunction<DataSourceInstanceType, TlsStateType, IncrementalStateType> fun) {
- nativeTrace(mNativeObj, fun);
+ public final void trace(TraceFunction<TlsStateType, IncrementalStateType> fun) {
+ boolean startedIterator = nativePerfettoDsTraceIterateBegin(mNativeObj);
+
+ if (!startedIterator) {
+ return;
+ }
+
+ try {
+ do {
+ TracingContext<TlsStateType, IncrementalStateType> ctx =
+ new TracingContext<>(mNativeObj);
+ fun.trace(ctx);
+
+ ctx.flush();
+ } while (nativePerfettoDsTraceIterateNext(mNativeObj));
+ } finally {
+ nativePerfettoDsTraceIterateBreak(mNativeObj);
+ }
}
/**
@@ -154,8 +171,6 @@
long dataSourcePtr, int bufferExhaustedPolicy);
private static native long nativeCreate(DataSource thiz, String name);
- private static native void nativeTrace(
- long nativeDataSourcePointer, TraceFunction traceFunction);
private static native void nativeFlushAll(long nativeDataSourcePointer);
private static native long nativeGetFinalizer();
@@ -163,4 +178,11 @@
long dataSourcePtr, int dsInstanceIdx);
private static native void nativeReleasePerfettoInstanceLocked(
long dataSourcePtr, int dsInstanceIdx);
+
+ @CriticalNative
+ private static native boolean nativePerfettoDsTraceIterateBegin(long dataSourcePtr);
+ @CriticalNative
+ private static native boolean nativePerfettoDsTraceIterateNext(long dataSourcePtr);
+ @CriticalNative
+ private static native void nativePerfettoDsTraceIterateBreak(long dataSourcePtr);
}
diff --git a/core/java/android/tracing/perfetto/TraceFunction.java b/core/java/android/tracing/perfetto/TraceFunction.java
index 62941df..13e663d 100644
--- a/core/java/android/tracing/perfetto/TraceFunction.java
+++ b/core/java/android/tracing/perfetto/TraceFunction.java
@@ -16,19 +16,15 @@
package android.tracing.perfetto;
-import java.io.IOException;
-
/**
* The interface for the trace function called from native on a trace call with a context.
*
- * @param <DataSourceInstanceType> The type of DataSource this tracing context is for.
* @param <TlsStateType> The type of the custom TLS state, if any is used.
* @param <IncrementalStateType> The type of the custom incremental state, if any is used.
*
* @hide
*/
-public interface TraceFunction<DataSourceInstanceType extends DataSourceInstance,
- TlsStateType, IncrementalStateType> {
+public interface TraceFunction<TlsStateType, IncrementalStateType> {
/**
* This function will be called synchronously (i.e., always before trace() returns) only if
@@ -38,6 +34,5 @@
*
* @param ctx the tracing context to trace for in the trace function.
*/
- void trace(TracingContext<DataSourceInstanceType, TlsStateType, IncrementalStateType> ctx)
- throws IOException;
+ void trace(TracingContext<TlsStateType, IncrementalStateType> ctx);
}
diff --git a/core/java/android/tracing/perfetto/TracingContext.java b/core/java/android/tracing/perfetto/TracingContext.java
index c1a61a7..060f964 100644
--- a/core/java/android/tracing/perfetto/TracingContext.java
+++ b/core/java/android/tracing/perfetto/TracingContext.java
@@ -24,26 +24,18 @@
/**
* Argument passed to the lambda function passed to Trace().
*
- * @param <DataSourceInstanceType> The type of the datasource this tracing context is for.
* @param <TlsStateType> The type of the custom TLS state, if any is used.
* @param <IncrementalStateType> The type of the custom incremental state, if any is used.
*
* @hide
*/
-public class TracingContext<DataSourceInstanceType extends DataSourceInstance,
- TlsStateType, IncrementalStateType> {
+public class TracingContext<TlsStateType, IncrementalStateType> {
- private final long mContextPtr;
- private final TlsStateType mTlsState;
- private final IncrementalStateType mIncrementalState;
+ private final long mNativeDsPtr;
private final List<ProtoOutputStream> mTracePackets = new ArrayList<>();
- // Should only be created from the native side.
- private TracingContext(long contextPtr, TlsStateType tlsState,
- IncrementalStateType incrementalState) {
- this.mContextPtr = contextPtr;
- this.mTlsState = tlsState;
- this.mIncrementalState = incrementalState;
+ TracingContext(long nativeDsPtr) {
+ this.mNativeDsPtr = nativeDsPtr;
}
/**
@@ -69,7 +61,7 @@
* Stop timeout expires.
*/
public void flush() {
- nativeFlush(this, mContextPtr);
+ nativeFlush(mNativeDsPtr, getAndClearAllPendingTracePackets());
}
/**
@@ -80,7 +72,7 @@
* @return The TlsState instance for the tracing thread and instance.
*/
public TlsStateType getCustomTlsState() {
- return this.mTlsState;
+ return (TlsStateType) nativeGetCustomTls(mNativeDsPtr);
}
/**
@@ -90,10 +82,9 @@
* @return The current IncrementalState object instance.
*/
public IncrementalStateType getIncrementalState() {
- return this.mIncrementalState;
+ return (IncrementalStateType) nativeGetIncrementalState(mNativeDsPtr);
}
- // Called from native to get trace packets
private byte[][] getAndClearAllPendingTracePackets() {
byte[][] res = new byte[mTracePackets.size()][];
for (int i = 0; i < mTracePackets.size(); i++) {
@@ -105,5 +96,7 @@
return res;
}
- private static native void nativeFlush(TracingContext thiz, long ctxPointer);
+ private static native void nativeFlush(long dataSourcePtr, byte[][] packetData);
+ private static native Object nativeGetCustomTls(long nativeDsPtr);
+ private static native Object nativeGetIncrementalState(long nativeDsPtr);
}
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index b300022..6caf4d6 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -196,11 +196,11 @@
if (!super.setControl(control, showTypes, hideTypes)) {
return false;
}
- final boolean hasLeash = control != null && control.getLeash() != null;
- if (!hasLeash && !mIsRequestedVisibleAwaitingLeash) {
+ if (control == null && !mIsRequestedVisibleAwaitingLeash) {
mController.setRequestedVisibleTypes(0 /* visibleTypes */, getType());
removeSurface();
}
+ final boolean hasLeash = control != null && control.getLeash() != null;
if (hasLeash) {
mIsRequestedVisibleAwaitingLeash = false;
}
diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
index f4aef22..eefc72b 100644
--- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
+++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
@@ -1,5 +1,4 @@
package: "android.view.accessibility"
-container: "system"
# NOTE: Keep alphabetized to help limit merge conflicts from multiple simultaneous editors.
diff --git a/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig b/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig
index 416a877..3c15518 100644
--- a/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig
+++ b/core/java/android/view/contentcapture/flags/content_capture_flags.aconfig
@@ -1,5 +1,4 @@
package: "android.view.contentcapture.flags"
-container: "system"
flag {
name: "run_on_background_thread_enabled"
diff --git a/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig b/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig
index b3bd92b..4de0f29 100644
--- a/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig
+++ b/core/java/android/view/contentprotection/flags/content_protection_flags.aconfig
@@ -1,5 +1,4 @@
package: "android.view.contentprotection.flags"
-container: "system"
flag {
name: "blocklist_update_enabled"
diff --git a/core/java/android/view/flags/refresh_rate_flags.aconfig b/core/java/android/view/flags/refresh_rate_flags.aconfig
index d0fe3e0..1047131 100644
--- a/core/java/android/view/flags/refresh_rate_flags.aconfig
+++ b/core/java/android/view/flags/refresh_rate_flags.aconfig
@@ -1,5 +1,4 @@
package: "android.view.flags"
-container: "system"
flag {
name: "view_velocity_api"
diff --git a/core/java/android/view/flags/scroll_feedback_flags.aconfig b/core/java/android/view/flags/scroll_feedback_flags.aconfig
index 338037f..a7c4104 100644
--- a/core/java/android/view/flags/scroll_feedback_flags.aconfig
+++ b/core/java/android/view/flags/scroll_feedback_flags.aconfig
@@ -1,5 +1,4 @@
package: "android.view.flags"
-container: "system"
flag {
namespace: "toolkit"
diff --git a/core/java/android/view/flags/view_flags.aconfig b/core/java/android/view/flags/view_flags.aconfig
index e8e02ec..c482f8b 100644
--- a/core/java/android/view/flags/view_flags.aconfig
+++ b/core/java/android/view/flags/view_flags.aconfig
@@ -1,5 +1,4 @@
package: "android.view.flags"
-container: "system"
flag {
name: "enable_surface_native_alloc_registration_ro"
diff --git a/core/java/android/view/flags/window_insets.aconfig b/core/java/android/view/flags/window_insets.aconfig
index bedb7d5..bf6df5c 100644
--- a/core/java/android/view/flags/window_insets.aconfig
+++ b/core/java/android/view/flags/window_insets.aconfig
@@ -1,5 +1,4 @@
package: "android.view.flags"
-container: "system"
flag {
name: "customizable_window_headers"
diff --git a/core/java/android/view/inputmethod/flags.aconfig b/core/java/android/view/inputmethod/flags.aconfig
index d79903b..0d19746 100644
--- a/core/java/android/view/inputmethod/flags.aconfig
+++ b/core/java/android/view/inputmethod/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.view.inputmethod"
-container: "system"
flag {
name: "refactor_insets_controller"
diff --git a/core/java/android/webkit/flags.aconfig b/core/java/android/webkit/flags.aconfig
index defe61e..2d834a8 100644
--- a/core/java/android/webkit/flags.aconfig
+++ b/core/java/android/webkit/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.webkit"
-container: "system"
flag {
name: "update_service_ipc_wrapper"
diff --git a/core/java/android/widget/flags/differential_motion_fling_flags.aconfig b/core/java/android/widget/flags/differential_motion_fling_flags.aconfig
index a0a391e..79cfe56 100644
--- a/core/java/android/widget/flags/differential_motion_fling_flags.aconfig
+++ b/core/java/android/widget/flags/differential_motion_fling_flags.aconfig
@@ -1,5 +1,4 @@
package: "android.widget.flags"
-container: "system"
flag {
namespace: "toolkit"
diff --git a/core/java/android/widget/flags/notification_widget_flags.aconfig b/core/java/android/widget/flags/notification_widget_flags.aconfig
index b530e71..e60fa15 100644
--- a/core/java/android/widget/flags/notification_widget_flags.aconfig
+++ b/core/java/android/widget/flags/notification_widget_flags.aconfig
@@ -1,5 +1,4 @@
package: "android.widget.flags"
-container: "system"
flag {
name: "notif_linearlayout_optimized"
diff --git a/core/java/android/window/flags/accessibility.aconfig b/core/java/android/window/flags/accessibility.aconfig
index 733e3db..368c609 100644
--- a/core/java/android/window/flags/accessibility.aconfig
+++ b/core/java/android/window/flags/accessibility.aconfig
@@ -1,5 +1,4 @@
package: "com.android.window.flags"
-container: "system"
flag {
name: "do_not_check_intersection_when_non_magnifiable_window_transitions"
diff --git a/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig b/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig
index 98ff3c6..fa0dab0 100644
--- a/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig
+++ b/core/java/android/window/flags/large_screen_experiences_app_compat.aconfig
@@ -1,5 +1,4 @@
package: "com.android.window.flags"
-container: "system"
flag {
name: "allows_screen_size_decoupled_from_status_bar_and_cutout"
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index efe31ff..9524a6e 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -1,5 +1,4 @@
package: "com.android.window.flags"
-container: "system"
flag {
name: "enable_scaled_resizing"
@@ -36,3 +35,17 @@
description: "Enables a limit on the number of Tasks shown in Desktop Mode"
bug: "332502912"
}
+
+flag {
+ name: "enable_windowing_edge_drag_resize"
+ namespace: "lse_desktop_experience"
+ description: "Enables edge drag resizing for all input sources"
+ bug: "323383067"
+}
+
+flag {
+ name: "enable_desktop_windowing_taskbar_running_apps"
+ namespace: "lse_desktop_experience"
+ description: "Shows running apps in Desktop Mode Taskbar"
+ bug: "332504528"
+}
diff --git a/core/java/android/window/flags/responsible_apis.aconfig b/core/java/android/window/flags/responsible_apis.aconfig
index 33af486..94c72c6 100644
--- a/core/java/android/window/flags/responsible_apis.aconfig
+++ b/core/java/android/window/flags/responsible_apis.aconfig
@@ -1,5 +1,4 @@
package: "com.android.window.flags"
-container: "system"
flag {
name: "bal_require_opt_in_by_pending_intent_creator"
diff --git a/core/java/android/window/flags/wallpaper_manager.aconfig b/core/java/android/window/flags/wallpaper_manager.aconfig
index aa92af2..edf90b5 100644
--- a/core/java/android/window/flags/wallpaper_manager.aconfig
+++ b/core/java/android/window/flags/wallpaper_manager.aconfig
@@ -1,5 +1,4 @@
package: "com.android.window.flags"
-container: "system"
flag {
name: "always_update_wallpaper_permission"
@@ -21,4 +20,14 @@
namespace: "systemui"
description: "Prevent the system from sending consecutive onVisibilityChanged(false) events."
bug: "285631818"
+}
+
+flag {
+ name: "offload_color_extraction"
+ namespace: "systemui"
+ description: "Let ImageWallpaper take care of its wallpaper color extraction, instead of system_server"
+ bug: "328791519"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
\ No newline at end of file
diff --git a/core/java/android/window/flags/window_surfaces.aconfig b/core/java/android/window/flags/window_surfaces.aconfig
index 460df31..5c31048 100644
--- a/core/java/android/window/flags/window_surfaces.aconfig
+++ b/core/java/android/window/flags/window_surfaces.aconfig
@@ -1,5 +1,4 @@
package: "com.android.window.flags"
-container: "system"
# Project link: https://gantry.corp.google.com/projects/android_platform_window_surfaces/changes
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 4d2abb0..e2efff3 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -1,5 +1,4 @@
package: "com.android.window.flags"
-container: "system"
flag {
name: "nav_bar_transparent_by_default"
@@ -141,4 +140,15 @@
description: "Configuration decoupled from insets"
bug: "151861875"
is_fixed_read_only: true
+}
+
+flag {
+ name: "keyguard_appear_transition"
+ namespace: "windowing_frontend"
+ description: "Add transition when keyguard appears"
+ bug: "327970608"
+ is_fixed_read_only: true
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
}
\ No newline at end of file
diff --git a/core/java/android/window/flags/windowing_sdk.aconfig b/core/java/android/window/flags/windowing_sdk.aconfig
index 80265ec..4b3d8e8 100644
--- a/core/java/android/window/flags/windowing_sdk.aconfig
+++ b/core/java/android/window/flags/windowing_sdk.aconfig
@@ -1,5 +1,4 @@
package: "com.android.window.flags"
-container: "system"
# Project link: https://gantry.corp.google.com/projects/android_platform_windowing_sdk/changes
diff --git a/core/java/com/android/internal/pm/pkg/component/flags/flags.aconfig b/core/java/com/android/internal/pm/pkg/component/flags/flags.aconfig
index 89db1cb..ea9abdb 100644
--- a/core/java/com/android/internal/pm/pkg/component/flags/flags.aconfig
+++ b/core/java/com/android/internal/pm/pkg/component/flags/flags.aconfig
@@ -1,5 +1,4 @@
package: "com.android.internal.pm.pkg.component.flags"
-container: "system"
flag {
name: "enable_per_process_use_embedded_dex_attr"
diff --git a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
index 9f3ce81..fca4e91 100644
--- a/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
+++ b/core/java/com/android/internal/protolog/PerfettoProtoLogImpl.java
@@ -53,6 +53,7 @@
import android.tracing.perfetto.Producer;
import android.tracing.perfetto.TracingContext;
import android.util.ArrayMap;
+import android.util.Log;
import android.util.LongArray;
import android.util.Slog;
import android.util.proto.ProtoInputStream;
@@ -67,6 +68,7 @@
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
@@ -166,78 +168,92 @@
}
mDataSource.trace(ctx -> {
- final ProtoOutputStream os = ctx.newTracePacket();
+ try {
+ final ProtoOutputStream os = ctx.newTracePacket();
- os.write(TIMESTAMP, SystemClock.elapsedRealtimeNanos());
+ os.write(TIMESTAMP, SystemClock.elapsedRealtimeNanos());
- final long outProtologViewerConfigToken = os.start(PROTOLOG_VIEWER_CONFIG);
- while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
- if (pis.getFieldNumber() == (int) MESSAGES) {
- final long inMessageToken = pis.start(MESSAGES);
- final long outMessagesToken = os.start(MESSAGES);
-
- while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
- switch (pis.getFieldNumber()) {
- case (int) MessageData.MESSAGE_ID:
- os.write(MessageData.MESSAGE_ID,
- pis.readLong(MessageData.MESSAGE_ID));
- break;
- case (int) MESSAGE:
- os.write(MESSAGE, pis.readString(MESSAGE));
- break;
- case (int) LEVEL:
- os.write(LEVEL, pis.readInt(LEVEL));
- break;
- case (int) GROUP_ID:
- os.write(GROUP_ID, pis.readInt(GROUP_ID));
- break;
- default:
- throw new RuntimeException(
- "Unexpected field id " + pis.getFieldNumber());
- }
+ final long outProtologViewerConfigToken = os.start(PROTOLOG_VIEWER_CONFIG);
+ while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+ if (pis.getFieldNumber() == (int) MESSAGES) {
+ writeViewerConfigMessage(pis, os);
}
- pis.end(inMessageToken);
- os.end(outMessagesToken);
- }
-
- if (pis.getFieldNumber() == (int) GROUPS) {
- final long inGroupToken = pis.start(GROUPS);
- final long outGroupToken = os.start(GROUPS);
-
- while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
- switch (pis.getFieldNumber()) {
- case (int) ID:
- int id = pis.readInt(ID);
- os.write(ID, id);
- break;
- case (int) NAME:
- String name = pis.readString(NAME);
- os.write(NAME, name);
- break;
- case (int) TAG:
- String tag = pis.readString(TAG);
- os.write(TAG, tag);
- break;
- default:
- throw new RuntimeException(
- "Unexpected field id " + pis.getFieldNumber());
- }
+ if (pis.getFieldNumber() == (int) GROUPS) {
+ writeViewerConfigGroup(pis, os);
}
-
- pis.end(inGroupToken);
- os.end(outGroupToken);
}
+
+ os.end(outProtologViewerConfigToken);
+
+ ctx.flush();
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "Failed to read ProtoLog viewer config to dump on tracing end", e);
}
-
- os.end(outProtologViewerConfigToken);
-
- ctx.flush();
});
mDataSource.flush();
}
+ private static void writeViewerConfigGroup(
+ ProtoInputStream pis, ProtoOutputStream os) throws IOException {
+ final long inGroupToken = pis.start(GROUPS);
+ final long outGroupToken = os.start(GROUPS);
+
+ while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+ switch (pis.getFieldNumber()) {
+ case (int) ID:
+ int id = pis.readInt(ID);
+ os.write(ID, id);
+ break;
+ case (int) NAME:
+ String name = pis.readString(NAME);
+ os.write(NAME, name);
+ break;
+ case (int) TAG:
+ String tag = pis.readString(TAG);
+ os.write(TAG, tag);
+ break;
+ default:
+ throw new RuntimeException(
+ "Unexpected field id " + pis.getFieldNumber());
+ }
+ }
+
+ pis.end(inGroupToken);
+ os.end(outGroupToken);
+ }
+
+ private static void writeViewerConfigMessage(
+ ProtoInputStream pis, ProtoOutputStream os) throws IOException {
+ final long inMessageToken = pis.start(MESSAGES);
+ final long outMessagesToken = os.start(MESSAGES);
+
+ while (pis.nextField() != ProtoInputStream.NO_MORE_FIELDS) {
+ switch (pis.getFieldNumber()) {
+ case (int) MessageData.MESSAGE_ID:
+ os.write(MessageData.MESSAGE_ID,
+ pis.readLong(MessageData.MESSAGE_ID));
+ break;
+ case (int) MESSAGE:
+ os.write(MESSAGE, pis.readString(MESSAGE));
+ break;
+ case (int) LEVEL:
+ os.write(LEVEL, pis.readInt(LEVEL));
+ break;
+ case (int) GROUP_ID:
+ os.write(GROUP_ID, pis.readInt(GROUP_ID));
+ break;
+ default:
+ throw new RuntimeException(
+ "Unexpected field id " + pis.getFieldNumber());
+ }
+ }
+
+ pis.end(inMessageToken);
+ os.end(outMessagesToken);
+ }
+
private void logToLogcat(String tag, LogLevel level, long messageHash,
@Nullable String messageString, Object[] args) {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "logToLogcat");
@@ -423,7 +439,7 @@
return sw.toString();
}
- private int internStacktraceString(TracingContext<ProtoLogDataSource.Instance,
+ private int internStacktraceString(TracingContext<
ProtoLogDataSource.TlsState,
ProtoLogDataSource.IncrementalState> ctx,
String stacktrace) {
@@ -433,9 +449,7 @@
}
private int internStringArg(
- TracingContext<ProtoLogDataSource.Instance,
- ProtoLogDataSource.TlsState,
- ProtoLogDataSource.IncrementalState> ctx,
+ TracingContext<ProtoLogDataSource.TlsState, ProtoLogDataSource.IncrementalState> ctx,
String string
) {
final ProtoLogDataSource.IncrementalState incrementalState = ctx.getIncrementalState();
@@ -444,9 +458,7 @@
}
private int internString(
- TracingContext<ProtoLogDataSource.Instance,
- ProtoLogDataSource.TlsState,
- ProtoLogDataSource.IncrementalState> ctx,
+ TracingContext<ProtoLogDataSource.TlsState, ProtoLogDataSource.IncrementalState> ctx,
Map<String, Integer> internMap,
long fieldId,
String string
diff --git a/core/jni/android_tracing_PerfettoDataSource.cpp b/core/jni/android_tracing_PerfettoDataSource.cpp
index 25ff853..5c7b470 100644
--- a/core/jni/android_tracing_PerfettoDataSource.cpp
+++ b/core/jni/android_tracing_PerfettoDataSource.cpp
@@ -45,12 +45,6 @@
static struct {
jclass clazz;
jmethodID init;
- jmethodID getAndClearAllPendingTracePackets;
-} gTracingContextClassInfo;
-
-static struct {
- jclass clazz;
- jmethodID init;
} gCreateTlsStateArgsClassInfo;
static struct {
@@ -68,32 +62,10 @@
jobject jobj;
};
-static void traceAllPendingPackets(JNIEnv* env, jobject jCtx, PerfettoDsTracerIterator* ctx) {
- jobjectArray packets =
- (jobjectArray)env
- ->CallObjectMethod(jCtx,
- gTracingContextClassInfo.getAndClearAllPendingTracePackets);
- if (env->ExceptionOccurred()) {
- env->ExceptionDescribe();
- env->ExceptionClear();
-
- LOG_ALWAYS_FATAL("Failed to call java context finalize method");
- }
-
- int packets_count = env->GetArrayLength(packets);
- for (int i = 0; i < packets_count; i++) {
- jbyteArray packet_proto_buffer = (jbyteArray)env->GetObjectArrayElement(packets, i);
-
- jbyte* raw_proto_buffer = env->GetByteArrayElements(packet_proto_buffer, 0);
- int buffer_size = env->GetArrayLength(packet_proto_buffer);
-
- struct PerfettoDsRootTracePacket trace_packet;
- PerfettoDsTracerPacketBegin(ctx, &trace_packet);
- PerfettoPbMsgAppendBytes(&trace_packet.msg.msg, (const uint8_t*)raw_proto_buffer,
- buffer_size);
- PerfettoDsTracerPacketEnd(ctx, &trace_packet);
- }
-}
+// In a single thread there can be only one trace point active across all data source, so we can use
+// a single global thread_local variable to keep track of the active tracer iterator.
+thread_local static bool gInIteration;
+thread_local static struct PerfettoDsTracerIterator gIterator;
PerfettoDataSource::PerfettoDataSource(JNIEnv* env, jobject javaDataSource,
std::string dataSourceName)
@@ -164,44 +136,89 @@
return env->NewGlobalRef(incrementalState.get());
}
-void PerfettoDataSource::trace(JNIEnv* env, jobject traceFunction) {
- PERFETTO_DS_TRACE(dataSource, ctx) {
- ALOG(LOG_DEBUG, LOG_TAG, "\tin native trace callback function %p", this);
- TlsState* tls_state =
- reinterpret_cast<TlsState*>(PerfettoDsGetCustomTls(&dataSource, &ctx));
- IncrementalState* incr_state = reinterpret_cast<IncrementalState*>(
- PerfettoDsGetIncrementalState(&dataSource, &ctx));
+bool PerfettoDataSource::TraceIterateBegin() {
+ if (gInIteration) {
+ return false;
+ }
- ALOG(LOG_DEBUG, LOG_TAG, "\t tls_state = %p", tls_state);
- ALOG(LOG_DEBUG, LOG_TAG, "\t incr_state = %p", incr_state);
+ gIterator = PerfettoDsTraceIterateBegin(&dataSource);
- ALOG(LOG_DEBUG, LOG_TAG, "\t tls_state->jobj = %p", tls_state->jobj);
- ALOG(LOG_DEBUG, LOG_TAG, "\t incr_state->jobj = %p", incr_state->jobj);
+ if (gIterator.impl.tracer == nullptr) {
+ return false;
+ }
- ScopedLocalRef<jobject> jCtx(env,
- env->NewObject(gTracingContextClassInfo.clazz,
- gTracingContextClassInfo.init, &ctx,
- tls_state->jobj, incr_state->jobj));
+ gInIteration = true;
+ return true;
+}
- ALOG(LOG_DEBUG, LOG_TAG, "\t jCtx = %p", jCtx.get());
+bool PerfettoDataSource::TraceIterateNext() {
+ if (!gInIteration) {
+ LOG_ALWAYS_FATAL("Tried calling TraceIterateNext outside of a tracer iteration.");
+ return false;
+ }
- jclass objclass = env->GetObjectClass(traceFunction);
- jmethodID method =
- env->GetMethodID(objclass, "trace", "(Landroid/tracing/perfetto/TracingContext;)V");
- if (method == 0) {
- LOG_ALWAYS_FATAL("Failed to get method id");
- }
+ PerfettoDsTraceIterateNext(&dataSource, &gIterator);
- env->ExceptionClear();
+ if (gIterator.impl.tracer == nullptr) {
+ // Reached end of iterator. No more datasource instances.
+ gInIteration = false;
+ return false;
+ }
- env->CallVoidMethod(traceFunction, method, jCtx.get());
- if (env->ExceptionOccurred()) {
- env->ExceptionDescribe();
- env->ExceptionClear();
- LOG_ALWAYS_FATAL("Failed to call java trace method");
- }
+ return true;
+}
- traceAllPendingPackets(env, jCtx.get(), &ctx);
+void PerfettoDataSource::TraceIterateBreak() {
+ if (!gInIteration) {
+ return;
+ }
+
+ PerfettoDsTraceIterateBreak(&dataSource, &gIterator);
+ gInIteration = false;
+}
+
+jobject PerfettoDataSource::GetCustomTls() {
+ if (!gInIteration) {
+ LOG_ALWAYS_FATAL("Tried getting CustomTls outside of a tracer iteration.");
+ return nullptr;
+ }
+
+ TlsState* tls_state =
+ reinterpret_cast<TlsState*>(PerfettoDsGetCustomTls(&dataSource, &gIterator));
+
+ return tls_state->jobj;
+}
+
+jobject PerfettoDataSource::GetIncrementalState() {
+ if (!gInIteration) {
+ LOG_ALWAYS_FATAL("Tried getting IncrementalState outside of a tracer iteration.");
+ return nullptr;
+ }
+
+ IncrementalState* incr_state = reinterpret_cast<IncrementalState*>(
+ PerfettoDsGetIncrementalState(&dataSource, &gIterator));
+
+ return incr_state->jobj;
+}
+
+void PerfettoDataSource::WritePackets(JNIEnv* env, jobjectArray packets) {
+ if (!gInIteration) {
+ LOG_ALWAYS_FATAL("Tried writing packets outside of a tracer iteration.");
+ return;
+ }
+
+ int packets_count = env->GetArrayLength(packets);
+ for (int i = 0; i < packets_count; i++) {
+ jbyteArray packet_proto_buffer = (jbyteArray)env->GetObjectArrayElement(packets, i);
+
+ jbyte* raw_proto_buffer = env->GetByteArrayElements(packet_proto_buffer, 0);
+ int buffer_size = env->GetArrayLength(packet_proto_buffer);
+
+ struct PerfettoDsRootTracePacket trace_packet;
+ PerfettoDsTracerPacketBegin(&gIterator, &trace_packet);
+ PerfettoPbMsgAppendBytes(&trace_packet.msg.msg, (const uint8_t*)raw_proto_buffer,
+ buffer_size);
+ PerfettoDsTracerPacketEnd(&gIterator, &trace_packet);
}
}
@@ -218,9 +235,7 @@
jlong nativeCreate(JNIEnv* env, jclass clazz, jobject javaDataSource, jstring name) {
const char* nativeString = env->GetStringUTFChars(name, 0);
- ALOG(LOG_DEBUG, LOG_TAG, "nativeCreate(%p, %s)", javaDataSource, nativeString);
PerfettoDataSource* dataSource = new PerfettoDataSource(env, javaDataSource, nativeString);
- ALOG(LOG_DEBUG, LOG_TAG, "\tdatasource* = %p", dataSource);
env->ReleaseStringUTFChars(name, nativeString);
dataSource->incStrong((void*)nativeCreate);
@@ -229,39 +244,27 @@
}
void nativeDestroy(void* ptr) {
- ALOG(LOG_DEBUG, LOG_TAG, "nativeCreate(%p)", ptr);
PerfettoDataSource* dataSource = reinterpret_cast<PerfettoDataSource*>(ptr);
dataSource->decStrong((void*)nativeCreate);
}
static jlong nativeGetFinalizer(JNIEnv* /* env */, jclass /* clazz */) {
- ALOG(LOG_DEBUG, LOG_TAG, "nativeGetFinalizer()");
return static_cast<jlong>(reinterpret_cast<uintptr_t>(&nativeDestroy));
}
-void nativeTrace(JNIEnv* env, jclass clazz, jlong dataSourcePtr, jobject traceFunctionInterface) {
- ALOG(LOG_DEBUG, LOG_TAG, "nativeTrace(%p)", (void*)dataSourcePtr);
- sp<PerfettoDataSource> datasource = reinterpret_cast<PerfettoDataSource*>(dataSourcePtr);
-
- datasource->trace(env, traceFunctionInterface);
-}
-
-void nativeFlush(JNIEnv* env, jclass clazz, jobject jCtx, jlong ctxPtr) {
- ALOG(LOG_DEBUG, LOG_TAG, "nativeFlush(%p, %p)", jCtx, (void*)ctxPtr);
- auto* ctx = reinterpret_cast<struct PerfettoDsTracerIterator*>(ctxPtr);
- traceAllPendingPackets(env, jCtx, ctx);
- PerfettoDsTracerFlush(ctx, nullptr, nullptr);
+void nativeFlush(JNIEnv* env, jclass clazz, jlong ds_ptr, jobjectArray packets) {
+ ALOG(LOG_DEBUG, LOG_TAG, "nativeFlush(%p)", (void*)ds_ptr);
+ sp<PerfettoDataSource> datasource = reinterpret_cast<PerfettoDataSource*>(ds_ptr);
+ datasource->WritePackets(env, packets);
}
void nativeFlushAll(JNIEnv* env, jclass clazz, jlong ptr) {
- ALOG(LOG_DEBUG, LOG_TAG, "nativeFlushAll(%p)", (void*)ptr);
sp<PerfettoDataSource> datasource = reinterpret_cast<PerfettoDataSource*>(ptr);
datasource->flushAll();
}
void nativeRegisterDataSource(JNIEnv* env, jclass clazz, jlong datasource_ptr,
int buffer_exhausted_policy) {
- ALOG(LOG_DEBUG, LOG_TAG, "nativeRegisterDataSource(%p)", (void*)datasource_ptr);
sp<PerfettoDataSource> datasource = reinterpret_cast<PerfettoDataSource*>(datasource_ptr);
struct PerfettoDsParams params = PerfettoDsParamsDefault();
@@ -283,10 +286,6 @@
auto* datasource_instance =
new PerfettoDataSourceInstance(env, java_data_source_instance.get(), inst_id);
-
- ALOG(LOG_DEBUG, LOG_TAG, "on_setup_cb ds=%p, ds_instance=%p", datasource,
- datasource_instance);
-
return static_cast<void*>(datasource_instance);
};
@@ -299,9 +298,6 @@
jobject java_tls_state = datasource->createTlsStateGlobalRef(env, inst_id);
auto* tls_state = new TlsState(java_tls_state);
-
- ALOG(LOG_DEBUG, LOG_TAG, "on_create_tls_cb ds=%p, tsl_state=%p", datasource, tls_state);
-
return static_cast<void*>(tls_state);
};
@@ -310,8 +306,6 @@
TlsState* tls_state = reinterpret_cast<TlsState*>(ptr);
- ALOG(LOG_DEBUG, LOG_TAG, "on_delete_tls_cb %p", tls_state);
-
env->DeleteGlobalRef(tls_state->jobj);
delete tls_state;
};
@@ -324,9 +318,6 @@
jobject java_incr_state = datasource->createIncrementalStateGlobalRef(env, inst_id);
auto* incr_state = new IncrementalState(java_incr_state);
-
- ALOG(LOG_DEBUG, LOG_TAG, "on_create_incr_cb ds=%p, incr_state=%p", datasource, incr_state);
-
return static_cast<void*>(incr_state);
};
@@ -335,8 +326,6 @@
IncrementalState* incr_state = reinterpret_cast<IncrementalState*>(ptr);
- ALOG(LOG_DEBUG, LOG_TAG, "on_delete_incr_cb incr_state=%p", incr_state);
-
env->DeleteGlobalRef(incr_state->jobj);
delete incr_state;
};
@@ -346,9 +335,6 @@
JNIEnv* env = GetOrAttachJNIEnvironment(gVm, JNI_VERSION_1_6);
auto* datasource_instance = static_cast<PerfettoDataSourceInstance*>(inst_ctx);
-
- ALOG(LOG_DEBUG, LOG_TAG, "on_start_cb ds_instance=%p", datasource_instance);
-
datasource_instance->onStart(env);
};
@@ -357,9 +343,6 @@
JNIEnv* env = GetOrAttachJNIEnvironment(gVm, JNI_VERSION_1_6);
auto* datasource_instance = static_cast<PerfettoDataSourceInstance*>(inst_ctx);
-
- ALOG(LOG_DEBUG, LOG_TAG, "on_flush_cb ds_instance=%p", datasource_instance);
-
datasource_instance->onFlush(env);
};
@@ -368,9 +351,6 @@
JNIEnv* env = GetOrAttachJNIEnvironment(gVm, JNI_VERSION_1_6);
auto* datasource_instance = static_cast<PerfettoDataSourceInstance*>(inst_ctx);
-
- ALOG(LOG_DEBUG, LOG_TAG, "on_stop_cb ds_instance=%p", datasource_instance);
-
datasource_instance->onStop(env);
};
@@ -378,18 +358,14 @@
void* inst_ctx) -> void {
auto* datasource_instance = static_cast<PerfettoDataSourceInstance*>(inst_ctx);
- ALOG(LOG_DEBUG, LOG_TAG, "on_destroy_cb ds_instance=%p", datasource_instance);
-
delete datasource_instance;
};
PerfettoDsRegister(&datasource->dataSource, datasource->dataSourceName.c_str(), params);
}
-jobject nativeGetPerfettoInstanceLocked(JNIEnv* env, jclass clazz, jlong dataSourcePtr,
+jobject nativeGetPerfettoInstanceLocked(JNIEnv* /* env */, jclass /* clazz */, jlong dataSourcePtr,
PerfettoDsInstanceIndex instance_idx) {
- ALOG(LOG_DEBUG, LOG_TAG, "nativeGetPerfettoInstanceLocked ds=%p, idx=%d", (void*)dataSourcePtr,
- instance_idx);
sp<PerfettoDataSource> datasource = reinterpret_cast<PerfettoDataSource*>(dataSourcePtr);
auto* datasource_instance = static_cast<PerfettoDataSourceInstance*>(
PerfettoDsImplGetInstanceLocked(datasource->dataSource.impl, instance_idx));
@@ -401,24 +377,44 @@
return nullptr;
}
- ALOG(LOG_DEBUG, LOG_TAG, "\tnativeGetPerfettoInstanceLocked got lock ds=%p, idx=%d",
- (void*)dataSourcePtr, instance_idx);
return datasource_instance->GetJavaDataSourceInstance();
}
-void nativeReleasePerfettoInstanceLocked(JNIEnv* env, jclass clazz, jlong dataSourcePtr,
+void nativeReleasePerfettoInstanceLocked(JNIEnv* /* env */, jclass /* clazz */, jlong dataSourcePtr,
PerfettoDsInstanceIndex instance_idx) {
- ALOG(LOG_DEBUG, LOG_TAG, "nativeReleasePerfettoInstanceLocked got lock ds=%p, idx=%d",
- (void*)dataSourcePtr, instance_idx);
sp<PerfettoDataSource> datasource = reinterpret_cast<PerfettoDataSource*>(dataSourcePtr);
PerfettoDsImplReleaseInstanceLocked(datasource->dataSource.impl, instance_idx);
}
+bool nativePerfettoDsTraceIterateBegin(jlong dataSourcePtr) {
+ sp<PerfettoDataSource> datasource = reinterpret_cast<PerfettoDataSource*>(dataSourcePtr);
+ return datasource->TraceIterateBegin();
+}
+
+bool nativePerfettoDsTraceIterateNext(jlong dataSourcePtr) {
+ sp<PerfettoDataSource> datasource = reinterpret_cast<PerfettoDataSource*>(dataSourcePtr);
+ return datasource->TraceIterateNext();
+}
+
+void nativePerfettoDsTraceIterateBreak(jlong dataSourcePtr) {
+ sp<PerfettoDataSource> datasource = reinterpret_cast<PerfettoDataSource*>(dataSourcePtr);
+ return datasource->TraceIterateBreak();
+}
+
+jobject nativeGetCustomTls(JNIEnv* /* env */, jclass /* clazz */, jlong dataSourcePtr) {
+ sp<PerfettoDataSource> datasource = reinterpret_cast<PerfettoDataSource*>(dataSourcePtr);
+ return datasource->GetCustomTls();
+}
+
+jobject nativeGetIncrementalState(JNIEnv* /* env */, jclass /* clazz */, jlong dataSourcePtr) {
+ sp<PerfettoDataSource> datasource = reinterpret_cast<PerfettoDataSource*>(dataSourcePtr);
+ return datasource->GetIncrementalState();
+}
+
const JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{"nativeCreate", "(Landroid/tracing/perfetto/DataSource;Ljava/lang/String;)J",
(void*)nativeCreate},
- {"nativeTrace", "(JLandroid/tracing/perfetto/TraceFunction;)V", (void*)nativeTrace},
{"nativeFlushAll", "(J)V", (void*)nativeFlushAll},
{"nativeGetFinalizer", "()J", (void*)nativeGetFinalizer},
{"nativeRegisterDataSource", "(JI)V", (void*)nativeRegisterDataSource},
@@ -426,11 +422,16 @@
(void*)nativeGetPerfettoInstanceLocked},
{"nativeReleasePerfettoInstanceLocked", "(JI)V",
(void*)nativeReleasePerfettoInstanceLocked},
-};
+
+ {"nativePerfettoDsTraceIterateBegin", "(J)Z", (void*)nativePerfettoDsTraceIterateBegin},
+ {"nativePerfettoDsTraceIterateNext", "(J)Z", (void*)nativePerfettoDsTraceIterateNext},
+ {"nativePerfettoDsTraceIterateBreak", "(J)V", (void*)nativePerfettoDsTraceIterateBreak}};
const JNINativeMethod gMethodsTracingContext[] = {
/* name, signature, funcPtr */
- {"nativeFlush", "(Landroid/tracing/perfetto/TracingContext;J)V", (void*)nativeFlush},
+ {"nativeFlush", "(J[[B)V", (void*)nativeFlush},
+ {"nativeGetCustomTls", "(J)Ljava/lang/Object;", (void*)nativeGetCustomTls},
+ {"nativeGetIncrementalState", "(J)Ljava/lang/Object;", (void*)nativeGetIncrementalState},
};
int register_android_tracing_PerfettoDataSource(JNIEnv* env) {
@@ -461,14 +462,6 @@
"(Landroid/tracing/perfetto/CreateIncrementalStateArgs;)Ljava/lang/"
"Object;");
- clazz = env->FindClass("android/tracing/perfetto/TracingContext");
- gTracingContextClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
- gTracingContextClassInfo.init = env->GetMethodID(gTracingContextClassInfo.clazz, "<init>",
- "(JLjava/lang/Object;Ljava/lang/Object;)V");
- gTracingContextClassInfo.getAndClearAllPendingTracePackets =
- env->GetMethodID(gTracingContextClassInfo.clazz, "getAndClearAllPendingTracePackets",
- "()[[B");
-
clazz = env->FindClass("android/tracing/perfetto/CreateTlsStateArgs");
gCreateTlsStateArgsClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
gCreateTlsStateArgsClassInfo.init =
diff --git a/core/jni/android_tracing_PerfettoDataSource.h b/core/jni/android_tracing_PerfettoDataSource.h
index 906d9f5..209de29 100644
--- a/core/jni/android_tracing_PerfettoDataSource.h
+++ b/core/jni/android_tracing_PerfettoDataSource.h
@@ -46,7 +46,15 @@
jobject createTlsStateGlobalRef(JNIEnv* env, PerfettoDsInstanceIndex inst_id);
jobject createIncrementalStateGlobalRef(JNIEnv* env, PerfettoDsInstanceIndex inst_id);
- void trace(JNIEnv* env, jobject trace_function);
+
+ bool TraceIterateBegin();
+ bool TraceIterateNext();
+ void TraceIterateBreak();
+ void WritePackets(JNIEnv* env, jobjectArray packets);
+
+ jobject GetCustomTls();
+ jobject GetIncrementalState();
+
void flushAll();
private:
diff --git a/core/res/OWNERS b/core/res/OWNERS
index 4e61ff2..3489cac 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -4,7 +4,6 @@
cinek@google.com
dsandler@android.com
dsandler@google.com
-dupin@google.com
hackbod@android.com
hackbod@google.com
ilyamaty@google.com
@@ -49,7 +48,7 @@
# Wear
per-file res/*-watch/* = file:/WEAR_OWNERS
-# Peformance
+# Performance
per-file res/values/config.xml = file:/PERFORMANCE_OWNERS
per-file res/values/symbols.xml = file:/PERFORMANCE_OWNERS
@@ -63,3 +62,11 @@
# TV Input Framework
per-file res/values/config_tv_external_input_logging.xml = file:/services/core/java/com/android/server/tv/OWNERS
+
+# SysUi Color Team
+per-file res/values/colors.xml = arteiro@google.com
+per-file res/values/attrs.xml = arteiro@google.com
+per-file res/values/styles.xml = arteiro@google.com
+per-file res/values/symbols.xml = arteiro@google.com
+per-file res/values/themes_device_defaults.xml = arteiro@google.com
+per-file res/values/styles_material.xml = arteiro@google.com
\ No newline at end of file
diff --git a/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java b/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java
index 6cc5485..8072d69 100644
--- a/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java
+++ b/core/tests/bugreports/src/com/android/os/bugreports/tests/BugreportManagerTest.java
@@ -16,6 +16,8 @@
package com.android.os.bugreports.tests;
+import static android.content.Context.RECEIVER_EXPORTED;
+
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertNotNull;
@@ -358,7 +360,10 @@
// shell UID rather than our own.
BugreportBroadcastReceiver br = new BugreportBroadcastReceiver();
InstrumentationRegistry.getContext()
- .registerReceiver(br, new IntentFilter(INTENT_BUGREPORT_FINISHED));
+ .registerReceiver(
+ br,
+ new IntentFilter(INTENT_BUGREPORT_FINISHED),
+ RECEIVER_EXPORTED);
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
.executeShellCommand("am bug-report");
diff --git a/data/etc/core.protolog.pb b/data/etc/core.protolog.pb
index 826adc39..97147a0 100644
--- a/data/etc/core.protolog.pb
+++ b/data/etc/core.protolog.pb
Binary files differ
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index d410d5f..6cf12de 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -709,18 +709,6 @@
"group": "WM_DEBUG_CONFIGURATION",
"at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
},
- "2959074735946674755": {
- "message": "Trying to update display configuration for system\/invalid process.",
- "level": "WARN",
- "group": "WM_DEBUG_CONFIGURATION",
- "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
- },
- "5668810920995272206": {
- "message": "Trying to update display configuration for invalid process, pid=%d",
- "level": "WARN",
- "group": "WM_DEBUG_CONFIGURATION",
- "at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
- },
"-1123414663662718691": {
"message": "setVr2dDisplayId called for: %d",
"level": "DEBUG",
@@ -3469,6 +3457,12 @@
"group": "WM_DEBUG_WALLPAPER",
"at": "com\/android\/server\/wm\/WallpaperController.java"
},
+ "257349083882992098": {
+ "message": "updateWallpaperTokens requestedVisibility=%b on keyguardLocked=%b",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_WALLPAPER",
+ "at": "com\/android\/server\/wm\/WallpaperController.java"
+ },
"7408402065665963407": {
"message": "Wallpaper at display %d - visibility: %b, keyguardLocked: %b",
"level": "VERBOSE",
diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
index efbbfc2..24aea37 100644
--- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java
+++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
@@ -229,4 +229,24 @@
"Keystore error while trying to get apps affected by SID.");
}
}
+
+ /**
+ * Deletes all keys in all KeyMint devices.
+ * Called by RecoverySystem before rebooting to recovery in order to delete all KeyMint keys,
+ * including synthetic password protector keys (used by LockSettingsService), as well as keys
+ * protecting DE and metadata encryption keys (used by vold). This ensures that FBE-encrypted
+ * data is unrecoverable even if the data wipe in recovery is interrupted or skipped.
+ */
+ public static void deleteAllKeys() throws KeyStoreException {
+ StrictMode.noteDiskWrite();
+ try {
+ getService().deleteAllKeys();
+ } catch (RemoteException | NullPointerException e) {
+ throw new KeyStoreException(SYSTEM_ERROR,
+ "Failure to connect to Keystore while trying to delete all keys.");
+ } catch (ServiceSpecificException e) {
+ throw new KeyStoreException(e.errorCode,
+ "Keystore error while trying to delete all keys.");
+ }
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
index 97bf8f7..73b2656 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java
@@ -32,6 +32,7 @@
import android.app.IActivityTaskManager;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.res.Configuration;
import android.database.ContentObserver;
import android.hardware.input.InputManager;
import android.net.Uri;
@@ -71,6 +72,7 @@
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.shared.annotations.ShellBackgroundThread;
import com.android.wm.shell.shared.annotations.ShellMainThread;
+import com.android.wm.shell.sysui.ConfigurationChangeListener;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
@@ -81,7 +83,8 @@
/**
* Controls the window animation run when a user initiates a back gesture.
*/
-public class BackAnimationController implements RemoteCallable<BackAnimationController> {
+public class BackAnimationController implements RemoteCallable<BackAnimationController>,
+ ConfigurationChangeListener {
private static final String TAG = "ShellBackPreview";
private static final int SETTING_VALUE_OFF = 0;
private static final int SETTING_VALUE_ON = 1;
@@ -248,6 +251,7 @@
mShellController.addExternalInterface(KEY_EXTRA_SHELL_BACK_ANIMATION,
this::createExternalInterface, this);
mShellCommandHandler.addDumpCallback(this::dump, this);
+ mShellController.addConfigurationChangeListener(this);
}
private void setupAnimationDeveloperSettingsObserver(
@@ -297,6 +301,11 @@
private final BackAnimationImpl mBackAnimation = new BackAnimationImpl();
@Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ mShellBackAnimationRegistry.onConfigurationChanged(newConfig);
+ }
+
+ @Override
public Context getContext() {
return mContext;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
index c6d4620..112ed09 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityBackAnimation.kt
@@ -68,7 +68,7 @@
private val backAnimRect = Rect()
- private val cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)
+ private var cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)
private val backAnimationRunner = BackAnimationRunner(
Callback(), Runner(), context, Cuj.CUJ_PREDICTIVE_BACK_CROSS_ACTIVITY
@@ -94,6 +94,10 @@
private var scrimLayer: SurfaceControl? = null
private var maxScrimAlpha: Float = 0f
+ override fun onConfigurationChanged(newConfiguration: Configuration) {
+ cornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context)
+ }
+
override fun getRunner() = backAnimationRunner
private fun startBackAnimation(backMotionEvent: BackMotionEvent) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
index 987001d..c34f30d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java
@@ -29,6 +29,7 @@
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.Rect;
@@ -80,7 +81,7 @@
private static final int POST_ANIMATION_DURATION_MS = 500;
private final Rect mStartTaskRect = new Rect();
- private final float mCornerRadius;
+ private float mCornerRadius;
// The closing window properties.
private final Rect mClosingStartRect = new Rect();
@@ -120,6 +121,11 @@
mContext = context;
}
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ mCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(mContext);
+ }
+
private static float mapRange(float value, float min, float max) {
return min + (value * (max - min));
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java
index e33aa75..838dab4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/CustomizeActivityAnimation.java
@@ -29,6 +29,7 @@
import android.annotation.Nullable;
import android.app.Activity;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.RemoteException;
@@ -63,7 +64,7 @@
public class CustomizeActivityAnimation extends ShellBackAnimation {
private final BackProgressAnimator mProgressAnimator = new BackProgressAnimator();
private final BackAnimationRunner mBackAnimationRunner;
- private final float mCornerRadius;
+ private float mCornerRadius;
private final SurfaceControl.Transaction mTransaction;
private final BackAnimationBackground mBackground;
private RemoteAnimationTarget mEnteringTarget;
@@ -88,6 +89,7 @@
final Transformation mTransformation = new Transformation();
private final Choreographer mChoreographer;
+ private final Context mContext;
@Inject
public CustomizeActivityAnimation(Context context, BackAnimationBackground background) {
@@ -108,6 +110,12 @@
.setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY));
mTransaction = transaction == null ? new SurfaceControl.Transaction() : transaction;
mChoreographer = choreographer != null ? choreographer : Choreographer.getInstance();
+ mContext = context;
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ mCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(mContext);
}
private float getLatestProgress() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimation.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimation.java
index dc65919..8a0daaa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimation.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimation.java
@@ -16,6 +16,7 @@
package com.android.wm.shell.back;
+import android.content.res.Configuration;
import android.window.BackNavigationInfo;
import javax.inject.Qualifier;
@@ -48,4 +49,8 @@
public boolean prepareNextAnimation(BackNavigationInfo.CustomAnimationInfo animationInfo) {
return false;
}
+
+ void onConfigurationChanged(Configuration newConfig) {
+
+ }
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java
index 26d2097..00daddc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/ShellBackAnimationRegistry.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.res.Configuration;
import android.util.Log;
import android.util.SparseArray;
import android.window.BackNavigationInfo;
@@ -29,6 +30,7 @@
private final SparseArray<BackAnimationRunner> mAnimationDefinition = new SparseArray<>();
private final ShellBackAnimation mDefaultCrossActivityAnimation;
private final ShellBackAnimation mCustomizeActivityAnimation;
+ private final ShellBackAnimation mCrossTaskAnimation;
public ShellBackAnimationRegistry(
@ShellBackAnimation.CrossActivity @Nullable ShellBackAnimation crossActivityAnimation,
@@ -57,6 +59,7 @@
mDefaultCrossActivityAnimation = crossActivityAnimation;
mCustomizeActivityAnimation = customizeActivityAnimation;
+ mCrossTaskAnimation = crossTaskAnimation;
// TODO(b/236760237): register dialog close animation when it's completed.
}
@@ -125,6 +128,12 @@
BackNavigationInfo.TYPE_CROSS_ACTIVITY, mDefaultCrossActivityAnimation.getRunner());
}
+ void onConfigurationChanged(Configuration newConfig) {
+ mCustomizeActivityAnimation.onConfigurationChanged(newConfig);
+ mDefaultCrossActivityAnimation.onConfigurationChanged(newConfig);
+ mCrossTaskAnimation.onConfigurationChanged(newConfig);
+ }
+
BackAnimationRunner getAnimationRunnerAndInit(BackNavigationInfo backNavigationInfo) {
int type = backNavigationInfo.getType();
// Initiate customized cross-activity animation, or fall back to cross activity animation
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 313d0d2..d295877 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -455,8 +455,7 @@
ProtoLog.d(WM_SHELL_BUBBLES,
"onActivityRestartAttempt - taskId=%d selecting matching bubble=%s",
task.taskId, b.getKey());
- mBubbleData.setSelectedBubble(b);
- mBubbleData.setExpanded(true);
+ mBubbleData.setSelectedBubbleAndExpandStack(b);
return;
}
}
@@ -593,13 +592,6 @@
}
}
- private void openBubbleOverflow() {
- ensureBubbleViewsAndWindowCreated();
- mBubbleData.setShowingOverflow(true);
- mBubbleData.setSelectedBubble(mBubbleData.getOverflow());
- mBubbleData.setExpanded(true);
- }
-
/**
* Called when the status bar has become visible or invisible (either permanently or
* temporarily).
@@ -1247,8 +1239,7 @@
}
if (mBubbleData.hasBubbleInStackWithKey(b.getKey())) {
// already in the stack
- mBubbleData.setSelectedBubble(b);
- mBubbleData.setExpanded(true);
+ mBubbleData.setSelectedBubbleAndExpandStack(b);
} else if (mBubbleData.hasOverflowBubbleWithKey(b.getKey())) {
// promote it out of the overflow
promoteBubbleFromOverflow(b);
@@ -1273,8 +1264,7 @@
String key = entry.getKey();
Bubble bubble = mBubbleData.getBubbleInStackWithKey(key);
if (bubble != null) {
- mBubbleData.setSelectedBubble(bubble);
- mBubbleData.setExpanded(true);
+ mBubbleData.setSelectedBubbleAndExpandStack(bubble);
} else {
bubble = mBubbleData.getOverflowBubbleWithKey(key);
if (bubble != null) {
@@ -1367,8 +1357,7 @@
} else {
// App bubble is not selected, select it & expand
Log.i(TAG, " showOrHideAppBubble, expand and select existing app bubble");
- mBubbleData.setSelectedBubble(existingAppBubble);
- mBubbleData.setExpanded(true);
+ mBubbleData.setSelectedBubbleAndExpandStack(existingAppBubble);
}
} else {
// Check if it exists in the overflow
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
index 61f0ed2..ae3d0c5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java
@@ -365,6 +365,19 @@
mSelectedBubble = bubble;
}
+ /**
+ * Sets the selected bubble and expands it.
+ *
+ * <p>This dispatches a single state update for both changes and should be used instead of
+ * calling {@link #setSelectedBubble(BubbleViewProvider)} followed by
+ * {@link #setExpanded(boolean)} immediately after, which will generate 2 separate updates.
+ */
+ public void setSelectedBubbleAndExpandStack(BubbleViewProvider bubble) {
+ setSelectedBubbleInternal(bubble);
+ setExpandedInternal(true);
+ dispatchPendingChanges();
+ }
+
public void setSelectedBubble(BubbleViewProvider bubble) {
setSelectedBubbleInternal(bubble);
dispatchPendingChanges();
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index 2ff1ddd..9c623bd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -120,6 +120,8 @@
private TestableContentResolver mContentResolver;
private TestableLooper mTestableLooper;
+ private CrossActivityBackAnimation mCrossActivityBackAnimation;
+ private CrossTaskBackAnimation mCrossTaskBackAnimation;
private ShellBackAnimationRegistry mShellBackAnimationRegistry;
@Before
@@ -133,11 +135,11 @@
ANIMATION_ENABLED);
mTestableLooper = TestableLooper.get(this);
mShellInit = spy(new ShellInit(mShellExecutor));
+ mCrossActivityBackAnimation = new CrossActivityBackAnimation(mContext, mAnimationBackground,
+ mRootTaskDisplayAreaOrganizer);
+ mCrossTaskBackAnimation = new CrossTaskBackAnimation(mContext, mAnimationBackground);
mShellBackAnimationRegistry =
- new ShellBackAnimationRegistry(
- new CrossActivityBackAnimation(
- mContext, mAnimationBackground, mRootTaskDisplayAreaOrganizer),
- new CrossTaskBackAnimation(mContext, mAnimationBackground),
+ new ShellBackAnimationRegistry(mCrossActivityBackAnimation, mCrossTaskBackAnimation,
/* dialogCloseAnimation= */ null,
new CustomizeActivityAnimation(mContext, mAnimationBackground),
/* defaultBackToHomeAnimation= */ null);
@@ -576,16 +578,14 @@
@Test
public void testBackToActivity() throws RemoteException {
- final CrossActivityBackAnimation animation = new CrossActivityBackAnimation(
- mContext, mAnimationBackground, mRootTaskDisplayAreaOrganizer);
- verifySystemBackBehavior(BackNavigationInfo.TYPE_CROSS_ACTIVITY, animation.getRunner());
+ verifySystemBackBehavior(BackNavigationInfo.TYPE_CROSS_ACTIVITY,
+ mCrossActivityBackAnimation.getRunner());
}
@Test
public void testBackToTask() throws RemoteException {
- final CrossTaskBackAnimation animation = new CrossTaskBackAnimation(mContext,
- mAnimationBackground);
- verifySystemBackBehavior(BackNavigationInfo.TYPE_CROSS_TASK, animation.getRunner());
+ verifySystemBackBehavior(BackNavigationInfo.TYPE_CROSS_TASK,
+ mCrossTaskBackAnimation.getRunner());
}
private void verifySystemBackBehavior(int type, BackAnimationRunner animation)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
index 48e396a..6be411d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
@@ -1222,6 +1222,19 @@
assertThat(update.bubbleBarLocation).isEqualTo(BubbleBarLocation.LEFT);
}
+ @Test
+ public void setSelectedBubbleAndExpandStack() {
+ sendUpdatedEntryAtTime(mEntryA1, 1000);
+ sendUpdatedEntryAtTime(mEntryA2, 2000);
+ mBubbleData.setListener(mListener);
+
+ mBubbleData.setSelectedBubbleAndExpandStack(mBubbleA1);
+
+ verifyUpdateReceived();
+ assertSelectionChangedTo(mBubbleA1);
+ assertExpandedChangedTo(true);
+ }
+
private void verifyUpdateReceived() {
verify(mListener).applyUpdate(mUpdateCaptor.capture());
reset(mListener);
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 2904dfe..708b011 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -442,14 +442,17 @@
}
// TODO: maybe we want to get rid of the WCG check if overlay properties just works?
- const bool canUseFp16 = DeviceInfo::get()->isSupportFp16ForHdr() ||
- DeviceInfo::get()->getWideColorType() == kRGBA_F16_SkColorType;
+ bool canUseFp16 = DeviceInfo::get()->isSupportFp16ForHdr() ||
+ DeviceInfo::get()->getWideColorType() == kRGBA_F16_SkColorType;
- if (canUseFp16) {
- if (mEglConfigF16 == EGL_NO_CONFIG_KHR) {
- colorMode = ColorMode::Default;
- } else {
- config = mEglConfigF16;
+ if (colorMode == ColorMode::Hdr) {
+ if (canUseFp16 && !DeviceInfo::get()->isSupportRgba10101010ForHdr()) {
+ if (mEglConfigF16 == EGL_NO_CONFIG_KHR) {
+ // If the driver doesn't support fp16 then fallback to 8-bit
+ canUseFp16 = false;
+ } else {
+ config = mEglConfigF16;
+ }
}
}
diff --git a/location/java/android/location/flags/location.aconfig b/location/java/android/location/flags/location.aconfig
index b8b03b6..19e59a7 100644
--- a/location/java/android/location/flags/location.aconfig
+++ b/location/java/android/location/flags/location.aconfig
@@ -1,5 +1,4 @@
package: "android.location.flags"
-container: "system"
flag {
name: "new_geocoder"
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 76bbca6..5aa006b 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -1309,18 +1309,24 @@
return;
}
- RoutingController newController;
- if (sessionInfo.isSystemSession()) {
- newController = getSystemController();
- newController.setRoutingSessionInfo(sessionInfo);
+ RoutingController newController = addRoutingController(sessionInfo);
+ notifyTransfer(oldController, newController);
+ }
+
+ @NonNull
+ private RoutingController addRoutingController(@NonNull RoutingSessionInfo session) {
+ RoutingController controller;
+ if (session.isSystemSession()) {
+ // mSystemController is never released, so we only need to update its status.
+ mSystemController.setRoutingSessionInfo(session);
+ controller = mSystemController;
} else {
- newController = new RoutingController(sessionInfo);
+ controller = new RoutingController(session);
synchronized (mLock) {
- mNonSystemRoutingControllers.put(newController.getId(), newController);
+ mNonSystemRoutingControllers.put(controller.getId(), controller);
}
}
-
- notifyTransfer(oldController, newController);
+ return controller;
}
void updateControllerOnHandler(RoutingSessionInfo sessionInfo) {
@@ -1329,40 +1335,12 @@
return;
}
- if (sessionInfo.isSystemSession()) {
- // The session info is sent from SystemMediaRoute2Provider.
- RoutingController systemController = getSystemController();
- systemController.setRoutingSessionInfo(sessionInfo);
- notifyControllerUpdated(systemController);
- return;
+ RoutingController controller =
+ getMatchingController(sessionInfo, /* logPrefix */ "updateControllerOnHandler");
+ if (controller != null) {
+ controller.setRoutingSessionInfo(sessionInfo);
+ notifyControllerUpdated(controller);
}
-
- RoutingController matchingController;
- synchronized (mLock) {
- matchingController = mNonSystemRoutingControllers.get(sessionInfo.getId());
- }
-
- if (matchingController == null) {
- Log.w(
- TAG,
- "updateControllerOnHandler: Matching controller not found. uniqueSessionId="
- + sessionInfo.getId());
- return;
- }
-
- RoutingSessionInfo oldInfo = matchingController.getRoutingSessionInfo();
- if (!TextUtils.equals(oldInfo.getProviderId(), sessionInfo.getProviderId())) {
- Log.w(
- TAG,
- "updateControllerOnHandler: Provider IDs are not matched. old="
- + oldInfo.getProviderId()
- + ", new="
- + sessionInfo.getProviderId());
- return;
- }
-
- matchingController.setRoutingSessionInfo(sessionInfo);
- notifyControllerUpdated(matchingController);
}
void releaseControllerOnHandler(RoutingSessionInfo sessionInfo) {
@@ -1371,34 +1349,47 @@
return;
}
- RoutingController matchingController;
- synchronized (mLock) {
- matchingController = mNonSystemRoutingControllers.get(sessionInfo.getId());
- }
+ RoutingController matchingController =
+ getMatchingController(sessionInfo, /* logPrefix */ "releaseControllerOnHandler");
- if (matchingController == null) {
- if (DEBUG) {
- Log.d(
- TAG,
- "releaseControllerOnHandler: Matching controller not found. "
- + "uniqueSessionId="
- + sessionInfo.getId());
+ if (matchingController != null) {
+ matchingController.releaseInternal(/* shouldReleaseSession= */ false);
+ }
+ }
+
+ @Nullable
+ private RoutingController getMatchingController(
+ RoutingSessionInfo sessionInfo, String logPrefix) {
+ if (sessionInfo.isSystemSession()) {
+ return getSystemController();
+ } else {
+ RoutingController controller;
+ synchronized (mLock) {
+ controller = mNonSystemRoutingControllers.get(sessionInfo.getId());
}
- return;
- }
- RoutingSessionInfo oldInfo = matchingController.getRoutingSessionInfo();
- if (!TextUtils.equals(oldInfo.getProviderId(), sessionInfo.getProviderId())) {
- Log.w(
- TAG,
- "releaseControllerOnHandler: Provider IDs are not matched. old="
- + oldInfo.getProviderId()
- + ", new="
- + sessionInfo.getProviderId());
- return;
- }
+ if (controller == null) {
+ Log.w(
+ TAG,
+ logPrefix
+ + ": Matching controller not found. uniqueSessionId="
+ + sessionInfo.getId());
+ return null;
+ }
- matchingController.releaseInternal(/* shouldReleaseSession= */ false);
+ RoutingSessionInfo oldInfo = controller.getRoutingSessionInfo();
+ if (!TextUtils.equals(oldInfo.getProviderId(), sessionInfo.getProviderId())) {
+ Log.w(
+ TAG,
+ logPrefix
+ + ": Provider IDs are not matched. old="
+ + oldInfo.getProviderId()
+ + ", new="
+ + sessionInfo.getProviderId());
+ return null;
+ }
+ return controller;
+ }
}
void onRequestCreateControllerByManagerOnHandler(
diff --git a/media/java/android/media/flags/editing.aconfig b/media/java/android/media/flags/editing.aconfig
index bf6ec96..5bf1b4e 100644
--- a/media/java/android/media/flags/editing.aconfig
+++ b/media/java/android/media/flags/editing.aconfig
@@ -1,5 +1,4 @@
package: "com.android.media.editing.flags"
-container: "system"
flag {
name: "add_media_metrics_editing"
diff --git a/media/java/android/media/flags/media_better_together.aconfig b/media/java/android/media/flags/media_better_together.aconfig
index 91c4f11..8d6982e 100644
--- a/media/java/android/media/flags/media_better_together.aconfig
+++ b/media/java/android/media/flags/media_better_together.aconfig
@@ -1,5 +1,4 @@
package: "com.android.media.flags"
-container: "system"
flag {
name: "enable_rlp_callbacks_in_media_router2"
diff --git a/media/java/android/media/flags/projection.aconfig b/media/java/android/media/flags/projection.aconfig
index 9a9a073..b165809 100644
--- a/media/java/android/media/flags/projection.aconfig
+++ b/media/java/android/media/flags/projection.aconfig
@@ -1,5 +1,4 @@
package: "com.android.media.projection.flags"
-container: "system"
# Project link: https://gantry.corp.google.com/projects/android_platform_window_surfaces/changes
diff --git a/media/java/android/media/tv/flags/media_tv.aconfig b/media/java/android/media/tv/flags/media_tv.aconfig
index 97971e1..1731e5e 100644
--- a/media/java/android/media/tv/flags/media_tv.aconfig
+++ b/media/java/android/media/tv/flags/media_tv.aconfig
@@ -1,5 +1,4 @@
package: "android.media.tv.flags"
-container: "system"
flag {
name: "broadcast_visibility_types"
diff --git a/media/jni/playback_flags.aconfig b/media/jni/playback_flags.aconfig
index 9d927ec..2bb0ec5 100644
--- a/media/jni/playback_flags.aconfig
+++ b/media/jni/playback_flags.aconfig
@@ -1,5 +1,4 @@
package: "com.android.media.playback.flags"
-container: "system"
flag {
name: "mediametadataretriever_default_rgba8888"
diff --git a/nfc/TEST_MAPPING b/nfc/TEST_MAPPING
index 5b5ea37..49c778d 100644
--- a/nfc/TEST_MAPPING
+++ b/nfc/TEST_MAPPING
@@ -5,6 +5,9 @@
},
{
"name": "CtsNfcTestCases"
+ },
+ {
+ "name": "CtsNdefTestCases"
}
]
}
diff --git a/nfc/java/android/nfc/flags.aconfig b/nfc/java/android/nfc/flags.aconfig
index 73b29db..778f07c 100644
--- a/nfc/java/android/nfc/flags.aconfig
+++ b/nfc/java/android/nfc/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.nfc"
-container: "system"
flag {
name: "enable_nfc_mainline"
diff --git a/packages/CrashRecovery/aconfig/flags.aconfig b/packages/CrashRecovery/aconfig/flags.aconfig
index 35d7393..8627eac 100644
--- a/packages/CrashRecovery/aconfig/flags.aconfig
+++ b/packages/CrashRecovery/aconfig/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.crashrecovery.flags"
-container: "system"
flag {
name: "recoverability_detection"
diff --git a/packages/InputDevices/res/raw/keyboard_layout_german.kcm b/packages/InputDevices/res/raw/keyboard_layout_german.kcm
index fbb9bb6..1fb0924 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_german.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_german.kcm
@@ -28,82 +28,93 @@
key GRAVE {
label: '^'
- base: '^'
+ base: '\u0302'
shift: '\u00b0'
}
key 1 {
label: '1'
base: '1'
- shift: '!'
+ shift, capslock: '!'
+ shift+capslock: '1'
}
key 2 {
label: '2'
base: '2'
- shift: '"'
+ shift, capslock: '"'
+ shift+capslock: '2'
ralt: '\u00b2'
}
key 3 {
label: '3'
base: '3'
- shift: '\u00a7'
+ shift, capslock: '\u00a7'
+ shift+capslock: '3'
ralt: '\u00b3'
}
key 4 {
label: '4'
base: '4'
- shift: '$'
+ shift, capslock: '$'
+ shift+capslock: '4'
}
key 5 {
label: '5'
base: '5'
- shift: '%'
+ shift, capslock: '%'
+ shift+capslock: '5'
}
key 6 {
label: '6'
base: '6'
- shift: '&'
+ shift, capslock: '&'
+ shift+capslock: '6'
}
key 7 {
label: '7'
base: '7'
- shift: '/'
+ shift, capslock: '/'
+ shift+capslock: '7'
ralt: '{'
}
key 8 {
label: '8'
base: '8'
- shift: '('
+ shift, capslock: '('
+ shift+capslock: '8'
ralt: '['
}
key 9 {
label: '9'
base: '9'
- shift: ')'
+ shift, capslock: ')'
+ shift+capslock: '9'
ralt: ']'
}
key 0 {
label: '0'
base: '0'
- shift: '='
+ shift, capslock: '='
+ shift+capslock: '0'
ralt: '}'
}
key SLASH {
label: '\u00df'
base: '\u00df'
- capslock: '\u1e9e'
- shift: '?'
+ shift, capslock: '?'
+ shift+capslock: '\u00df'
ralt: '\\'
+ shift+ralt: '\u1e9e'
}
key EQUALS {
@@ -196,7 +207,8 @@
key RIGHT_BRACKET {
label: '+'
base: '+'
- shift: '*'
+ shift, capslock: '*'
+ shift+capslock: '+'
ralt: '~'
}
@@ -282,7 +294,8 @@
key BACKSLASH {
label: '#'
base: '#'
- shift: '\''
+ shift, capslock: '\''
+ shift+capslock: '#'
}
### ROW 4
@@ -347,13 +360,15 @@
key COMMA {
label: ','
base: ','
- shift: ';'
+ shift, capslock: ';'
+ shift+capslock: ','
}
key PERIOD {
label: '.'
base: '.'
- shift: ':'
+ shift, capslock: ':'
+ shift+capslock: '.'
}
key MINUS {
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
index 8f5d07c..407ab5f 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
@@ -245,8 +245,7 @@
}
private static boolean isArchivingEnabled() {
- return android.content.pm.Flags.archiving()
- || SystemProperties.getBoolean("pm.archiving.enabled", false);
+ return android.content.pm.Flags.archiving();
}
private boolean isCloneProfile(UserHandle userHandle) {
diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_mainSwitchPreference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_mainSwitchPreference.png
index 3e016f7..75c8e6e 100644
--- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_mainSwitchPreference.png
+++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_mainSwitchPreference.png
Binary files differ
diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_spinner.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_spinner.png
index d156f95..06f0059 100644
--- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_spinner.png
+++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_landscape_spinner.png
Binary files differ
diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_mainSwitchPreference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_mainSwitchPreference.png
index b8bb25f..b72c8db 100644
--- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_mainSwitchPreference.png
+++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_mainSwitchPreference.png
Binary files differ
diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_spinner.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_spinner.png
index d156f95..06f0059 100644
--- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_spinner.png
+++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_spinner.png
Binary files differ
diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_twoTargetSwitchPreference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_twoTargetSwitchPreference.png
index 9044208..e43f27d 100644
--- a/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_twoTargetSwitchPreference.png
+++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/phone/light_portrait_twoTargetSwitchPreference.png
Binary files differ
diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_mainSwitchPreference.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_mainSwitchPreference.png
index 36cbadc..15c86dc 100644
--- a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_mainSwitchPreference.png
+++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_mainSwitchPreference.png
Binary files differ
diff --git a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_spinner.png b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_spinner.png
index a279481..5be3a21 100644
--- a/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_spinner.png
+++ b/packages/SettingsLib/Spa/screenshot/robotests/assets/tablet/dark_portrait_spinner.png
Binary files differ
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt
index a395266..e1e1ee5 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppListRepository.kt
@@ -151,7 +151,7 @@
}
private fun isArchivingEnabled(featureFlags: FeatureFlags) =
- featureFlags.archiving() || SystemProperties.getBoolean("pm.archiving.enabled", false)
+ featureFlags.archiving()
override fun showSystemPredicate(
userIdFlow: Flow<Int>,
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
index 64cf5c64..6c12cb7 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
@@ -78,6 +78,7 @@
public static final String ACTION_LE_AUDIO_SHARING_STATE_CHANGE =
"com.android.settings.action.BLUETOOTH_LE_AUDIO_SHARING_STATE_CHANGE";
public static final String EXTRA_LE_AUDIO_SHARING_STATE = "BLUETOOTH_LE_AUDIO_SHARING_STATE";
+ public static final String EXTRA_BLUETOOTH_DEVICE = "BLUETOOTH_DEVICE";
public static final int BROADCAST_STATE_UNKNOWN = 0;
public static final int BROADCAST_STATE_ON = 1;
public static final int BROADCAST_STATE_OFF = 2;
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index f42efe2..c891dfc 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -840,6 +840,8 @@
Settings.Secure.BIOMETRIC_APP_ENABLED,
Settings.Secure.BIOMETRIC_KEYGUARD_ENABLED,
Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED,
+ Settings.Secure.BIOMETRIC_FINGERPRINT_VIRTUAL_ENABLED,
+ Settings.Secure.BIOMETRIC_FACE_VIRTUAL_ENABLED,
Settings.Secure.BLUETOOTH_ADDR_VALID,
Settings.Secure.BLUETOOTH_ADDRESS,
Settings.Secure.BLUETOOTH_NAME,
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml b/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml
index 648cc3b..a98625f 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml
@@ -40,7 +40,7 @@
android:exported="true"
android:label="@string/accessibility_menu_settings_name"
android:launchMode="singleTop"
- android:theme="@style/Theme.SettingsBase">
+ android:theme="@style/SettingsTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
@@ -59,4 +59,4 @@
<action android:name="android.intent.action.VOICE_COMMAND" />
</intent>
</queries>
-</manifest>
\ No newline at end of file
+</manifest>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values/styles.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values/styles.xml
index 4169155..a138fa9 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values/styles.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values/styles.xml
@@ -21,6 +21,11 @@
<item name="android:colorControlNormal">@color/colorControlNormal</item>
</style>
+ <style name="SettingsTheme" parent="Theme.SettingsBase">
+ <!-- Quick fix so that the preference page doesn't render under its parent header. -->
+ <item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
+ </style>
+
<!--The basic theme for service and test case only-->
<style name="A11yMenuBaseTheme" parent="android:Theme.DeviceDefault.Light">
<item name="android:windowActionBar">false</item>
diff --git a/packages/SystemUI/aconfig/Android.bp b/packages/SystemUI/aconfig/Android.bp
index 2a32b58..1858c80 100644
--- a/packages/SystemUI/aconfig/Android.bp
+++ b/packages/SystemUI/aconfig/Android.bp
@@ -45,4 +45,5 @@
java_aconfig_library {
name: "com_android_systemui_flags_lib",
aconfig_declarations: "com_android_systemui_flags",
+ sdk_version: "system_current",
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt
index fcd7760..02a12e4 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/ShadeHeader.kt
@@ -54,9 +54,9 @@
import com.android.compose.animation.scene.ElementKey
import com.android.compose.animation.scene.LowestZIndexScenePicker
import com.android.compose.animation.scene.SceneScope
+import com.android.compose.animation.scene.TransitionState
import com.android.compose.animation.scene.ValueKey
import com.android.compose.animation.scene.animateElementFloatAsState
-import com.android.compose.animation.scene.animateSceneFloatAsState
import com.android.compose.windowsizeclass.LocalWindowSizeClass
import com.android.settingslib.Utils
import com.android.systemui.battery.BatteryMeterView
@@ -87,10 +87,6 @@
val ShadeCarrierGroup = ElementKey("ShadeCarrierGroup")
}
- object Keys {
- val transitionProgress = ValueKey("ShadeHeaderTransitionProgress")
- }
-
object Values {
val ClockScale = ValueKey("ShadeHeaderClockScale")
}
@@ -119,19 +115,17 @@
return
}
- val formatProgress =
- animateSceneFloatAsState(0f, ShadeHeader.Keys.transitionProgress)
- .unsafeCompositionState(initialValue = 0f)
-
val cutoutWidth = LocalDisplayCutout.current.width()
val cutoutLocation = LocalDisplayCutout.current.location
val useExpandedFormat by
- remember(formatProgress) {
+ remember(cutoutLocation) {
derivedStateOf {
- cutoutLocation != CutoutLocation.CENTER || formatProgress.value > 0.5f
+ cutoutLocation != CutoutLocation.CENTER ||
+ shouldUseExpandedFormat(layoutState.transitionState)
}
}
+
val isPrivacyChipVisible by viewModel.isPrivacyChipVisible.collectAsState()
// This layout assumes it is globally positioned at (0, 0) and is the
@@ -207,7 +201,7 @@
val screenWidth = constraints.maxWidth
val cutoutWidthPx = cutoutWidth.roundToPx()
- val height = ShadeHeader.Dimensions.CollapsedHeight.roundToPx()
+ val height = CollapsedHeight.roundToPx()
val childConstraints = Constraints.fixed((screenWidth - cutoutWidthPx) / 2, height)
val startMeasurable = measurables[0][0]
@@ -261,11 +255,10 @@
return
}
- val formatProgress =
- animateSceneFloatAsState(1f, ShadeHeader.Keys.transitionProgress)
- .unsafeCompositionState(initialValue = 1f)
- val useExpandedFormat by
- remember(formatProgress) { derivedStateOf { formatProgress.value > 0.5f } }
+ val useExpandedFormat by remember {
+ derivedStateOf { shouldUseExpandedFormat(layoutState.transitionState) }
+ }
+
val isPrivacyChipVisible by viewModel.isPrivacyChipVisible.collectAsState()
Box(modifier = modifier) {
@@ -530,3 +523,15 @@
modifier = modifier.element(ShadeHeader.Elements.PrivacyChip),
)
}
+
+private fun shouldUseExpandedFormat(state: TransitionState): Boolean {
+ return when (state) {
+ is TransitionState.Idle -> {
+ state.currentScene == Scenes.QuickSettings
+ }
+ is TransitionState.Transition -> {
+ (state.isTransitioning(Scenes.Shade, Scenes.QuickSettings) && state.progress >= 0.5) ||
+ (state.isTransitioning(Scenes.QuickSettings, Scenes.Shade) && state.progress < 0.5)
+ }
+ }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
index 426f94d..139289a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt
@@ -31,6 +31,7 @@
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
import com.android.systemui.qs.ui.adapter.FakeQSSceneAdapter
import com.android.systemui.res.R
+import com.android.systemui.scene.domain.interactor.sceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.brightness.ui.viewmodel.brightnessMirrorViewModel
import com.android.systemui.shade.domain.interactor.privacyChipInteractor
@@ -88,6 +89,7 @@
flags,
scope = testScope.backgroundScope,
)
+ private val sceneInteractor = kosmos.sceneInteractor
private lateinit var shadeHeaderViewModel: ShadeHeaderViewModel
@@ -115,11 +117,12 @@
notifications = kosmos.notificationsPlaceholderViewModel,
footerActionsViewModelFactory = footerActionsViewModelFactory,
footerActionsController = footerActionsController,
+ sceneInteractor = sceneInteractor,
)
}
@Test
- fun destinationsNotCustomizing() =
+ fun destinations_whenNotCustomizing() =
testScope.runTest {
overrideResource(R.bool.config_use_split_notification_shade, false)
val destinations by collectLastValue(underTest.destinationScenes)
@@ -135,7 +138,30 @@
}
@Test
- fun destinationsCustomizing_noDestinations() =
+ fun destinations_whenNotCustomizing_withPreviousSceneLockscreen() =
+ testScope.runTest {
+ overrideResource(R.bool.config_use_split_notification_shade, false)
+ qsFlexiglassAdapter.setCustomizing(false)
+ val destinations by collectLastValue(underTest.destinationScenes)
+
+ val currentScene by collectLastValue(sceneInteractor.currentScene)
+ val previousScene by collectLastValue(sceneInteractor.previousScene)
+ sceneInteractor.changeScene(Scenes.Lockscreen, "reason")
+ sceneInteractor.changeScene(Scenes.QuickSettings, "reason")
+ assertThat(currentScene).isEqualTo(Scenes.QuickSettings)
+ assertThat(previousScene).isEqualTo(Scenes.Lockscreen)
+
+ assertThat(destinations)
+ .isEqualTo(
+ mapOf(
+ Back to UserActionResult(Scenes.Lockscreen),
+ Swipe(SwipeDirection.Up) to UserActionResult(Scenes.Lockscreen),
+ )
+ )
+ }
+
+ @Test
+ fun destinations_whenCustomizing_noDestinations() =
testScope.runTest {
overrideResource(R.bool.config_use_split_notification_shade, false)
val destinations by collectLastValue(underTest.destinationScenes)
diff --git a/packages/SystemUI/res/drawable/tv_volume_row_seek_thumb.xml b/packages/SystemUI/res/drawable/tv_volume_row_seek_thumb.xml
index 3c31861..a706c65 100644
--- a/packages/SystemUI/res/drawable/tv_volume_row_seek_thumb.xml
+++ b/packages/SystemUI/res/drawable/tv_volume_row_seek_thumb.xml
@@ -19,9 +19,4 @@
<solid android:color="@color/tv_volume_dialog_accent" />
<size android:width="@dimen/tv_volume_seek_bar_thumb_diameter"
android:height="@dimen/tv_volume_seek_bar_thumb_diameter" />
- <stroke android:width="@dimen/tv_volume_seek_bar_thumb_focus_ring_width"
- android:color="@color/tv_volume_dialog_seek_thumb_focus_ring"/>
- <item name="android:shadowColor">@color/tv_volume_dialog_seek_thumb_shadow</item>
- <item name="android:shadowRadius">@dimen/tv_volume_seek_bar_thumb_shadow_radius</item>
- <item name="android:shadowDy">@dimen/tv_volume_seek_bar_thumb_shadow_dy</item>
</shape>
diff --git a/packages/SystemUI/res/values-land-television/dimens.xml b/packages/SystemUI/res/values-land-television/dimens.xml
index 52f591f..d3bafbc 100644
--- a/packages/SystemUI/res/values-land-television/dimens.xml
+++ b/packages/SystemUI/res/values-land-television/dimens.xml
@@ -28,9 +28,6 @@
<dimen name="tv_volume_dialog_bubble_size">36dp</dimen>
<dimen name="tv_volume_dialog_row_padding">6dp</dimen>
<dimen name="tv_volume_number_text_size">16sp</dimen>
- <dimen name="tv_volume_seek_bar_thumb_diameter">24dp</dimen>
- <dimen name="tv_volume_seek_bar_thumb_focus_ring_width">8dp</dimen>
+ <dimen name="tv_volume_seek_bar_thumb_diameter">16dp</dimen>
<dimen name="tv_volume_icons_size">20dp</dimen>
- <dimen name="tv_volume_seek_bar_thumb_shadow_radius">4.0</dimen>
- <dimen name="tv_volume_seek_bar_thumb_shadow_dy">4.0</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/colors_tv.xml b/packages/SystemUI/res/values/colors_tv.xml
index 2bab3cb..5d45607 100644
--- a/packages/SystemUI/res/values/colors_tv.xml
+++ b/packages/SystemUI/res/values/colors_tv.xml
@@ -28,8 +28,6 @@
<color name="red">#FFCC0000</color>
<color name="tv_volume_dialog_circle">#08FFFFFF</color>
- <color name="tv_volume_dialog_seek_thumb_focus_ring">#1AFFFFFF</color>
- <color name="tv_volume_dialog_seek_thumb_shadow">#40000000</color>
<color name="tv_volume_dialog_seek_bar_background">#A03C4043</color>
<color name="tv_volume_dialog_seek_bar_fill">#FFF8F9FA</color>
<color name="tv_volume_dialog_accent">#FFDADCE0</color>
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
index 0f4d63c..7e96e48 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationAnimationController.java
@@ -149,7 +149,7 @@
if (mState == STATE_ENABLING || mState == STATE_DISABLING) {
mValueAnimator.cancel();
}
- mController.enableWindowMagnificationInternal(scale, centerX, centerY,
+ mController.updateWindowMagnificationInternal(scale, centerX, centerY,
mMagnificationFrameOffsetRatioX, mMagnificationFrameOffsetRatioY);
updateState();
return;
@@ -159,7 +159,7 @@
if (mEndSpec.equals(mStartSpec)) {
if (mState == STATE_DISABLED) {
- mController.enableWindowMagnificationInternal(scale, centerX, centerY,
+ mController.updateWindowMagnificationInternal(scale, centerX, centerY,
mMagnificationFrameOffsetRatioX, mMagnificationFrameOffsetRatioY);
} else if (mState == STATE_ENABLING || mState == STATE_DISABLING) {
mValueAnimator.cancel();
@@ -306,7 +306,7 @@
// If the animation is playing backwards, mStartSpec will be the final spec we would
// like to reach.
AnimationSpec spec = isReverse ? mStartSpec : mEndSpec;
- mController.enableWindowMagnificationInternal(
+ mController.updateWindowMagnificationInternal(
spec.mScale, spec.mCenterX, spec.mCenterY,
mMagnificationFrameOffsetRatioX, mMagnificationFrameOffsetRatioY);
@@ -358,7 +358,7 @@
mStartSpec.mCenterX + (mEndSpec.mCenterX - mStartSpec.mCenterX) * fract;
final float centerY =
mStartSpec.mCenterY + (mEndSpec.mCenterY - mStartSpec.mCenterY) * fract;
- mController.enableWindowMagnificationInternal(sentScale, centerX, centerY,
+ mController.updateWindowMagnificationInternal(sentScale, centerX, centerY,
mMagnificationFrameOffsetRatioX, mMagnificationFrameOffsetRatioY);
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
index d65cd5c..a847c3d 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnificationController.java
@@ -148,7 +148,7 @@
/**
* SourceBound is the bound of the magnified region which projects the magnified content.
* SourceBound's center is equal to the parameters centerX and centerY in
- * {@link WindowMagnificationController#enableWindowMagnificationInternal(float, float, float)}}
+ * {@link WindowMagnificationController#updateWindowMagnificationInternal(float, float, float)}}
* but it is calculated from {@link #mMagnificationFrame}'s center in the runtime.
*/
private final Rect mSourceBounds = new Rect();
@@ -566,7 +566,7 @@
// window size changed not caused by rotation.
if (isActivated() && reCreateWindow) {
deleteWindowMagnification();
- enableWindowMagnificationInternal(Float.NaN, Float.NaN, Float.NaN);
+ updateWindowMagnificationInternal(Float.NaN, Float.NaN, Float.NaN);
}
}
@@ -1317,7 +1317,7 @@
}
/**
- * Wraps {@link WindowMagnificationController#enableWindowMagnificationInternal(float, float,
+ * Wraps {@link WindowMagnificationController#updateWindowMagnificationInternal(float, float,
* float, float, float)}
* with transition animation. If the window magnification is not enabled, the scale will start
* from 1.0 and the center won't be changed during the animation. If animator is
@@ -1344,10 +1344,12 @@
}
/**
- * Enables window magnification with specified parameters. If the given scale is <strong>less
- * than or equal to 1.0f</strong>, then
+ * Updates window magnification status with specified parameters. If the given scale is
+ * <strong>less than 1.0f</strong>, then
* {@link WindowMagnificationController#deleteWindowMagnification()} will be called instead to
- * be consistent with the behavior of display magnification.
+ * be consistent with the behavior of display magnification. If the given scale is
+ * <strong>larger than or equal to 1.0f</strong>, and the window magnification is not activated
+ * yet, window magnification will be enabled.
*
* @param scale the target scale, or {@link Float#NaN} to leave unchanged
* @param centerX the screen-relative X coordinate around which to center for magnification,
@@ -1355,16 +1357,17 @@
* @param centerY the screen-relative Y coordinate around which to center for magnification,
* or {@link Float#NaN} to leave unchanged.
*/
- void enableWindowMagnificationInternal(float scale, float centerX, float centerY) {
- enableWindowMagnificationInternal(scale, centerX, centerY, Float.NaN, Float.NaN);
+ void updateWindowMagnificationInternal(float scale, float centerX, float centerY) {
+ updateWindowMagnificationInternal(scale, centerX, centerY, Float.NaN, Float.NaN);
}
/**
- * Enables window magnification with specified parameters. If the given scale is <strong>less
- * than 1.0f</strong>, then
+ * Updates window magnification status with specified parameters. If the given scale is
+ * <strong>less than 1.0f</strong>, then
* {@link WindowMagnificationController#deleteWindowMagnification()} will be called instead to
- * be consistent with the behavior of display magnification.
- *
+ * be consistent with the behavior of display magnification. If the given scale is
+ * <strong>larger than or equal to 1.0f</strong>, and the window magnification is not activated
+ * yet, window magnification will be enabled.
* @param scale the target scale, or {@link Float#NaN} to leave unchanged
* @param centerX the screen-relative X coordinate around which to center for magnification,
* or {@link Float#NaN} to leave unchanged.
@@ -1377,7 +1380,7 @@
* between frame position Y and centerY,
* or {@link Float#NaN} to leave unchanged.
*/
- void enableWindowMagnificationInternal(float scale, float centerX, float centerY,
+ void updateWindowMagnificationInternal(float scale, float centerX, float centerY,
float magnificationFrameOffsetRatioX, float magnificationFrameOffsetRatioY) {
if (Float.compare(scale, 1.0f) < 0) {
deleteWindowMagnification();
@@ -1433,7 +1436,7 @@
return;
}
- enableWindowMagnificationInternal(scale, Float.NaN, Float.NaN);
+ updateWindowMagnificationInternal(scale, Float.NaN, Float.NaN);
mHandler.removeCallbacks(mUpdateStateDescriptionRunnable);
mHandler.postDelayed(mUpdateStateDescriptionRunnable, UPDATE_STATE_DESCRIPTION_DELAY_MS);
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
index 42bd4af..ce1aed0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt
@@ -621,7 +621,9 @@
}
private suspend fun updateClockAppearance(clock: ClockController) {
- clockController.clock = clock
+ if (!MigrateClocksToBlueprint.isEnabled) {
+ clockController.clock = clock
+ }
val colors = wallpaperColors
if (clockRegistry.seedColor == null && colors != null) {
// Seed color null means users do not override any color on the clock. The default
@@ -639,6 +641,11 @@
if (isWallpaperDark) lightClockColor else darkClockColor
)
}
+ // In clock preview, we should have a seed color for clock
+ // before setting clock to clockEventController to avoid updateColor with seedColor == null
+ if (MigrateClocksToBlueprint.isEnabled) {
+ clockController.clock = clock
+ }
}
private fun onClockChanged() {
if (MigrateClocksToBlueprint.isEnabled) {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
index a09d58a..3a19780 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModel.kt
@@ -21,21 +21,15 @@
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryUdfpsInteractor
import com.android.systemui.keyguard.domain.interactor.FromOccludedTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import com.android.systemui.res.R
-import com.android.systemui.util.kotlin.pairwise
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.merge
/**
* Breaks down OCCLUDED->LOCKSCREEN transition into discrete steps for corresponding views to
@@ -49,8 +43,6 @@
deviceEntryUdfpsInteractor: DeviceEntryUdfpsInteractor,
configurationInteractor: ConfigurationInteractor,
animationFlow: KeyguardTransitionAnimationFlow,
- keyguardInteractor: KeyguardInteractor,
- keyguardTransitionInteractor: KeyguardTransitionInteractor,
) : DeviceEntryIconTransition {
private val transitionAnimation =
@@ -82,28 +74,11 @@
/** Lockscreen views alpha */
val lockscreenAlpha: Flow<Float> =
- merge(
- transitionAnimation.sharedFlow(
- startTime = 233.milliseconds,
- duration = 250.milliseconds,
- onStep = { it },
- name = "OCCLUDED->LOCKSCREEN: lockscreenAlpha",
- ),
- // Required to fix a bug where the shade expands while lockscreenAlpha=1f, due to a call
- // to setOccluded(false) triggering a reset() call in KeyguardViewMediator. The
- // permanent solution is to only expand the shade once the keyguard transition from
- // OCCLUDED starts, but that requires more refactoring of expansion amounts. For now,
- // emit alpha = 0f for OCCLUDED -> LOCKSCREEN whenever isOccluded flips from true to
- // false while currentState == OCCLUDED, so that alpha = 0f when that expansion occurs.
- // TODO(b/332946323): Remove this once it's no longer needed.
- keyguardInteractor.isKeyguardOccluded
- .pairwise()
- .filter { (wasOccluded, isOccluded) ->
- wasOccluded &&
- !isOccluded &&
- keyguardTransitionInteractor.getCurrentState() == KeyguardState.OCCLUDED
- }
- .map { 0f }
+ transitionAnimation.sharedFlow(
+ startTime = 233.milliseconds,
+ duration = 250.milliseconds,
+ onStep = { it },
+ name = "OCCLUDED->LOCKSCREEN: lockscreenAlpha",
)
val deviceEntryBackgroundViewAlpha: Flow<Float> =
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index adee7f2c..4db89d1 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -1200,9 +1200,7 @@
}
boolean isVolumeControlEnabled(@NonNull MediaDevice device) {
- return (isPlayBackInfoLocal()
- || device.getDeviceType() != MediaDevice.MediaDeviceType.TYPE_CAST_GROUP_DEVICE)
- && !device.isVolumeFixed();
+ return !device.isVolumeFixed();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
index d247122..f08bc17 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorComponent.kt
@@ -25,8 +25,8 @@
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.mediaprojection.appselector.data.ActivityTaskManagerLabelLoader
import com.android.systemui.mediaprojection.appselector.data.ActivityTaskManagerThumbnailLoader
-import com.android.systemui.mediaprojection.appselector.data.AppIconLoader
-import com.android.systemui.mediaprojection.appselector.data.IconLoaderLibAppIconLoader
+import com.android.systemui.mediaprojection.appselector.data.BasicAppIconLoader
+import com.android.systemui.mediaprojection.appselector.data.BasicPackageManagerAppIconLoader
import com.android.systemui.mediaprojection.appselector.data.RecentTaskLabelLoader
import com.android.systemui.mediaprojection.appselector.data.RecentTaskListProvider
import com.android.systemui.mediaprojection.appselector.data.RecentTaskThumbnailLoader
@@ -102,7 +102,7 @@
@Binds
@MediaProjectionAppSelectorScope
- fun bindAppIconLoader(impl: IconLoaderLibAppIconLoader): AppIconLoader
+ fun bindAppIconLoader(impl: BasicPackageManagerAppIconLoader): BasicAppIconLoader
@Binds
@IntoSet
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/BadgedAppIconLoader.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/BadgedAppIconLoader.kt
new file mode 100644
index 0000000..ca5b5f8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/BadgedAppIconLoader.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2024 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.mediaprojection.appselector.data
+
+import android.content.ComponentName
+import android.content.Context
+import android.graphics.drawable.Drawable
+import android.os.UserHandle
+import com.android.launcher3.icons.BaseIconFactory
+import com.android.launcher3.icons.IconFactory
+import com.android.launcher3.util.UserIconInfo
+import com.android.systemui.dagger.qualifiers.Background
+import javax.inject.Inject
+import javax.inject.Provider
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.withContext
+
+class BadgedAppIconLoader
+@Inject
+constructor(
+ private val basicAppIconLoader: BasicAppIconLoader,
+ @Background private val backgroundDispatcher: CoroutineDispatcher,
+ private val context: Context,
+ private val iconFactoryProvider: Provider<IconFactory>,
+) {
+
+ suspend fun loadIcon(
+ userId: Int,
+ userType: RecentTask.UserType,
+ componentName: ComponentName
+ ): Drawable? =
+ withContext(backgroundDispatcher) {
+ iconFactoryProvider.get().use<IconFactory, Drawable?> { iconFactory ->
+ val icon =
+ basicAppIconLoader.loadIcon(userId, componentName) ?: return@withContext null
+ val userHandler = UserHandle.of(userId)
+ val iconType = getIconType(userType)
+ val options =
+ BaseIconFactory.IconOptions().apply {
+ setUser(UserIconInfo(userHandler, iconType))
+ }
+ val badgedIcon = iconFactory.createBadgedIconBitmap(icon, options)
+ badgedIcon.newIcon(context)
+ }
+ }
+
+ private fun getIconType(userType: RecentTask.UserType): Int =
+ when (userType) {
+ RecentTask.UserType.CLONED -> UserIconInfo.TYPE_CLONED
+ RecentTask.UserType.WORK -> UserIconInfo.TYPE_WORK
+ RecentTask.UserType.PRIVATE -> UserIconInfo.TYPE_PRIVATE
+ RecentTask.UserType.STANDARD -> UserIconInfo.TYPE_MAIN
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/AppIconLoader.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/BasicAppIconLoader.kt
similarity index 61%
rename from packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/AppIconLoader.kt
rename to packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/BasicAppIconLoader.kt
index b85d628..03f6f01 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/AppIconLoader.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/BasicAppIconLoader.kt
@@ -17,45 +17,29 @@
package com.android.systemui.mediaprojection.appselector.data
import android.content.ComponentName
-import android.content.Context
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
-import android.os.UserHandle
-import com.android.launcher3.icons.BaseIconFactory.IconOptions
-import com.android.launcher3.icons.IconFactory
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.shared.system.PackageManagerWrapper
import javax.inject.Inject
-import javax.inject.Provider
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
-interface AppIconLoader {
+interface BasicAppIconLoader {
suspend fun loadIcon(userId: Int, component: ComponentName): Drawable?
}
-class IconLoaderLibAppIconLoader
+class BasicPackageManagerAppIconLoader
@Inject
constructor(
@Background private val backgroundDispatcher: CoroutineDispatcher,
- private val context: Context,
// Use wrapper to access hidden API that allows to get ActivityInfo for any user id
private val packageManagerWrapper: PackageManagerWrapper,
private val packageManager: PackageManager,
- private val iconFactoryProvider: Provider<IconFactory>
-) : AppIconLoader {
+) : BasicAppIconLoader {
override suspend fun loadIcon(userId: Int, component: ComponentName): Drawable? =
withContext(backgroundDispatcher) {
- iconFactoryProvider.get().use<IconFactory, Drawable?> { iconFactory ->
- val activityInfo =
- packageManagerWrapper.getActivityInfo(component, userId)
- ?: return@withContext null
- val icon = activityInfo.loadIcon(packageManager) ?: return@withContext null
- val userHandler = UserHandle.of(userId)
- val options = IconOptions().apply { setUser(userHandler) }
- val badgedIcon = iconFactory.createBadgedIconBitmap(icon, options)
- badgedIcon.newIcon(context)
- }
+ packageManagerWrapper.getActivityInfo(component, userId)?.loadIcon(packageManager)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTask.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTask.kt
index e9b4582..3e9b546 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTask.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTask.kt
@@ -28,4 +28,12 @@
val baseIntentComponent: ComponentName?,
@ColorInt val colorBackground: Int?,
val isForegroundTask: Boolean,
-)
+ val userType: UserType,
+) {
+ enum class UserType {
+ STANDARD,
+ WORK,
+ PRIVATE,
+ CLONED
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskListProvider.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskListProvider.kt
index 5dde14b..a6049c8 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskListProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/data/RecentTaskListProvider.kt
@@ -17,6 +17,8 @@
package com.android.systemui.mediaprojection.appselector.data
import android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE
+import android.content.pm.UserInfo
+import android.os.UserManager
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.settings.UserTracker
import com.android.systemui.util.kotlin.getOrNull
@@ -41,7 +43,8 @@
@Background private val coroutineDispatcher: CoroutineDispatcher,
@Background private val backgroundExecutor: Executor,
private val recentTasks: Optional<RecentTasks>,
- private val userTracker: UserTracker
+ private val userTracker: UserTracker,
+ private val userManager: UserManager,
) : RecentTaskListProvider {
private val recents by lazy { recentTasks.getOrNull() }
@@ -65,7 +68,8 @@
it.topActivity,
it.baseIntent?.component,
it.taskDescription?.backgroundColor,
- isForegroundTask = it.taskId in foregroundTaskIds && it.isVisible
+ isForegroundTask = it.taskId in foregroundTaskIds && it.isVisible,
+ userType = userManager.getUserInfo(it.userId).toUserType(),
)
}
}
@@ -81,4 +85,15 @@
continuation.resume(tasks)
}
}
+
+ private fun UserInfo.toUserType(): RecentTask.UserType =
+ if (isCloneProfile) {
+ RecentTask.UserType.CLONED
+ } else if (isManagedProfile) {
+ RecentTask.UserType.WORK
+ } else if (isPrivateProfile) {
+ RecentTask.UserType.PRIVATE
+ } else {
+ RecentTask.UserType.STANDARD
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt
index 3fe040a..3b84d2c 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/appselector/view/RecentTaskViewHolder.kt
@@ -21,12 +21,12 @@
import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
-import com.android.systemui.res.R
import com.android.systemui.mediaprojection.appselector.MediaProjectionAppSelector
-import com.android.systemui.mediaprojection.appselector.data.AppIconLoader
+import com.android.systemui.mediaprojection.appselector.data.BadgedAppIconLoader
import com.android.systemui.mediaprojection.appselector.data.RecentTask
import com.android.systemui.mediaprojection.appselector.data.RecentTaskLabelLoader
import com.android.systemui.mediaprojection.appselector.data.RecentTaskThumbnailLoader
+import com.android.systemui.res.R
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -39,7 +39,7 @@
@AssistedInject
constructor(
@Assisted private val root: ViewGroup,
- private val iconLoader: AppIconLoader,
+ private val iconLoader: BadgedAppIconLoader,
private val thumbnailLoader: RecentTaskThumbnailLoader,
private val labelLoader: RecentTaskLabelLoader,
private val taskViewSizeProvider: TaskPreviewSizeProvider,
@@ -63,7 +63,7 @@
scope.launch {
task.baseIntentComponent?.let { component ->
launch {
- val icon = iconLoader.loadIcon(task.userId, component)
+ val icon = iconLoader.loadIcon(task.userId, task.userType, component)
iconView.setImageDrawable(icon)
}
launch {
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
index b3d848c..30f33a3 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -34,7 +34,6 @@
import androidx.core.os.postDelayed
import androidx.core.view.isVisible
import androidx.dynamicanimation.animation.DynamicAnimation
-import com.android.internal.jank.Cuj.CUJ_BACK_PANEL_ARROW
import com.android.internal.jank.InteractionJankMonitor
import com.android.internal.util.LatencyTracker
import com.android.systemui.dagger.qualifiers.Main
@@ -1039,7 +1038,7 @@
override fun dump(pw: PrintWriter) {
pw.println("$TAG:")
pw.println(" currentState=$currentState")
- pw.println(" isLeftPanel=$mView.isLeftPanel")
+ pw.println(" isLeftPanel=${mView.isLeftPanel}")
}
init {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
index 4c86471..4e0b576 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt
@@ -25,12 +25,15 @@
import com.android.systemui.qs.FooterActionsController
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
import com.android.systemui.qs.ui.adapter.QSSceneAdapter
+import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.settings.brightness.ui.viewModel.BrightnessMirrorViewModel
import com.android.systemui.shade.ui.viewmodel.ShadeHeaderViewModel
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
/** Models UI state and handles user input for the quick settings scene. */
@@ -44,20 +47,23 @@
val notifications: NotificationsPlaceholderViewModel,
private val footerActionsViewModelFactory: FooterActionsViewModel.Factory,
private val footerActionsController: FooterActionsController,
+ private val sceneInteractor: SceneInteractor,
) {
val destinationScenes =
- qsSceneAdapter.isCustomizing.map { customizing ->
+ qsSceneAdapter.isCustomizing.flatMapLatest { customizing ->
if (customizing) {
// TODO(b/332749288) Empty map so there are no back handlers and back can close
// customizer
- emptyMap()
+ flowOf(emptyMap())
// TODO(b/330200163) Add an Up from Bottom to be able to collapse the shade
// while customizing
} else {
- mapOf(
- Back to UserActionResult(Scenes.Shade),
- Swipe(SwipeDirection.Up) to UserActionResult(Scenes.Shade),
- )
+ sceneInteractor.previousScene.map { previousScene ->
+ mapOf(
+ Back to UserActionResult(previousScene ?: Scenes.Shade),
+ Swipe(SwipeDirection.Up) to UserActionResult(previousScene ?: Scenes.Shade),
+ )
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
index f69021f..0ccb19c 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionsProvider.kt
@@ -29,7 +29,7 @@
import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED
import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_SHARE_TAPPED
import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_SMART_ACTION_TAPPED
-import com.android.systemui.screenshot.ui.viewmodel.ActionButtonViewModel
+import com.android.systemui.screenshot.ui.viewmodel.ActionButtonAppearance
import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@@ -81,65 +81,67 @@
}
}
viewModel.addAction(
- ActionButtonViewModel(
+ ActionButtonAppearance(
AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_edit),
context.resources.getString(R.string.screenshot_edit_label),
context.resources.getString(R.string.screenshot_edit_description),
- ) {
- debugLog(LogConfig.DEBUG_ACTIONS) { "Edit tapped" }
- uiEventLogger.log(SCREENSHOT_EDIT_TAPPED, 0, request.packageNameString)
- onDeferrableActionTapped { result ->
- actionExecutor.startSharedTransition(
- createEdit(result.uri, context),
- result.user,
- true
- )
- }
+ )
+ ) {
+ debugLog(LogConfig.DEBUG_ACTIONS) { "Edit tapped" }
+ uiEventLogger.log(SCREENSHOT_EDIT_TAPPED, 0, request.packageNameString)
+ onDeferrableActionTapped { result ->
+ actionExecutor.startSharedTransition(
+ createEdit(result.uri, context),
+ result.user,
+ true
+ )
}
- )
+ }
+
viewModel.addAction(
- ActionButtonViewModel(
+ ActionButtonAppearance(
AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_share),
context.resources.getString(R.string.screenshot_share_label),
context.resources.getString(R.string.screenshot_share_description),
- ) {
- debugLog(LogConfig.DEBUG_ACTIONS) { "Share tapped" }
- uiEventLogger.log(SCREENSHOT_SHARE_TAPPED, 0, request.packageNameString)
- onDeferrableActionTapped { result ->
- actionExecutor.startSharedTransition(
- createShareWithSubject(result.uri, result.subject),
- result.user,
- false
- )
- }
+ )
+ ) {
+ debugLog(LogConfig.DEBUG_ACTIONS) { "Share tapped" }
+ uiEventLogger.log(SCREENSHOT_SHARE_TAPPED, 0, request.packageNameString)
+ onDeferrableActionTapped { result ->
+ actionExecutor.startSharedTransition(
+ createShareWithSubject(result.uri, result.subject),
+ result.user,
+ false
+ )
}
- )
+ }
+
smartActionsProvider.requestQuickShare(request, requestId) { quickShare ->
if (!quickShare.actionIntent.isImmutable) {
viewModel.addAction(
- ActionButtonViewModel(
+ ActionButtonAppearance(
quickShare.getIcon().loadDrawable(context),
quickShare.title,
quickShare.title
- ) {
- debugLog(LogConfig.DEBUG_ACTIONS) { "Quickshare tapped" }
- onDeferrableActionTapped { result ->
- uiEventLogger.log(
- SCREENSHOT_SMART_ACTION_TAPPED,
- 0,
- request.packageNameString
+ )
+ ) {
+ debugLog(LogConfig.DEBUG_ACTIONS) { "Quickshare tapped" }
+ onDeferrableActionTapped { result ->
+ uiEventLogger.log(
+ SCREENSHOT_SMART_ACTION_TAPPED,
+ 0,
+ request.packageNameString
+ )
+ val pendingIntentWithUri =
+ smartActionsProvider.wrapIntent(
+ quickShare,
+ result.uri,
+ result.subject,
+ requestId
)
- val pendingIntentWithUri =
- smartActionsProvider.wrapIntent(
- quickShare,
- result.uri,
- result.subject,
- requestId
- )
- actionExecutor.sendPendingIntent(pendingIntentWithUri)
- }
+ actionExecutor.sendPendingIntent(pendingIntentWithUri)
}
- )
+ }
} else {
Log.w(TAG, "Received immutable quick share pending intent; ignoring")
}
@@ -148,14 +150,14 @@
override fun onScrollChipReady(onClick: Runnable) {
viewModel.addAction(
- ActionButtonViewModel(
+ ActionButtonAppearance(
AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_scroll),
context.resources.getString(R.string.screenshot_scroll_label),
context.resources.getString(R.string.screenshot_scroll_label),
- ) {
- onClick.run()
- }
- )
+ )
+ ) {
+ onClick.run()
+ }
}
override fun setCompletedScreenshot(result: ScreenshotSavedResult) {
@@ -166,13 +168,19 @@
this.result = result
pendingAction?.invoke(result)
smartActionsProvider.requestSmartActions(request, requestId, result) { smartActions ->
- viewModel.addActions(
- smartActions.map {
- ActionButtonViewModel(it.getIcon().loadDrawable(context), it.title, it.title) {
- actionExecutor.sendPendingIntent(it.actionIntent)
+ smartActions.forEach {
+ smartActions.forEach { action ->
+ viewModel.addAction(
+ ActionButtonAppearance(
+ action.getIcon().loadDrawable(context),
+ action.title,
+ action.title,
+ )
+ ) {
+ actionExecutor.sendPendingIntent(action.actionIntent)
}
}
- )
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt
index a6374ae..3c5a0ec 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/binder/ActionButtonViewBinder.kt
@@ -28,16 +28,16 @@
fun bind(view: View, viewModel: ActionButtonViewModel) {
val iconView = view.requireViewById<ImageView>(R.id.overlay_action_chip_icon)
val textView = view.requireViewById<TextView>(R.id.overlay_action_chip_text)
- iconView.setImageDrawable(viewModel.icon)
- textView.text = viewModel.name
- setMargins(iconView, textView, viewModel.name?.isNotEmpty() ?: false)
+ iconView.setImageDrawable(viewModel.appearance.icon)
+ textView.text = viewModel.appearance.label
+ setMargins(iconView, textView, viewModel.appearance.label?.isNotEmpty() ?: false)
if (viewModel.onClicked != null) {
view.setOnClickListener { viewModel.onClicked.invoke() }
} else {
view.setOnClickListener(null)
}
view.tag = viewModel.id
- view.contentDescription = viewModel.description
+ view.contentDescription = viewModel.appearance.description
view.visibility = View.VISIBLE
view.alpha = 1f
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonAppearance.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonAppearance.kt
new file mode 100644
index 0000000..55a2ad2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonAppearance.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2024 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.screenshot.ui.viewmodel
+
+import android.graphics.drawable.Drawable
+
+/** Data describing how an action should be shown to the user. */
+data class ActionButtonAppearance(
+ val icon: Drawable?,
+ val label: CharSequence?,
+ val description: CharSequence,
+)
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonViewModel.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonViewModel.kt
index 97b24c1..64b0105 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ActionButtonViewModel.kt
@@ -16,19 +16,19 @@
package com.android.systemui.screenshot.ui.viewmodel
-import android.graphics.drawable.Drawable
-
data class ActionButtonViewModel(
- val icon: Drawable?,
- val name: CharSequence?,
- val description: CharSequence,
+ val appearance: ActionButtonAppearance,
+ val id: Int,
val onClicked: (() -> Unit)?,
) {
- val id: Int = getId()
-
companion object {
private var nextId = 0
private fun getId() = nextId.also { nextId += 1 }
+
+ fun withNextId(
+ appearance: ActionButtonAppearance,
+ onClicked: (() -> Unit)?
+ ): ActionButtonViewModel = ActionButtonViewModel(appearance, getId(), onClicked)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt
index ddfa69b..fa34803 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModel.kt
@@ -17,6 +17,7 @@
package com.android.systemui.screenshot.ui.viewmodel
import android.graphics.Bitmap
+import android.util.Log
import android.view.accessibility.AccessibilityManager
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@@ -39,16 +40,34 @@
_previewAction.value = onClick
}
- fun addAction(action: ActionButtonViewModel) {
+ fun addAction(actionAppearance: ActionButtonAppearance, onClicked: (() -> Unit)): Int {
val actionList = _actions.value.toMutableList()
+ val action = ActionButtonViewModel.withNextId(actionAppearance, onClicked)
actionList.add(action)
_actions.value = actionList
+ return action.id
}
- fun addActions(actions: List<ActionButtonViewModel>) {
+ fun updateActionAppearance(actionId: Int, appearance: ActionButtonAppearance) {
val actionList = _actions.value.toMutableList()
- actionList.addAll(actions)
- _actions.value = actionList
+ val index = actionList.indexOfFirst { it.id == actionId }
+ if (index >= 0) {
+ actionList[index] =
+ ActionButtonViewModel(appearance, actionId, actionList[index].onClicked)
+ _actions.value = actionList
+ } else {
+ Log.w(TAG, "Attempted to update unknown action id $actionId")
+ }
+ }
+
+ fun removeAction(actionId: Int) {
+ val actionList = _actions.value.toMutableList()
+ if (actionList.removeIf { it.id == actionId }) {
+ // Update if something was removed.
+ _actions.value = actionList
+ } else {
+ Log.w(TAG, "Attempted to remove unknown action id $actionId")
+ }
}
fun reset() {
@@ -56,4 +75,8 @@
_previewAction.value = null
_actions.value = listOf()
}
+
+ companion object {
+ const val TAG = "ScreenshotViewModel"
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
index d00081e..1568e8c0 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/ImageWallpaper.java
@@ -20,6 +20,9 @@
import static android.app.WallpaperManager.FLAG_SYSTEM;
import static android.app.WallpaperManager.SetWallpaperFlags;
+import static com.android.window.flags.Flags.offloadColorExtraction;
+
+import android.annotation.Nullable;
import android.app.WallpaperColors;
import android.app.WallpaperManager;
import android.content.Context;
@@ -135,6 +138,12 @@
mLongExecutor,
mLock,
new WallpaperLocalColorExtractor.WallpaperLocalColorExtractorCallback() {
+
+ @Override
+ public void onColorsProcessed() {
+ CanvasEngine.this.notifyColorsChanged();
+ }
+
@Override
public void onColorsProcessed(List<RectF> regions,
List<WallpaperColors> colors) {
@@ -433,6 +442,12 @@
}
@Override
+ public @Nullable WallpaperColors onComputeColors() {
+ if (!offloadColorExtraction()) return null;
+ return mWallpaperLocalColorExtractor.onComputeColors();
+ }
+
+ @Override
public boolean supportsLocalColorExtraction() {
return true;
}
@@ -469,6 +484,12 @@
}
@Override
+ public void onDimAmountChanged(float dimAmount) {
+ if (!offloadColorExtraction()) return;
+ mWallpaperLocalColorExtractor.onDimAmountChanged(dimAmount);
+ }
+
+ @Override
public void onDisplayAdded(int displayId) {
}
diff --git a/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java b/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java
index e2ec8dc..d37dfb4 100644
--- a/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractor.java
@@ -17,6 +17,8 @@
package com.android.systemui.wallpapers;
+import static com.android.window.flags.Flags.offloadColorExtraction;
+
import android.app.WallpaperColors;
import android.graphics.Bitmap;
import android.graphics.Rect;
@@ -66,6 +68,12 @@
private final List<RectF> mPendingRegions = new ArrayList<>();
private final Set<RectF> mProcessedRegions = new ArraySet<>();
+ private float mWallpaperDimAmount = 0f;
+ private WallpaperColors mWallpaperColors;
+
+ // By default we assume that colors were loaded from disk and don't need to be recomputed
+ private boolean mRecomputeColors = false;
+
@LongRunning
private final Executor mLongExecutor;
@@ -75,6 +83,12 @@
* Interface to handle the callbacks after the different steps of the color extraction
*/
public interface WallpaperLocalColorExtractorCallback {
+
+ /**
+ * Callback after the wallpaper colors have been computed
+ */
+ void onColorsProcessed();
+
/**
* Callback after the colors of new regions have been extracted
* @param regions the list of new regions that have been processed
@@ -129,7 +143,7 @@
if (displayWidth == mDisplayWidth && displayHeight == mDisplayHeight) return;
mDisplayWidth = displayWidth;
mDisplayHeight = displayHeight;
- processColorsInternal();
+ processLocalColorsInternal();
}
}
@@ -166,7 +180,8 @@
mBitmapHeight = bitmap.getHeight();
mMiniBitmap = createMiniBitmap(bitmap);
mWallpaperLocalColorExtractorCallback.onMiniBitmapUpdated();
- recomputeColors();
+ if (offloadColorExtraction() && mRecomputeColors) recomputeColorsInternal();
+ recomputeLocalColors();
}
}
@@ -184,16 +199,66 @@
if (mPages == pages) return;
mPages = pages;
if (mMiniBitmap != null && !mMiniBitmap.isRecycled()) {
- recomputeColors();
+ recomputeLocalColors();
}
}
}
- // helper to recompute colors, to be called in synchronized methods
- private void recomputeColors() {
+ /**
+ * Should be called when the dim amount of the wallpaper changes, to recompute the colors
+ */
+ public void onDimAmountChanged(float dimAmount) {
+ mLongExecutor.execute(() -> onDimAmountChangedSynchronized(dimAmount));
+ }
+
+ private void onDimAmountChangedSynchronized(float dimAmount) {
+ synchronized (mLock) {
+ if (mWallpaperDimAmount == dimAmount) return;
+ mWallpaperDimAmount = dimAmount;
+ mRecomputeColors = true;
+ recomputeColorsInternal();
+ }
+ }
+
+ /**
+ * To be called by {@link ImageWallpaper.CanvasEngine#onComputeColors}. This will either
+ * return the current wallpaper colors, or if the bitmap is not yet loaded, return null and call
+ * {@link WallpaperLocalColorExtractorCallback#onColorsProcessed()} when the colors are ready.
+ */
+ public WallpaperColors onComputeColors() {
+ mLongExecutor.execute(this::onComputeColorsSynchronized);
+ return mWallpaperColors;
+ }
+
+ private void onComputeColorsSynchronized() {
+ synchronized (mLock) {
+ if (mRecomputeColors) return;
+ mRecomputeColors = true;
+ recomputeColorsInternal();
+ }
+ }
+
+ /**
+ * helper to recompute main colors, to be called in synchronized methods
+ */
+ private void recomputeColorsInternal() {
+ if (mMiniBitmap == null) return;
+ mWallpaperColors = getWallpaperColors(mMiniBitmap, mWallpaperDimAmount);
+ mWallpaperLocalColorExtractorCallback.onColorsProcessed();
+ }
+
+ @VisibleForTesting
+ WallpaperColors getWallpaperColors(@NonNull Bitmap bitmap, float dimAmount) {
+ return WallpaperColors.fromBitmap(bitmap, dimAmount);
+ }
+
+ /**
+ * helper to recompute local colors, to be called in synchronized methods
+ */
+ private void recomputeLocalColors() {
mPendingRegions.addAll(mProcessedRegions);
mProcessedRegions.clear();
- processColorsInternal();
+ processLocalColorsInternal();
}
/**
@@ -216,7 +281,7 @@
if (!wasActive && isActive()) {
mWallpaperLocalColorExtractorCallback.onActivated();
}
- processColorsInternal();
+ processLocalColorsInternal();
}
}
@@ -353,7 +418,7 @@
* then notify the callback with the resulting colors for these regions
* This method should only be called synchronously
*/
- private void processColorsInternal() {
+ private void processLocalColorsInternal() {
/*
* if the miniBitmap is not yet loaded, that means the onBitmapChanged has not yet been
* called, and thus the wallpaper is not yet loaded. In that case, exit, the function
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
index 69cd592..e076420 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationAnimationControllerTest.java
@@ -181,7 +181,7 @@
throws RemoteException {
enableWindowMagnificationAndWaitAnimating(mWaitAnimationDuration, mAnimationCallback);
- verify(mSpyController, atLeast(2)).enableWindowMagnificationInternal(
+ verify(mSpyController, atLeast(2)).updateWindowMagnificationInternal(
mScaleCaptor.capture(),
mCenterXCaptor.capture(), mCenterYCaptor.capture(),
mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
@@ -220,7 +220,7 @@
mWaitAnimationDuration, /* targetScale= */ 1.0f,
DEFAULT_CENTER_X, DEFAULT_CENTER_Y, mAnimationCallback);
- verify(mSpyController).enableWindowMagnificationInternal(1.0f, DEFAULT_CENTER_X,
+ verify(mSpyController).updateWindowMagnificationInternal(1.0f, DEFAULT_CENTER_X,
DEFAULT_CENTER_Y, 0f, 0f);
verify(mAnimationCallback).onResult(true);
}
@@ -244,7 +244,7 @@
advanceTimeBy(mWaitAnimationDuration);
});
- verify(mSpyController, atLeast(2)).enableWindowMagnificationInternal(
+ verify(mSpyController, atLeast(2)).updateWindowMagnificationInternal(
mScaleCaptor.capture(),
mCenterXCaptor.capture(), mCenterYCaptor.capture(),
mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
@@ -299,7 +299,7 @@
advanceTimeBy(mWaitAnimationDuration);
});
- verify(mSpyController, atLeast(2)).enableWindowMagnificationInternal(
+ verify(mSpyController, atLeast(2)).updateWindowMagnificationInternal(
mScaleCaptor.capture(),
mCenterXCaptor.capture(), mCenterYCaptor.capture(),
mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
@@ -341,7 +341,7 @@
advanceTimeBy(mWaitAnimationDuration);
});
- verify(mSpyController, atLeast(2)).enableWindowMagnificationInternal(
+ verify(mSpyController, atLeast(2)).updateWindowMagnificationInternal(
mScaleCaptor.capture(),
mCenterXCaptor.capture(), mCenterYCaptor.capture(),
mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
@@ -377,7 +377,7 @@
advanceTimeBy(mWaitAnimationDuration);
});
- verify(mSpyController, atLeast(2)).enableWindowMagnificationInternal(
+ verify(mSpyController, atLeast(2)).updateWindowMagnificationInternal(
mScaleCaptor.capture(),
mCenterXCaptor.capture(), mCenterYCaptor.capture(),
mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
@@ -439,7 +439,7 @@
enableWindowMagnificationAndWaitAnimating(
mWaitAnimationDuration, Float.NaN, Float.NaN, Float.NaN, mAnimationCallback2);
- verify(mSpyController, never()).enableWindowMagnificationInternal(anyFloat(), anyFloat(),
+ verify(mSpyController, never()).updateWindowMagnificationInternal(anyFloat(), anyFloat(),
anyFloat());
verify(mAnimationCallback).onResult(false);
verify(mAnimationCallback2).onResult(true);
@@ -479,7 +479,7 @@
// Verify the method is called in
// {@link ValueAnimator.AnimatorUpdateListener#onAnimationUpdate} once and
// {@link Animator.AnimatorListener#onAnimationEnd} once in {@link ValueAnimator#end()}
- verify(mSpyController, times(2)).enableWindowMagnificationInternal(
+ verify(mSpyController, times(2)).updateWindowMagnificationInternal(
mScaleCaptor.capture(),
mCenterXCaptor.capture(), mCenterYCaptor.capture(),
mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
@@ -526,7 +526,7 @@
enableWindowMagnificationAndWaitAnimating(mWaitAnimationDuration, Float.NaN,
Float.NaN, Float.NaN, mAnimationCallback2);
- verify(mSpyController, never()).enableWindowMagnificationInternal(anyFloat(), anyFloat(),
+ verify(mSpyController, never()).updateWindowMagnificationInternal(anyFloat(), anyFloat(),
anyFloat());
verify(mSpyController, never()).deleteWindowMagnification();
verify(mAnimationCallback).onResult(false);
@@ -551,7 +551,7 @@
advanceTimeBy(mWaitAnimationDuration);
});
- verify(mSpyController, atLeast(2)).enableWindowMagnificationInternal(
+ verify(mSpyController, atLeast(2)).updateWindowMagnificationInternal(
mScaleCaptor.capture(),
mCenterXCaptor.capture(), mCenterYCaptor.capture(),
mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
@@ -720,7 +720,7 @@
enableWindowMagnificationAndWaitAnimating(mWaitAnimationDuration, mAnimationCallback);
- verify(mSpyController, never()).enableWindowMagnificationInternal(anyFloat(), anyFloat(),
+ verify(mSpyController, never()).updateWindowMagnificationInternal(anyFloat(), anyFloat(),
anyFloat());
verify(mAnimationCallback).onResult(true);
}
@@ -733,7 +733,7 @@
resetMockObjects();
deleteWindowMagnificationAndWaitAnimating(mWaitAnimationDuration, mAnimationCallback);
- verify(mSpyController, atLeast(2)).enableWindowMagnificationInternal(
+ verify(mSpyController, atLeast(2)).updateWindowMagnificationInternal(
mScaleCaptor.capture(),
mCenterXCaptor.capture(), mCenterYCaptor.capture(),
mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
@@ -790,7 +790,7 @@
// Verify the method is called in
// {@link ValueAnimator.AnimatorUpdateListener#onAnimationUpdate} once and
// {@link Animator.AnimatorListener#onAnimationEnd} once in {@link ValueAnimator#end()}
- verify(mSpyController, times(2)).enableWindowMagnificationInternal(
+ verify(mSpyController, times(2)).updateWindowMagnificationInternal(
mScaleCaptor.capture(),
mCenterXCaptor.capture(), mCenterYCaptor.capture(),
mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
@@ -835,7 +835,7 @@
// {@link ValueAnimator.AnimatorUpdateListener#onAnimationUpdate} once and
// {@link Animator.AnimatorListener#onAnimationEnd} once when running the animation at
// the final duration time.
- verify(mSpyController, times(2)).enableWindowMagnificationInternal(
+ verify(mSpyController, times(2)).updateWindowMagnificationInternal(
mScaleCaptor.capture(),
mCenterXCaptor.capture(), mCenterYCaptor.capture(),
mOffsetXCaptor.capture(), mOffsetYCaptor.capture());
@@ -1040,17 +1040,17 @@
}
@Override
- void enableWindowMagnificationInternal(float scale, float centerX, float centerY) {
- super.enableWindowMagnificationInternal(scale, centerX, centerY);
- mSpyController.enableWindowMagnificationInternal(scale, centerX, centerY);
+ void updateWindowMagnificationInternal(float scale, float centerX, float centerY) {
+ super.updateWindowMagnificationInternal(scale, centerX, centerY);
+ mSpyController.updateWindowMagnificationInternal(scale, centerX, centerY);
}
@Override
- void enableWindowMagnificationInternal(float scale, float centerX, float centerY,
+ void updateWindowMagnificationInternal(float scale, float centerX, float centerY,
float magnificationOffsetFrameRatioX, float magnificationOffsetFrameRatioY) {
- super.enableWindowMagnificationInternal(scale, centerX, centerY,
+ super.updateWindowMagnificationInternal(scale, centerX, centerY,
magnificationOffsetFrameRatioX, magnificationOffsetFrameRatioY);
- mSpyController.enableWindowMagnificationInternal(scale, centerX, centerY,
+ mSpyController.updateWindowMagnificationInternal(scale, centerX, centerY,
magnificationOffsetFrameRatioX, magnificationOffsetFrameRatioY);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
index 6f285fb..cb42078 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerTest.java
@@ -273,7 +273,7 @@
@Test
public void enableWindowMagnification_showControlAndNotifyBoundsChanged() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
@@ -341,7 +341,7 @@
@Test
public void enableWindowMagnification_systemGestureExclusionRectsIsSet() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
// Wait for Rects updated.
@@ -358,7 +358,7 @@
mWindowManager.setWindowBounds(new Rect(0, 0, screenSize, screenSize));
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
@@ -373,7 +373,7 @@
@Test
public void deleteWindowMagnification_destroyControlAndUnregisterComponentCallback() {
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN,
Float.NaN));
@@ -391,7 +391,7 @@
setSystemGestureInsets();
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
bounds.bottom);
});
ReferenceTestUtils.waitForCondition(this::hasMagnificationOverlapFlag);
@@ -407,7 +407,7 @@
@Test
public void deleteWindowMagnification_notifySourceBoundsChanged() {
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN,
Float.NaN));
@@ -423,7 +423,7 @@
@Test
public void moveMagnifier_schedulesFrame() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.moveWindowMagnifier(100f, 100f);
});
@@ -506,7 +506,7 @@
@Test
public void setScale_enabled_expectedValueAndUpdateStateDescription() {
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(2.0f,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(2.0f,
Float.NaN, Float.NaN));
mInstrumentation.runOnMainSync(() -> mWindowMagnificationController.setScale(3.0f));
@@ -539,7 +539,7 @@
final float displayWidth = windowBounds.width();
final PointF magnifiedCenter = new PointF(center, center + 5f);
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
magnifiedCenter.x, magnifiedCenter.y);
// Get the center again in case the center we set is out of screen.
magnifiedCenter.set(mWindowMagnificationController.getCenterX(),
@@ -582,7 +582,7 @@
final float expectedRatio = 0.5f;
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
@@ -621,8 +621,8 @@
preferredWindowSize.toString())
.commit();
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController
- .enableWindowMagnificationInternal(Float.NaN, Float.NaN, Float.NaN);
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
+ Float.NaN);
});
// Change screen density and size to trigger restoring the preferred window size
@@ -649,7 +649,7 @@
@Test
public void screenSizeIsChangedToLarge_enabled_defaultWindowSize() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
final int screenSize = mWindowManager.getCurrentWindowMetrics().getBounds().width() * 10;
@@ -674,7 +674,7 @@
@Test
public void onDensityChanged_enabled_updateDimensionsAndResetWindowMagnification() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
Mockito.reset(mWindowManager);
Mockito.reset(mMirrorWindowControl);
@@ -703,7 +703,7 @@
@Test
public void initializeA11yNode_enabled_expectedValues() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(2.5f, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(2.5f, Float.NaN,
Float.NaN);
});
final View mirrorView = mWindowManager.getAttachedView();
@@ -727,7 +727,7 @@
public void performA11yActions_visible_expectedResults() {
final int displayId = mContext.getDisplayId();
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(1.5f, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(1.5f, Float.NaN,
Float.NaN);
});
@@ -761,7 +761,7 @@
public void performA11yActions_visible_notifyAccessibilityActionPerformed() {
final int displayId = mContext.getDisplayId();
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(2.5f, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(2.5f, Float.NaN,
Float.NaN);
});
@@ -774,7 +774,7 @@
@Test
public void windowMagnifierEditMode_performA11yClickAction_exitEditMode() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
});
@@ -812,7 +812,7 @@
/* pbase= */ 1);
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -852,7 +852,7 @@
/* pbase= */ 1);
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -888,7 +888,7 @@
final int startingHeight = windowBounds.height();
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -908,7 +908,7 @@
final int startingHeight = windowBounds.height();
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -931,7 +931,7 @@
/* base= */ 1,
/* pbase= */ 1);
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingSize, startingSize);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -971,7 +971,7 @@
/* pbase= */ 1);
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingSize, startingSize);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -1007,7 +1007,7 @@
final int startingSize = mMinWindowSize;
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingSize, startingSize);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -1027,7 +1027,7 @@
final int startingSize = mMinWindowSize;
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingSize, startingSize);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -1043,7 +1043,7 @@
@Test
public void enableWindowMagnification_hasA11yWindowTitle() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
@@ -1054,12 +1054,12 @@
@Test
public void enableWindowMagnificationWithScaleLessThanOne_enabled_disabled() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(0.9f, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(0.9f, Float.NaN,
Float.NaN);
});
@@ -1078,7 +1078,7 @@
final int newRotation = simulateRotateTheDevice();
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN, Float.NaN));
assertEquals(newRotation, mWindowMagnificationController.mRotation);
@@ -1087,7 +1087,7 @@
@Test
public void enableWindowMagnification_registerComponentCallback() {
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN,
Float.NaN));
@@ -1098,7 +1098,7 @@
public void onLocaleChanged_enabled_updateA11yWindowTitle() {
final String newA11yWindowTitle = "new a11y window title";
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
final TestableResources testableResources = getContext().getOrCreateTestableResources();
@@ -1116,7 +1116,7 @@
@Test
public void onSingleTap_enabled_scaleAnimates() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
@@ -1143,7 +1143,7 @@
final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
setSystemGestureInsets();
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
@@ -1161,7 +1161,7 @@
setSystemGestureInsets();
mInstrumentation.runOnMainSync(
() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(
+ mWindowMagnificationController.updateWindowMagnificationInternal(
Float.NaN, Float.NaN, Float.NaN);
});
@@ -1197,7 +1197,7 @@
setSystemGestureInsets();
mInstrumentation.runOnMainSync(
() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(
+ mWindowMagnificationController.updateWindowMagnificationInternal(
Float.NaN, Float.NaN, Float.NaN);
});
@@ -1232,7 +1232,7 @@
final int expectedWindowHeight = minimumWindowSize;
final int expectedWindowWidth = minimumWindowSize;
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN, Float.NaN));
final AtomicInteger actualWindowHeight = new AtomicInteger();
@@ -1259,7 +1259,7 @@
final AtomicInteger actualWindowWidth = new AtomicInteger();
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.setWindowSize(expectedWindowWidth, expectedWindowHeight);
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN, Float.NaN);
actualWindowHeight.set(mWindowManager.getLayoutParamsFromAttachedView().height);
actualWindowWidth.set(mWindowManager.getLayoutParamsFromAttachedView().width);
@@ -1274,7 +1274,7 @@
final int minimumWindowSize = mResources.getDimensionPixelSize(
com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN, Float.NaN));
final AtomicInteger actualWindowHeight = new AtomicInteger();
@@ -1294,7 +1294,7 @@
public void setWindowSizeLargerThanScreenSize_enabled_windowSizeIsScreenSize() {
final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN, Float.NaN));
final AtomicInteger actualWindowHeight = new AtomicInteger();
@@ -1323,7 +1323,7 @@
mInstrumentation.runOnMainSync(
() ->
- mWindowMagnificationController.enableWindowMagnificationInternal(
+ mWindowMagnificationController.updateWindowMagnificationInternal(
Float.NaN, Float.NaN, Float.NaN));
final AtomicInteger actualWindowHeight = new AtomicInteger();
@@ -1348,7 +1348,7 @@
mInstrumentation.runOnMainSync(
() ->
- mWindowMagnificationController.enableWindowMagnificationInternal(
+ mWindowMagnificationController.updateWindowMagnificationInternal(
Float.NaN, Float.NaN, Float.NaN));
final AtomicInteger actualWindowHeight = new AtomicInteger();
@@ -1382,7 +1382,7 @@
mInstrumentation.runOnMainSync(
() ->
- mWindowMagnificationController.enableWindowMagnificationInternal(
+ mWindowMagnificationController.updateWindowMagnificationInternal(
Float.NaN, Float.NaN, Float.NaN));
final AtomicInteger actualWindowHeight = new AtomicInteger();
@@ -1408,7 +1408,7 @@
com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN, Float.NaN));
final AtomicInteger magnificationCenterX = new AtomicInteger();
@@ -1429,7 +1429,7 @@
final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
mInstrumentation.runOnMainSync(
() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(
+ mWindowMagnificationController.updateWindowMagnificationInternal(
1.5f, bounds.centerX(), bounds.centerY());
});
View dragButton = getInternalView(R.id.drag_handle);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
index e9d36b8..a88654b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/WindowMagnificationControllerWindowlessMagnifierTest.java
@@ -282,7 +282,7 @@
@Test
public void enableWindowMagnification_showControlAndNotifyBoundsChanged() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
@@ -351,7 +351,7 @@
@Test
public void enableWindowMagnification_systemGestureExclusionRectsIsSet() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
// Wait for Rects updated.
@@ -368,7 +368,7 @@
mWindowManager.setWindowBounds(new Rect(0, 0, screenSize, screenSize));
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
@@ -383,7 +383,7 @@
@Test
public void deleteWindowMagnification_destroyControlAndUnregisterComponentCallback() {
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN,
Float.NaN));
@@ -401,7 +401,7 @@
setSystemGestureInsets();
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
bounds.bottom);
});
ReferenceTestUtils.waitForCondition(this::hasMagnificationOverlapFlag);
@@ -417,7 +417,7 @@
@Test
public void deleteWindowMagnification_notifySourceBoundsChanged() {
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN,
Float.NaN));
@@ -433,7 +433,7 @@
@Test
public void moveMagnifier_schedulesFrame() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
@@ -520,7 +520,7 @@
@Test
public void setScale_enabled_expectedValueAndUpdateStateDescription() {
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(2.0f,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(2.0f,
Float.NaN, Float.NaN));
mInstrumentation.runOnMainSync(() -> mWindowMagnificationController.setScale(3.0f));
@@ -553,7 +553,7 @@
final float displayWidth = windowBounds.width();
final PointF magnifiedCenter = new PointF(center, center + 5f);
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
magnifiedCenter.x, magnifiedCenter.y);
// Get the center again in case the center we set is out of screen.
magnifiedCenter.set(mWindowMagnificationController.getCenterX(),
@@ -596,7 +596,7 @@
final float expectedRatio = 0.5f;
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
@@ -635,8 +635,8 @@
preferredWindowSize.toString())
.commit();
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController
- .enableWindowMagnificationInternal(Float.NaN, Float.NaN, Float.NaN);
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
+ Float.NaN);
});
// Screen density and size change
@@ -663,7 +663,7 @@
@Test
public void screenSizeIsChangedToLarge_enabled_defaultWindowSize() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
final int screenSize = mWindowManager.getCurrentWindowMetrics().getBounds().width() * 10;
@@ -688,7 +688,7 @@
@Test
public void onDensityChanged_enabled_updateDimensionsAndResetWindowMagnification() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
Mockito.reset(mWindowManager);
Mockito.reset(mMirrorWindowControl);
@@ -717,7 +717,7 @@
@Test
public void initializeA11yNode_enabled_expectedValues() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(2.5f, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(2.5f, Float.NaN,
Float.NaN);
});
final View mirrorView = mSurfaceControlViewHost.getView();
@@ -741,7 +741,7 @@
public void performA11yActions_visible_expectedResults() {
final int displayId = mContext.getDisplayId();
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(1.5f, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(1.5f, Float.NaN,
Float.NaN);
});
@@ -775,7 +775,7 @@
public void performA11yActions_visible_notifyAccessibilityActionPerformed() {
final int displayId = mContext.getDisplayId();
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(2.5f, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(2.5f, Float.NaN,
Float.NaN);
});
@@ -788,7 +788,7 @@
@Test
public void windowMagnifierEditMode_performA11yClickAction_exitEditMode() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
});
@@ -829,7 +829,7 @@
/* pbase= */ 1);
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -871,7 +871,7 @@
/* pbase= */ 1);
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -909,7 +909,7 @@
final int startingHeight = windowBounds.height();
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -929,7 +929,7 @@
final int startingHeight = windowBounds.height();
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingWidth, startingHeight);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -952,7 +952,7 @@
/* base= */ 1,
/* pbase= */ 1);
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingSize, startingSize);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -994,7 +994,7 @@
/* pbase= */ 1);
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingSize, startingSize);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -1032,7 +1032,7 @@
final int startingSize = mMinWindowSize;
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingSize, startingSize);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -1052,7 +1052,7 @@
final int startingSize = mMinWindowSize;
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
mWindowMagnificationController.setWindowSize(startingSize, startingSize);
mWindowMagnificationController.setEditMagnifierSizeMode(true);
@@ -1068,7 +1068,7 @@
@Test
public void enableWindowMagnification_hasA11yWindowTitle() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
@@ -1079,12 +1079,12 @@
@Test
public void enableWindowMagnificationWithScaleLessThanOne_enabled_disabled() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(0.9f, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(0.9f, Float.NaN,
Float.NaN);
});
@@ -1103,7 +1103,7 @@
final int newRotation = simulateRotateTheDevice();
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN, Float.NaN));
assertEquals(newRotation, mWindowMagnificationController.mRotation);
@@ -1112,7 +1112,7 @@
@Test
public void enableWindowMagnification_registerComponentCallback() {
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN,
Float.NaN));
@@ -1123,7 +1123,7 @@
public void onLocaleChanged_enabled_updateA11yWindowTitle() {
final String newA11yWindowTitle = "new a11y window title";
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
final TestableResources testableResources = getContext().getOrCreateTestableResources();
@@ -1141,7 +1141,7 @@
@Test
public void onSingleTap_enabled_scaleAnimates() {
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
@@ -1168,7 +1168,7 @@
final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
setSystemGestureInsets();
mInstrumentation.runOnMainSync(() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN, Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN, Float.NaN,
Float.NaN);
});
@@ -1186,7 +1186,7 @@
setSystemGestureInsets();
mInstrumentation.runOnMainSync(
() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(
+ mWindowMagnificationController.updateWindowMagnificationInternal(
Float.NaN, Float.NaN, Float.NaN);
});
// Wait for Region updated.
@@ -1215,7 +1215,7 @@
setSystemGestureInsets();
mInstrumentation.runOnMainSync(
() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(
+ mWindowMagnificationController.updateWindowMagnificationInternal(
Float.NaN, Float.NaN, Float.NaN);
});
// Wait for Region updated.
@@ -1244,7 +1244,7 @@
final int expectedWindowHeight = minimumWindowSize;
final int expectedWindowWidth = minimumWindowSize;
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN, Float.NaN));
final AtomicInteger actualWindowHeight = new AtomicInteger();
@@ -1271,7 +1271,7 @@
final AtomicInteger actualWindowWidth = new AtomicInteger();
mInstrumentation.runOnMainSync(() -> {
mWindowMagnificationController.setWindowSize(expectedWindowWidth, expectedWindowHeight);
- mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN, Float.NaN);
actualWindowHeight.set(mSurfaceControlViewHost.getView().getLayoutParams().height);
actualWindowWidth.set(mSurfaceControlViewHost.getView().getLayoutParams().width);
@@ -1286,7 +1286,7 @@
final int minimumWindowSize = mResources.getDimensionPixelSize(
com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN, Float.NaN));
final AtomicInteger actualWindowHeight = new AtomicInteger();
@@ -1306,7 +1306,7 @@
public void setWindowSizeLargerThanScreenSize_enabled_windowSizeIsScreenSize() {
final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN, Float.NaN));
final AtomicInteger actualWindowHeight = new AtomicInteger();
@@ -1335,7 +1335,7 @@
mInstrumentation.runOnMainSync(
() ->
- mWindowMagnificationController.enableWindowMagnificationInternal(
+ mWindowMagnificationController.updateWindowMagnificationInternal(
Float.NaN, Float.NaN, Float.NaN));
final AtomicInteger actualWindowHeight = new AtomicInteger();
@@ -1362,7 +1362,7 @@
mInstrumentation.runOnMainSync(
() ->
- mWindowMagnificationController.enableWindowMagnificationInternal(
+ mWindowMagnificationController.updateWindowMagnificationInternal(
Float.NaN, Float.NaN, Float.NaN));
final AtomicInteger actualWindowHeight = new AtomicInteger();
@@ -1398,7 +1398,7 @@
mInstrumentation.runOnMainSync(
() ->
- mWindowMagnificationController.enableWindowMagnificationInternal(
+ mWindowMagnificationController.updateWindowMagnificationInternal(
Float.NaN, Float.NaN, Float.NaN));
final AtomicInteger actualWindowHeight = new AtomicInteger();
@@ -1426,7 +1426,7 @@
com.android.internal.R.dimen.accessibility_window_magnifier_min_size);
final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
mInstrumentation.runOnMainSync(
- () -> mWindowMagnificationController.enableWindowMagnificationInternal(Float.NaN,
+ () -> mWindowMagnificationController.updateWindowMagnificationInternal(Float.NaN,
Float.NaN, Float.NaN));
final AtomicInteger magnificationCenterX = new AtomicInteger();
@@ -1447,7 +1447,7 @@
final Rect bounds = mWindowManager.getCurrentWindowMetrics().getBounds();
mInstrumentation.runOnMainSync(
() -> {
- mWindowMagnificationController.enableWindowMagnificationInternal(
+ mWindowMagnificationController.updateWindowMagnificationInternal(
1.5f, bounds.centerX(), bounds.centerY());
});
View dragButton = getInternalView(R.id.drag_handle);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt
index 44798ea..8b79fa4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/MediaProjectionAppSelectorControllerTest.kt
@@ -257,6 +257,7 @@
userId = userId,
colorBackground = 0,
isForegroundTask = isForegroundTask,
+ userType = RecentTask.UserType.STANDARD,
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/data/IconLoaderLibAppIconLoaderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/data/BasicPackageManagerAppIconLoaderTest.kt
similarity index 78%
rename from packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/data/IconLoaderLibAppIconLoaderTest.kt
rename to packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/data/BasicPackageManagerAppIconLoaderTest.kt
index 9b346d0..fa1c8f8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/data/IconLoaderLibAppIconLoaderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/data/BasicPackageManagerAppIconLoaderTest.kt
@@ -20,15 +20,10 @@
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.graphics.Bitmap
-import android.graphics.drawable.Drawable
import androidx.test.filters.SmallTest
-import com.android.launcher3.icons.BitmapInfo
import com.android.launcher3.icons.FastBitmapDrawable
-import com.android.launcher3.icons.IconFactory
import com.android.systemui.SysuiTestCase
import com.android.systemui.shared.system.PackageManagerWrapper
-import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
@@ -40,20 +35,17 @@
@SmallTest
@RunWith(JUnit4::class)
-class IconLoaderLibAppIconLoaderTest : SysuiTestCase() {
+class BasicPackageManagerAppIconLoaderTest : SysuiTestCase() {
- private val iconFactory: IconFactory = mock()
private val packageManagerWrapper: PackageManagerWrapper = mock()
private val packageManager: PackageManager = mock()
private val dispatcher = Dispatchers.Unconfined
private val appIconLoader =
- IconLoaderLibAppIconLoader(
+ BasicPackageManagerAppIconLoader(
backgroundDispatcher = dispatcher,
- context = context,
packageManagerWrapper = packageManagerWrapper,
packageManager = packageManager,
- iconFactoryProvider = { iconFactory }
)
@Test
@@ -70,12 +62,7 @@
private fun givenIcon(component: ComponentName, userId: Int, icon: FastBitmapDrawable) {
val activityInfo = mock<ActivityInfo>()
whenever(packageManagerWrapper.getActivityInfo(component, userId)).thenReturn(activityInfo)
- val rawIcon = mock<Drawable>()
- whenever(activityInfo.loadIcon(packageManager)).thenReturn(rawIcon)
-
- val bitmapInfo = mock<BitmapInfo>()
- whenever(iconFactory.createBadgedIconBitmap(eq(rawIcon), any())).thenReturn(bitmapInfo)
- whenever(bitmapInfo.newIcon(context)).thenReturn(icon)
+ whenever(activityInfo.loadIcon(packageManager)).thenReturn(icon)
}
private fun createIcon(): FastBitmapDrawable =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/data/ShellRecentTaskListProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/data/ShellRecentTaskListProviderTest.kt
index b593def..dd62112 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/data/ShellRecentTaskListProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/data/ShellRecentTaskListProviderTest.kt
@@ -1,9 +1,15 @@
package com.android.systemui.mediaprojection.appselector.data
import android.app.ActivityManager.RecentTaskInfo
+import android.content.pm.UserInfo
+import android.os.UserManager
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.mediaprojection.appselector.data.RecentTask.UserType.CLONED
+import com.android.systemui.mediaprojection.appselector.data.RecentTask.UserType.PRIVATE
+import com.android.systemui.mediaprojection.appselector.data.RecentTask.UserType.STANDARD
+import com.android.systemui.mediaprojection.appselector.data.RecentTask.UserType.WORK
import com.android.systemui.settings.UserTracker
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
@@ -17,6 +23,7 @@
import kotlinx.coroutines.runBlocking
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
@RunWith(AndroidTestingRunner::class)
@SmallTest
@@ -25,12 +32,16 @@
private val dispatcher = Dispatchers.Unconfined
private val recentTasks: RecentTasks = mock()
private val userTracker: UserTracker = mock()
+ private val userManager: UserManager = mock {
+ whenever(getUserInfo(anyInt())).thenReturn(mock())
+ }
private val recentTaskListProvider =
ShellRecentTaskListProvider(
dispatcher,
Runnable::run,
Optional.of(recentTasks),
- userTracker
+ userTracker,
+ userManager,
)
@Test
@@ -147,6 +158,22 @@
.inOrder()
}
+ @Test
+ fun loadRecentTasks_assignsCorrectUserType() {
+ givenRecentTasks(
+ createSingleTask(taskId = 1, userId = 10, userType = STANDARD),
+ createSingleTask(taskId = 2, userId = 20, userType = WORK),
+ createSingleTask(taskId = 3, userId = 30, userType = CLONED),
+ createSingleTask(taskId = 4, userId = 40, userType = PRIVATE),
+ )
+
+ val result = runBlocking { recentTaskListProvider.loadRecentTasks() }
+
+ assertThat(result.map { it.userType })
+ .containsExactly(STANDARD, WORK, CLONED, PRIVATE)
+ .inOrder()
+ }
+
@Suppress("UNCHECKED_CAST")
private fun givenRecentTasks(vararg tasks: GroupedRecentTaskInfo) {
whenever(recentTasks.getRecentTasks(any(), any(), any(), any(), any())).thenAnswer {
@@ -155,7 +182,10 @@
}
}
- private fun createRecentTask(taskId: Int): RecentTask =
+ private fun createRecentTask(
+ taskId: Int,
+ userType: RecentTask.UserType = STANDARD
+ ): RecentTask =
RecentTask(
taskId = taskId,
displayId = 0,
@@ -164,25 +194,42 @@
baseIntentComponent = null,
colorBackground = null,
isForegroundTask = false,
+ userType = userType,
)
- private fun createSingleTask(taskId: Int, isVisible: Boolean = false): GroupedRecentTaskInfo =
- GroupedRecentTaskInfo.forSingleTask(createTaskInfo(taskId, isVisible))
+ private fun createSingleTask(
+ taskId: Int,
+ userId: Int = 0,
+ isVisible: Boolean = false,
+ userType: RecentTask.UserType = STANDARD,
+ ): GroupedRecentTaskInfo {
+ val userInfo =
+ mock<UserInfo> {
+ whenever(isCloneProfile).thenReturn(userType == CLONED)
+ whenever(isManagedProfile).thenReturn(userType == WORK)
+ whenever(isPrivateProfile).thenReturn(userType == PRIVATE)
+ }
+ whenever(userManager.getUserInfo(userId)).thenReturn(userInfo)
+ return GroupedRecentTaskInfo.forSingleTask(createTaskInfo(taskId, userId, isVisible))
+ }
private fun createTaskPair(
taskId1: Int,
+ userId1: Int = 0,
taskId2: Int,
+ userId2: Int = 0,
isVisible: Boolean = false
): GroupedRecentTaskInfo =
GroupedRecentTaskInfo.forSplitTasks(
- createTaskInfo(taskId1, isVisible),
- createTaskInfo(taskId2, isVisible),
+ createTaskInfo(taskId1, userId1, isVisible),
+ createTaskInfo(taskId2, userId2, isVisible),
null
)
- private fun createTaskInfo(taskId: Int, isVisible: Boolean = false) =
+ private fun createTaskInfo(taskId: Int, userId: Int, isVisible: Boolean = false) =
RecentTaskInfo().apply {
this.taskId = taskId
this.isVisible = isVisible
+ this.userId = userId
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewControllerTest.kt
index ac41073..a84008b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/mediaprojection/appselector/view/MediaProjectionRecentsViewControllerTest.kt
@@ -56,7 +56,8 @@
topActivityComponent = null,
baseIntentComponent = null,
colorBackground = null,
- isForegroundTask = false
+ isForegroundTask = false,
+ userType = RecentTask.UserType.STANDARD,
)
private val taskView =
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModelTest.kt
new file mode 100644
index 0000000..d44e26c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ui/viewmodel/ScreenshotViewModelTest.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2024 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.screenshot.ui.viewmodel
+
+import android.view.accessibility.AccessibilityManager
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.mockito.Mockito.mock
+
+@SmallTest
+class ScreenshotViewModelTest {
+ private val accessibilityManager: AccessibilityManager = mock(AccessibilityManager::class.java)
+ private val appearance = ActionButtonAppearance(null, "Label", "Description")
+ private val onclick = {}
+
+ @Test
+ fun testAddAction() {
+ val viewModel = ScreenshotViewModel(accessibilityManager)
+
+ assertThat(viewModel.actions.value).isEmpty()
+
+ viewModel.addAction(appearance, onclick)
+
+ assertThat(viewModel.actions.value).hasSize(1)
+
+ val added = viewModel.actions.value[0]
+ assertThat(added.appearance).isEqualTo(appearance)
+ assertThat(added.onClicked).isEqualTo(onclick)
+ }
+
+ @Test
+ fun testRemoveAction() {
+ val viewModel = ScreenshotViewModel(accessibilityManager)
+ val firstId = viewModel.addAction(ActionButtonAppearance(null, "", ""), {})
+ val secondId = viewModel.addAction(appearance, onclick)
+
+ assertThat(viewModel.actions.value).hasSize(2)
+ assertThat(firstId).isNotEqualTo(secondId)
+
+ viewModel.removeAction(firstId)
+
+ assertThat(viewModel.actions.value).hasSize(1)
+
+ val remaining = viewModel.actions.value[0]
+ assertThat(remaining.appearance).isEqualTo(appearance)
+ assertThat(remaining.onClicked).isEqualTo(onclick)
+ }
+
+ @Test
+ fun testUpdateActionAppearance() {
+ val viewModel = ScreenshotViewModel(accessibilityManager)
+ val id = viewModel.addAction(appearance, onclick)
+ val otherAppearance = ActionButtonAppearance(null, "Other", "Other")
+
+ viewModel.updateActionAppearance(id, otherAppearance)
+
+ assertThat(viewModel.actions.value).hasSize(1)
+ val updated = viewModel.actions.value[0]
+ assertThat(updated.appearance).isEqualTo(otherAppearance)
+ assertThat(updated.onClicked).isEqualTo(onclick)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractorTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractorTest.java
index 1125d41..0eba21a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/WallpaperLocalColorExtractorTest.java
@@ -16,9 +16,12 @@
package com.android.systemui.wallpapers;
+import static com.android.window.flags.Flags.FLAG_OFFLOAD_COLOR_EXTRACTION;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
@@ -32,6 +35,7 @@
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.platform.test.annotations.EnableFlags;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -77,6 +81,7 @@
private Executor mBackgroundExecutor;
private int mColorsProcessed;
+ private int mLocalColorsProcessed;
private int mMiniBitmapUpdatedCount;
private int mActivatedCount;
private int mDeactivatedCount;
@@ -93,6 +98,7 @@
private void resetCounters() {
mColorsProcessed = 0;
+ mLocalColorsProcessed = 0;
mMiniBitmapUpdatedCount = 0;
mActivatedCount = 0;
mDeactivatedCount = 0;
@@ -112,10 +118,14 @@
new Object(),
new WallpaperLocalColorExtractor.WallpaperLocalColorExtractorCallback() {
@Override
+ public void onColorsProcessed() {
+ mColorsProcessed++;
+ }
+ @Override
public void onColorsProcessed(List<RectF> regions,
List<WallpaperColors> colors) {
assertThat(regions.size()).isEqualTo(colors.size());
- mColorsProcessed += regions.size();
+ mLocalColorsProcessed += regions.size();
}
@Override
@@ -148,8 +158,10 @@
.when(spyColorExtractor)
.createMiniBitmap(any(Bitmap.class), anyInt(), anyInt());
- doReturn(new WallpaperColors(Color.valueOf(0), Color.valueOf(0), Color.valueOf(0)))
- .when(spyColorExtractor).getLocalWallpaperColors(any(Rect.class));
+ WallpaperColors colors = new WallpaperColors(
+ Color.valueOf(0), Color.valueOf(0), Color.valueOf(0));
+ doReturn(colors).when(spyColorExtractor).getLocalWallpaperColors(any(Rect.class));
+ doReturn(colors).when(spyColorExtractor).getWallpaperColors(any(Bitmap.class), anyFloat());
return spyColorExtractor;
}
@@ -244,7 +256,7 @@
assertThat(mActivatedCount).isEqualTo(1);
assertThat(mMiniBitmapUpdatedCount).isEqualTo(1);
- assertThat(mColorsProcessed).isEqualTo(regions.size());
+ assertThat(mLocalColorsProcessed).isEqualTo(regions.size());
spyColorExtractor.removeLocalColorAreas(regions);
assertThat(mDeactivatedCount).isEqualTo(1);
@@ -329,12 +341,69 @@
spyColorExtractor.onBitmapChanged(newBitmap);
assertThat(mMiniBitmapUpdatedCount).isEqualTo(1);
}
- assertThat(mColorsProcessed).isEqualTo(regions.size());
+ assertThat(mLocalColorsProcessed).isEqualTo(regions.size());
}
spyColorExtractor.removeLocalColorAreas(regions);
assertThat(mDeactivatedCount).isEqualTo(1);
}
+ /**
+ * Test that after the bitmap changes, the colors are computed only if asked via onComputeColors
+ */
+ @Test
+ @EnableFlags(FLAG_OFFLOAD_COLOR_EXTRACTION)
+ public void testRecomputeColors() {
+ resetCounters();
+ Bitmap bitmap = getMockBitmap(HIGH_BMP_WIDTH, HIGH_BMP_HEIGHT);
+ WallpaperLocalColorExtractor spyColorExtractor = getSpyWallpaperLocalColorExtractor();
+ spyColorExtractor.onBitmapChanged(bitmap);
+ assertThat(mColorsProcessed).isEqualTo(0);
+ spyColorExtractor.onComputeColors();
+ assertThat(mColorsProcessed).isEqualTo(1);
+ }
+
+ /**
+ * Test that after onComputeColors is called, the colors are computed once the bitmap is loaded
+ */
+ @Test
+ @EnableFlags(FLAG_OFFLOAD_COLOR_EXTRACTION)
+ public void testRecomputeColorsBeforeBitmapLoaded() {
+ resetCounters();
+ Bitmap bitmap = getMockBitmap(HIGH_BMP_WIDTH, HIGH_BMP_HEIGHT);
+ WallpaperLocalColorExtractor spyColorExtractor = getSpyWallpaperLocalColorExtractor();
+ spyColorExtractor.onComputeColors();
+ spyColorExtractor.onBitmapChanged(bitmap);
+ assertThat(mColorsProcessed).isEqualTo(1);
+ }
+
+ /**
+ * Test that after the dim changes, the colors are computed if the bitmap is already loaded
+ */
+ @Test
+ @EnableFlags(FLAG_OFFLOAD_COLOR_EXTRACTION)
+ public void testRecomputeColorsOnDimChanged() {
+ resetCounters();
+ Bitmap bitmap = getMockBitmap(HIGH_BMP_WIDTH, HIGH_BMP_HEIGHT);
+ WallpaperLocalColorExtractor spyColorExtractor = getSpyWallpaperLocalColorExtractor();
+ spyColorExtractor.onBitmapChanged(bitmap);
+ spyColorExtractor.onDimAmountChanged(0.5f);
+ assertThat(mColorsProcessed).isEqualTo(1);
+ }
+
+ /**
+ * Test that after the dim changes, the colors will be recomputed once the bitmap is loaded
+ */
+ @Test
+ @EnableFlags(FLAG_OFFLOAD_COLOR_EXTRACTION)
+ public void testRecomputeColorsOnDimChangedBeforeBitmapLoaded() {
+ resetCounters();
+ Bitmap bitmap = getMockBitmap(HIGH_BMP_WIDTH, HIGH_BMP_HEIGHT);
+ WallpaperLocalColorExtractor spyColorExtractor = getSpyWallpaperLocalColorExtractor();
+ spyColorExtractor.onDimAmountChanged(0.3f);
+ spyColorExtractor.onBitmapChanged(bitmap);
+ assertThat(mColorsProcessed).isEqualTo(1);
+ }
+
@Test
public void testCleanUp() {
resetCounters();
@@ -346,6 +415,6 @@
assertThat(mMiniBitmapUpdatedCount).isEqualTo(1);
spyColorExtractor.cleanUp();
spyColorExtractor.addLocalColorsAreas(listOfRandomAreas(MIN_AREAS, MAX_AREAS));
- assertThat(mColorsProcessed).isEqualTo(0);
+ assertThat(mLocalColorsProcessed).isEqualTo(0);
}
}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt
index f86e9b7..e6651a4 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelKosmos.kt
@@ -20,8 +20,6 @@
import com.android.systemui.common.ui.domain.interactor.configurationInteractor
import com.android.systemui.deviceentry.domain.interactor.deviceEntryUdfpsInteractor
-import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
-import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor
import com.android.systemui.keyguard.ui.keyguardTransitionAnimationFlow
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture
@@ -32,7 +30,5 @@
deviceEntryUdfpsInteractor = deviceEntryUdfpsInteractor,
configurationInteractor = configurationInteractor,
animationFlow = keyguardTransitionAnimationFlow,
- keyguardInteractor = keyguardInteractor,
- keyguardTransitionInteractor = keyguardTransitionInteractor,
)
}
diff --git a/services/Android.bp b/services/Android.bp
index 881d6e1..6235195 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -241,6 +241,7 @@
libs: [
"android.hidl.manager-V1.0-java",
"framework-tethering.stubs.module_lib",
+ "keepanno-annotations",
"service-art.stubs.system_server",
"service-permission.stubs.system_server",
"service-rkp.stubs.system_server",
diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig
index 1d6399e..bfa1c7b 100644
--- a/services/accessibility/accessibility.aconfig
+++ b/services/accessibility/accessibility.aconfig
@@ -49,6 +49,13 @@
}
flag {
+ name: "enable_a11y_checker_logging"
+ namespace: "accessibility"
+ description: "Whether to identify and log app a11y issues."
+ bug: "325420273"
+}
+
+flag {
name: "enable_magnification_joystick"
namespace: "accessibility"
description: "Whether to enable joystick controls for magnification"
diff --git a/services/autofill/bugfixes.aconfig b/services/autofill/bugfixes.aconfig
index 0a3906a..ced10fb 100644
--- a/services/autofill/bugfixes.aconfig
+++ b/services/autofill/bugfixes.aconfig
@@ -1,5 +1,4 @@
package: "android.service.autofill"
-container: "system"
flag {
name: "test"
diff --git a/services/autofill/features.aconfig b/services/autofill/features.aconfig
index 1dc3b73..c130cee 100644
--- a/services/autofill/features.aconfig
+++ b/services/autofill/features.aconfig
@@ -1,5 +1,4 @@
package: "android.service.autofill"
-container: "system"
flag {
name: "autofill_credman_integration"
diff --git a/services/core/Android.bp b/services/core/Android.bp
index fd7e4ab..392c0c7 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -182,6 +182,7 @@
"android.hardware.vibrator-V2-java",
"app-compat-annotations",
"framework-tethering.stubs.module_lib",
+ "keepanno-annotations",
"service-art.stubs.system_server",
"service-permission.stubs.system_server",
"service-rkp.stubs.system_server",
@@ -213,7 +214,9 @@
"android.hardware.health-V3-java", // AIDL
"android.hardware.health-translate-java",
"android.hardware.light-V1-java",
+ "android.hardware.security.authgraph-V1-java",
"android.hardware.security.rkp-V3-java",
+ "android.hardware.security.secretkeeper-V1-java",
"android.hardware.tv.cec-V1.1-java",
"android.hardware.tv.hdmi.cec-V1-java",
"android.hardware.tv.hdmi.connection-V1-java",
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index e7fae24..67e18ca 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -107,6 +107,7 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.DiskInfo;
+import android.os.storage.ICeStorageLockEventListener;
import android.os.storage.IObbActionListener;
import android.os.storage.IStorageEventListener;
import android.os.storage.IStorageManager;
@@ -139,6 +140,7 @@
import android.util.Xml;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IAppOpsService;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.AppFuseMount;
@@ -185,6 +187,7 @@
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -602,6 +605,9 @@
// Not guarded by lock, always used on the ActivityManager thread
private final SparseArray<PackageMonitor> mPackageMonitorsForUser = new SparseArray<>();
+ /** List of listeners registered for ce storage callbacks */
+ private final CopyOnWriteArrayList<ICeStorageLockEventListener>
+ mCeStorageEventCallbacks = new CopyOnWriteArrayList<>();
class ObbState implements IBinder.DeathRecipient {
public ObbState(String rawPath, String canonicalPath, int callingUid,
@@ -3315,6 +3321,11 @@
synchronized (mLock) {
mCeUnlockedUsers.remove(userId);
}
+ if (android.os.Flags.allowPrivateProfile()
+ && android.multiuser.Flags.enablePrivateSpaceFeatures()
+ && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()) {
+ dispatchCeStorageLockedEvent(userId);
+ }
}
@Override
@@ -4580,6 +4591,18 @@
return StorageManager.MOUNT_MODE_EXTERNAL_NONE;
}
+ @VisibleForTesting
+ CopyOnWriteArrayList<ICeStorageLockEventListener> getCeStorageEventCallbacks() {
+ return mCeStorageEventCallbacks;
+ }
+
+ @VisibleForTesting
+ void dispatchCeStorageLockedEvent(int userId) {
+ for (ICeStorageLockEventListener listener: mCeStorageEventCallbacks) {
+ listener.onStorageLocked(userId);
+ }
+ }
+
private static class Callbacks extends Handler {
private static final int MSG_STORAGE_STATE_CHANGED = 1;
private static final int MSG_VOLUME_STATE_CHANGED = 2;
@@ -5066,5 +5089,23 @@
throw new IOException(e);
}
}
+
+ @Override
+ public void registerStorageLockEventListener(
+ @NonNull ICeStorageLockEventListener listener) {
+ boolean registered = mCeStorageEventCallbacks.add(listener);
+ if (!registered) {
+ Slog.w(TAG, "Failed to register listener: " + listener);
+ }
+ }
+
+ @Override
+ public void unregisterStorageLockEventListener(
+ @NonNull ICeStorageLockEventListener listener) {
+ boolean unregistered = mCeStorageEventCallbacks.remove(listener);
+ if (!unregistered) {
+ Slog.w(TAG, "Unregistering " + listener + " that was not registered");
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index baae40b..5933639 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -74,6 +74,15 @@
"file_patterns": ["SensitiveContentProtectionManagerService\\.java"]
},
{
+ "name": "FrameworksMockingServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.StorageManagerServiceTest"
+ }
+ ],
+ "file_patterns": ["StorageManagerService\\.java"]
+ },
+ {
"name": "FrameworksServicesTests",
"options": [
{
diff --git a/services/core/java/com/android/server/app/flags.aconfig b/services/core/java/com/android/server/app/flags.aconfig
index 54e4571..0673013 100644
--- a/services/core/java/com/android/server/app/flags.aconfig
+++ b/services/core/java/com/android/server/app/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.server.app"
-container: "system"
flag {
name: "game_default_frame_rate"
diff --git a/services/core/java/com/android/server/backup/SystemBackupAgent.java b/services/core/java/com/android/server/backup/SystemBackupAgent.java
index 5b9469b..1ea72d7 100644
--- a/services/core/java/com/android/server/backup/SystemBackupAgent.java
+++ b/services/core/java/com/android/server/backup/SystemBackupAgent.java
@@ -34,10 +34,11 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Slog;
-import com.google.android.collect.Sets;
import com.android.server.backup.Flags;
+import com.google.android.collect.Sets;
+
import java.io.File;
import java.io.IOException;
import java.util.Set;
@@ -64,6 +65,7 @@
private static final String APP_LOCALES_HELPER = "app_locales";
private static final String APP_GENDER_HELPER = "app_gender";
private static final String COMPANION_HELPER = "companion";
+ private static final String SYSTEM_GENDER_HELPER = "system_gender";
// These paths must match what the WallpaperManagerService uses. The leaf *_FILENAME
// are also used in the full-backup file format, so must not change unless steps are
@@ -99,7 +101,9 @@
NOTIFICATION_HELPER,
SYNC_SETTINGS_HELPER,
APP_LOCALES_HELPER,
- COMPANION_HELPER);
+ COMPANION_HELPER,
+ APP_GENDER_HELPER,
+ SYSTEM_GENDER_HELPER);
/** Helpers that are enabled for full, non-system users. */
private static final Set<String> sEligibleHelpersForNonSystemUser =
@@ -139,6 +143,8 @@
addHelperIfEligibleForUser(APP_GENDER_HELPER,
new AppGrammaticalGenderBackupHelper(mUserId));
addHelperIfEligibleForUser(COMPANION_HELPER, new CompanionBackupHelper(mUserId));
+ addHelperIfEligibleForUser(SYSTEM_GENDER_HELPER,
+ new SystemGrammaticalGenderBackupHelper(mUserId));
}
@Override
diff --git a/services/core/java/com/android/server/backup/SystemGrammaticalGenderBackupHelper.java b/services/core/java/com/android/server/backup/SystemGrammaticalGenderBackupHelper.java
new file mode 100644
index 0000000..c0d398e
--- /dev/null
+++ b/services/core/java/com/android/server/backup/SystemGrammaticalGenderBackupHelper.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2024 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.backup;
+
+import static android.app.backup.BackupAgent.FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED;
+
+import android.annotation.UserIdInt;
+import android.app.backup.BackupDataOutput;
+import android.app.backup.BlobBackupHelper;
+import android.os.ParcelFileDescriptor;
+
+import com.android.server.LocalServices;
+import com.android.server.grammaticalinflection.GrammaticalInflectionManagerInternal;
+
+public class SystemGrammaticalGenderBackupHelper extends BlobBackupHelper {
+ private static final int BLOB_VERSION = 1;
+ private static final String KEY_SYSTEM_GENDER = "system_gender";
+
+ private final @UserIdInt int mUserId;
+ private final GrammaticalInflectionManagerInternal mGrammarInflectionManagerInternal;
+
+ public SystemGrammaticalGenderBackupHelper(int userId) {
+ super(BLOB_VERSION, KEY_SYSTEM_GENDER);
+ mUserId = userId;
+ mGrammarInflectionManagerInternal = LocalServices.getService(
+ GrammaticalInflectionManagerInternal.class);
+ }
+
+ @Override
+ public void performBackup(ParcelFileDescriptor oldStateFd, BackupDataOutput data,
+ ParcelFileDescriptor newStateFd) {
+ // Only backup the gender data if e2e encryption is present
+ if ((data.getTransportFlags() & FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED) == 0) {
+ return;
+ }
+
+ super.performBackup(oldStateFd, data, newStateFd);
+ }
+
+ @Override
+ protected byte[] getBackupPayload(String key) {
+ return KEY_SYSTEM_GENDER.equals(key) && mGrammarInflectionManagerInternal != null
+ ? mGrammarInflectionManagerInternal.getSystemBackupPayload(mUserId) : null;
+ }
+
+ @Override
+ protected void applyRestoredPayload(String key, byte[] payload) {
+ if (KEY_SYSTEM_GENDER.equals(key) && mGrammarInflectionManagerInternal != null) {
+ mGrammarInflectionManagerInternal.applyRestoredSystemPayload(payload, mUserId);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java
index f51b62d..4af30a9 100644
--- a/services/core/java/com/android/server/biometrics/Utils.java
+++ b/services/core/java/com/android/server/biometrics/Utils.java
@@ -89,11 +89,23 @@
return true;
}
- /** If virtualized biometrics are supported (requires debug build). */
- public static boolean isVirtualEnabled(@NonNull Context context) {
+ /** If virtualized fingerprint sensor is supported. */
+ public static boolean isFingerprintVirtualEnabled(@NonNull Context context) {
return Build.isDebuggable()
- && Settings.Secure.getIntForUser(context.getContentResolver(),
- Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 0, UserHandle.USER_CURRENT) == 1;
+ && (Settings.Secure.getIntForUser(context.getContentResolver(),
+ Settings.Secure.BIOMETRIC_FINGERPRINT_VIRTUAL_ENABLED, 0,
+ UserHandle.USER_CURRENT) == 1
+ || Settings.Secure.getIntForUser(context.getContentResolver(),
+ Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 0, UserHandle.USER_CURRENT) == 1);
+ }
+
+ /** If virtualized face sensor is supported. */
+ public static boolean isFaceVirtualEnabled(@NonNull Context context) {
+ return Build.isDebuggable()
+ && (Settings.Secure.getIntForUser(context.getContentResolver(),
+ Settings.Secure.BIOMETRIC_FACE_VIRTUAL_ENABLED, 0, UserHandle.USER_CURRENT) == 1
+ || Settings.Secure.getIntForUser(context.getContentResolver(),
+ Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 0, UserHandle.USER_CURRENT) == 1);
}
/**
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index 1037124..a946af8 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -748,7 +748,7 @@
final String virtualInstance = "virtual";
final boolean isVirtualHalPresent =
faceSensorConfigurations.doesInstanceExist(virtualInstance);
- if (Flags.faceVhalFeature() && Utils.isVirtualEnabled(getContext())) {
+ if (Flags.faceVhalFeature() && Utils.isFaceVirtualEnabled(getContext())) {
if (isVirtualHalPresent) {
return new Pair<>(virtualInstance,
faceSensorConfigurations.getSensorPropForInstance(virtualInstance));
@@ -786,7 +786,7 @@
}
final int virtualAt = aidlInstances.indexOf("virtual");
- if (Flags.faceVhalFeature() && Utils.isVirtualEnabled(getContext())) {
+ if (Flags.faceVhalFeature() && Utils.isFaceVirtualEnabled(getContext())) {
if (virtualAt != -1) {
//only virtual instance should be returned
Slog.i(TAG, "virtual hal is used");
@@ -928,7 +928,7 @@
void syncEnrollmentsNow() {
Utils.checkPermissionOrShell(getContext(), MANAGE_FACE);
- if (Flags.faceVhalFeature() && Utils.isVirtualEnabled(getContext())) {
+ if (Flags.faceVhalFeature() && Utils.isFaceVirtualEnabled(getContext())) {
Slog.i(TAG, "Sync virtual enrollments");
final int userId = ActivityManager.getCurrentUser();
for (ServiceProvider provider : mRegistry.getProviders()) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index 2dc03ed..d762914 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -1136,7 +1136,7 @@
final String virtualInstance = "virtual";
final boolean isVirtualHalPresent =
fingerprintSensorConfigurations.doesInstanceExist(virtualInstance);
- if (Utils.isVirtualEnabled(getContext())) {
+ if (Utils.isFingerprintVirtualEnabled(getContext())) {
if (isVirtualHalPresent) {
return new Pair<>(virtualInstance,
fingerprintSensorConfigurations.getSensorPropForInstance(virtualInstance));
@@ -1169,7 +1169,7 @@
}
final int virtualAt = aidlInstances.indexOf("virtual");
- if (Utils.isVirtualEnabled(getContext())) {
+ if (Utils.isFingerprintVirtualEnabled(getContext())) {
if (virtualAt != -1) {
//only virtual instance should be returned
Slog.i(TAG, "virtual hal is used");
@@ -1295,7 +1295,7 @@
void syncEnrollmentsNow() {
Utils.checkPermissionOrShell(getContext(), MANAGE_FINGERPRINT);
- if (Utils.isVirtualEnabled(getContext())) {
+ if (Utils.isFingerprintVirtualEnabled(getContext())) {
Slog.i(TAG, "Sync virtual enrollments");
final int userId = ActivityManager.getCurrentUser();
final CountDownLatch latch = new CountDownLatch(mRegistry.getProviders().size());
@@ -1324,7 +1324,7 @@
}
void simulateVhalFingerDown() {
- if (Utils.isVirtualEnabled(getContext())) {
+ if (Utils.isFingerprintVirtualEnabled(getContext())) {
Slog.i(TAG, "Simulate virtual HAL finger down event");
final Pair<Integer, ServiceProvider> provider = mRegistry.getSingleProvider();
if (provider != null) {
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index 06dc7f5..9c020a7 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -425,7 +425,7 @@
return mScreenAutoBrightness;
}
- float getRawAutomaticScreenBrightness() {
+ public float getRawAutomaticScreenBrightness() {
return mRawScreenAutoBrightness;
}
diff --git a/services/core/java/com/android/server/display/DisplayBrightnessState.java b/services/core/java/com/android/server/display/DisplayBrightnessState.java
index d50a43a..e3e3be2 100644
--- a/services/core/java/com/android/server/display/DisplayBrightnessState.java
+++ b/services/core/java/com/android/server/display/DisplayBrightnessState.java
@@ -18,6 +18,7 @@
import android.text.TextUtils;
+import com.android.server.display.brightness.BrightnessEvent;
import com.android.server.display.brightness.BrightnessReason;
import java.util.Objects;
@@ -43,6 +44,8 @@
private final float mCustomAnimationRate;
+ private final BrightnessEvent mBrightnessEvent;
+
private DisplayBrightnessState(Builder builder) {
mBrightness = builder.getBrightness();
mSdrBrightness = builder.getSdrBrightness();
@@ -54,6 +57,7 @@
mMinBrightness = builder.getMinBrightness();
mCustomAnimationRate = builder.getCustomAnimationRate();
mShouldUpdateScreenBrightnessSetting = builder.shouldUpdateScreenBrightnessSetting();
+ mBrightnessEvent = builder.getBrightnessEvent();
}
/**
@@ -127,6 +131,13 @@
return mShouldUpdateScreenBrightnessSetting;
}
+ /**
+ * @return The BrightnessEvent object
+ */
+ public BrightnessEvent getBrightnessEvent() {
+ return mBrightnessEvent;
+ }
+
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder("DisplayBrightnessState:");
@@ -144,6 +155,8 @@
stringBuilder.append("\n customAnimationRate:").append(mCustomAnimationRate);
stringBuilder.append("\n shouldUpdateScreenBrightnessSetting:")
.append(mShouldUpdateScreenBrightnessSetting);
+ stringBuilder.append("\n mBrightnessEvent:")
+ .append(Objects.toString(mBrightnessEvent, "null"));
return stringBuilder.toString();
}
@@ -173,7 +186,8 @@
&& mMinBrightness == otherState.getMinBrightness()
&& mCustomAnimationRate == otherState.getCustomAnimationRate()
&& mShouldUpdateScreenBrightnessSetting
- == otherState.shouldUpdateScreenBrightnessSetting();
+ == otherState.shouldUpdateScreenBrightnessSetting()
+ && Objects.equals(mBrightnessEvent, otherState.getBrightnessEvent());
}
@Override
@@ -181,7 +195,7 @@
return Objects.hash(mBrightness, mSdrBrightness, mBrightnessReason,
mShouldUseAutoBrightness, mIsSlowChange, mMaxBrightness, mMinBrightness,
mCustomAnimationRate,
- mShouldUpdateScreenBrightnessSetting);
+ mShouldUpdateScreenBrightnessSetting, mBrightnessEvent);
}
/**
@@ -206,6 +220,8 @@
private float mCustomAnimationRate = CUSTOM_ANIMATION_RATE_NOT_SET;
private boolean mShouldUpdateScreenBrightnessSetting;
+ private BrightnessEvent mBrightnessEvent;
+
/**
* Create a builder starting with the values from the specified {@link
* DisplayBrightnessState}.
@@ -225,6 +241,7 @@
builder.setCustomAnimationRate(state.getCustomAnimationRate());
builder.setShouldUpdateScreenBrightnessSetting(
state.shouldUpdateScreenBrightnessSetting());
+ builder.setBrightnessEvent(state.getBrightnessEvent());
return builder;
}
@@ -400,5 +417,22 @@
public DisplayBrightnessState build() {
return new DisplayBrightnessState(this);
}
+
+
+ /**
+ * This is used to get the BrightnessEvent object from its builder
+ */
+ public BrightnessEvent getBrightnessEvent() {
+ return mBrightnessEvent;
+ }
+
+
+ /**
+ * This is used to set the BrightnessEvent object
+ */
+ public Builder setBrightnessEvent(BrightnessEvent brightnessEvent) {
+ mBrightnessEvent = brightnessEvent;
+ return this;
+ }
}
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 404c3ad..cfdb75f 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -83,7 +83,7 @@
import com.android.server.display.brightness.BrightnessUtils;
import com.android.server.display.brightness.DisplayBrightnessController;
import com.android.server.display.brightness.clamper.BrightnessClamperController;
-import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy;
+import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy2;
import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
import com.android.server.display.color.ColorDisplayService.ReduceBrightColorsListener;
import com.android.server.display.config.HysteresisLevels;
@@ -440,7 +440,7 @@
// Responsible for evaluating and tracking the automatic brightness relevant states.
// Todo: This is a temporary workaround. Ideally DPC2 should never talk to the strategies
- private final AutomaticBrightnessStrategy mAutomaticBrightnessStrategy;
+ private final AutomaticBrightnessStrategy2 mAutomaticBrightnessStrategy;
// A record of state for skipping brightness ramps.
private int mSkipRampState = RAMP_STATE_SKIP_NONE;
@@ -1337,9 +1337,6 @@
? AUTO_BRIGHTNESS_MODE_DOZE : AUTO_BRIGHTNESS_MODE_DEFAULT);
}
- final boolean userSetBrightnessChanged = mDisplayBrightnessController
- .updateUserSetScreenBrightness();
-
DisplayBrightnessState displayBrightnessState = mDisplayBrightnessController
.updateBrightness(mPowerRequest, state);
float brightnessState = displayBrightnessState.getBrightness();
@@ -1348,7 +1345,11 @@
boolean slowChange = displayBrightnessState.isSlowChange();
// custom transition duration
float customAnimationRate = displayBrightnessState.getCustomAnimationRate();
-
+ final boolean userSetBrightnessChanged =
+ mDisplayBrightnessController.getIsUserSetScreenBrightnessUpdated();
+ if (displayBrightnessState.getBrightnessEvent() != null) {
+ mTempBrightnessEvent.copyFrom(displayBrightnessState.getBrightnessEvent());
+ }
// Set up the ScreenOff controller used when coming out of SCREEN_OFF and the ALS sensor
// doesn't yet have a valid lux value to use with auto-brightness.
if (mScreenOffBrightnessSensorController != null) {
@@ -1364,11 +1365,13 @@
// request changes.
final boolean wasShortTermModelActive =
mAutomaticBrightnessStrategy.isShortTermModelActive();
- mAutomaticBrightnessStrategy.setAutoBrightnessState(state,
- mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig(),
- mBrightnessReasonTemp.getReason(), mPowerRequest.policy,
- mDisplayBrightnessController.getLastUserSetScreenBrightness(),
- userSetBrightnessChanged);
+ if (!mFlags.isRefactorDisplayPowerControllerEnabled()) {
+ mAutomaticBrightnessStrategy.setAutoBrightnessState(state,
+ mDisplayBrightnessController.isAllowAutoBrightnessWhileDozingConfig(),
+ mBrightnessReasonTemp.getReason(), mPowerRequest.policy,
+ mDisplayBrightnessController.getLastUserSetScreenBrightness(),
+ userSetBrightnessChanged);
+ }
// If the brightness is already set then it's been overridden by something other than the
// user, or is a temporary adjustment.
@@ -1390,9 +1393,22 @@
float currentBrightnessSetting = mDisplayBrightnessController.getCurrentBrightness();
// Apply auto-brightness.
int brightnessAdjustmentFlags = 0;
+ // All the conditions inside this if block will be moved to AutomaticBrightnessStrategy
+ if (mFlags.isRefactorDisplayPowerControllerEnabled()
+ && displayBrightnessState.getBrightnessReason().getReason()
+ == BrightnessReason.REASON_AUTOMATIC) {
+ brightnessAdjustmentFlags =
+ mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentReasonsFlags();
+ updateScreenBrightnessSetting = currentBrightnessSetting != brightnessState;
+ mBrightnessReasonTemp.setReason(BrightnessReason.REASON_AUTOMATIC);
+ if (mScreenOffBrightnessSensorController != null) {
+ mScreenOffBrightnessSensorController.setLightSensorEnabled(false);
+ }
+ setBrightnessFromOffload(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+ }
// AutomaticBrightnessStrategy has higher priority than OffloadBrightnessStrategy
- if (Float.isNaN(brightnessState)
- || mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_OFFLOAD) {
+ if (!mFlags.isRefactorDisplayPowerControllerEnabled() && (Float.isNaN(brightnessState)
+ || mBrightnessReasonTemp.getReason() == BrightnessReason.REASON_OFFLOAD)) {
if (mAutomaticBrightnessStrategy.isAutoBrightnessEnabled()) {
brightnessState = mAutomaticBrightnessStrategy.getAutomaticScreenBrightness(
mTempBrightnessEvent);
@@ -1422,8 +1438,8 @@
}
} else {
// Any non-auto-brightness values such as override or temporary should still be subject
- // to clamping so that they don't go beyond the current max as specified by HBM
- // Controller.
+ // to clamping so that they don't go beyond the current max as specified by Brightness
+ // Range Controller.
brightnessState = clampScreenBrightness(brightnessState);
mAutomaticBrightnessStrategy.setAutoBrightnessApplied(false);
}
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 1dfe037..182b05a 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -82,11 +82,8 @@
private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.boot.emulator.circular";
// Min and max strengths for even dimmer feature.
private static final float EVEN_DIMMER_MIN_STRENGTH = 0.0f;
- private static final float EVEN_DIMMER_MAX_STRENGTH = 70.0f; // not too dim yet.
+ private static final float EVEN_DIMMER_MAX_STRENGTH = 90.0f;
private static final float BRIGHTNESS_MIN = 0.0f;
- // The brightness at which we start using color matrices rather than backlight,
- // to dim the display
- private static final float BACKLIGHT_COLOR_TRANSITION_POINT = 0.1f;
private final LongSparseArray<LocalDisplayDevice> mDevices = new LongSparseArray<>();
@@ -995,9 +992,12 @@
private void applyColorMatrixBasedDimming(float brightnessState) {
int strength = (int) (MathUtils.constrainedMap(
- EVEN_DIMMER_MAX_STRENGTH, EVEN_DIMMER_MIN_STRENGTH, // to this range
- BRIGHTNESS_MIN, BACKLIGHT_COLOR_TRANSITION_POINT, // from this range
- brightnessState) + 0.5); // map this (+ rounded up)
+ // to this range:
+ EVEN_DIMMER_MAX_STRENGTH, EVEN_DIMMER_MIN_STRENGTH,
+ // from this range:
+ BRIGHTNESS_MIN, mDisplayDeviceConfig.getEvenDimmerTransitionPoint(),
+ // map this (+ rounded up):
+ brightnessState) + 0.5);
if (mEvenDimmerStrength < 0 // uninitialised
|| MathUtils.abs(mEvenDimmerStrength - strength) > 1
diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
index 8084685..8b3e4a4 100644
--- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
+++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessController.java
@@ -31,7 +31,7 @@
import com.android.server.display.BrightnessMappingStrategy;
import com.android.server.display.BrightnessSetting;
import com.android.server.display.DisplayBrightnessState;
-import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy;
+import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy2;
import com.android.server.display.brightness.strategy.DisplayBrightnessStrategy;
import com.android.server.display.feature.DisplayManagerFlags;
@@ -76,6 +76,10 @@
@GuardedBy("mLock")
private float mLastUserSetScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ // Represents if the system has adjusted the brightness based on the user suggested value. Will
+ // be false if the brightness change is coming from a non-user source
+ private boolean mUserSetScreenBrightnessUpdated;
+
// The listener which is to be notified everytime there is a change in the brightness in the
// BrightnessSetting.
private BrightnessSetting.BrightnessSettingListener mBrightnessSettingListener;
@@ -138,7 +142,6 @@
public DisplayBrightnessState updateBrightness(
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest,
int targetDisplayState) {
-
DisplayBrightnessState state;
synchronized (mLock) {
mDisplayBrightnessStrategy = mDisplayBrightnessStrategySelector.selectStrategy(
@@ -246,28 +249,14 @@
}
/**
- * We want to return true if the user has set the screen brightness.
- * RBC on, off, and intensity changes will return false.
- * Slider interactions whilst in RBC will return true, just as when in non-rbc.
+ * Returns if the system has adjusted the brightness based on the user suggested value. Will
+ * be false if the brightness change is coming from a non-user source.
+ *
+ * Todo: 294444204 This is a temporary workaround, and should be moved to the manual brightness
+ * strategy once that is introduced
*/
- public boolean updateUserSetScreenBrightness() {
- synchronized (mLock) {
- if (!BrightnessUtils.isValidBrightnessValue(mPendingScreenBrightness)) {
- return false;
- }
- if (mCurrentScreenBrightness == mPendingScreenBrightness) {
- mPendingScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- setTemporaryBrightnessLocked(PowerManager.BRIGHTNESS_INVALID_FLOAT);
- return false;
- }
- setCurrentScreenBrightnessLocked(mPendingScreenBrightness);
- mLastUserSetScreenBrightness = mPendingScreenBrightness;
- mPendingScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
- setTemporaryBrightnessLocked(PowerManager.BRIGHTNESS_INVALID_FLOAT);
- }
- notifyCurrentScreenBrightness();
- return true;
-
+ public boolean getIsUserSetScreenBrightnessUpdated() {
+ return mUserSetScreenBrightnessUpdated;
}
/**
@@ -355,7 +344,7 @@
/**
* TODO(b/253226419): Remove once auto-brightness is a fully-functioning strategy.
*/
- public AutomaticBrightnessStrategy getAutomaticBrightnessStrategy() {
+ public AutomaticBrightnessStrategy2 getAutomaticBrightnessStrategy() {
return mDisplayBrightnessStrategySelector.getAutomaticBrightnessStrategy();
}
@@ -442,6 +431,33 @@
}
}
+ /**
+ * We want to return true if the user has set the screen brightness.
+ * RBC on, off, and intensity changes will return false.
+ * Slider interactions whilst in RBC will return true, just as when in non-rbc.
+ */
+ @VisibleForTesting
+ boolean updateUserSetScreenBrightness() {
+ mUserSetScreenBrightnessUpdated = false;
+ synchronized (mLock) {
+ if (!BrightnessUtils.isValidBrightnessValue(mPendingScreenBrightness)) {
+ return false;
+ }
+ if (mCurrentScreenBrightness == mPendingScreenBrightness) {
+ mPendingScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ setTemporaryBrightnessLocked(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+ return false;
+ }
+ setCurrentScreenBrightnessLocked(mPendingScreenBrightness);
+ mLastUserSetScreenBrightness = mPendingScreenBrightness;
+ mPendingScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ setTemporaryBrightnessLocked(PowerManager.BRIGHTNESS_INVALID_FLOAT);
+ }
+ notifyCurrentScreenBrightness();
+ mUserSetScreenBrightnessUpdated = true;
+ return true;
+ }
+
@VisibleForTesting
static class Injector {
DisplayBrightnessStrategySelector getDisplayBrightnessStrategySelector(Context context,
@@ -470,7 +486,7 @@
* TODO(b/253226419): Remove once auto-brightness is a fully-functioning strategy.
*/
private DisplayBrightnessState addAutomaticBrightnessState(DisplayBrightnessState state) {
- AutomaticBrightnessStrategy autoStrat = getAutomaticBrightnessStrategy();
+ AutomaticBrightnessStrategy2 autoStrat = getAutomaticBrightnessStrategy();
DisplayBrightnessState.Builder builder = DisplayBrightnessState.Builder.from(state);
builder.setShouldUseAutoBrightness(
@@ -526,6 +542,12 @@
private StrategySelectionRequest constructStrategySelectionRequest(
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest,
int targetDisplayState) {
- return new StrategySelectionRequest(displayPowerRequest, targetDisplayState);
+ boolean userSetBrightnessChanged = updateUserSetScreenBrightness();
+ float lastUserSetScreenBrightness;
+ synchronized (mLock) {
+ lastUserSetScreenBrightness = mLastUserSetScreenBrightness;
+ }
+ return new StrategySelectionRequest(displayPowerRequest, targetDisplayState,
+ lastUserSetScreenBrightness, userSetBrightnessChanged);
}
}
diff --git a/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java b/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java
index 165c24b..da66879 100644
--- a/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java
+++ b/services/core/java/com/android/server/display/brightness/DisplayBrightnessStrategySelector.java
@@ -27,6 +27,7 @@
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy;
+import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy2;
import com.android.server.display.brightness.strategy.BoostBrightnessStrategy;
import com.android.server.display.brightness.strategy.DisplayBrightnessStrategy;
import com.android.server.display.brightness.strategy.DozeBrightnessStrategy;
@@ -65,7 +66,16 @@
// The brightness strategy used to manage the brightness state when the request is invalid.
private final InvalidBrightnessStrategy mInvalidBrightnessStrategy;
// Controls brightness when automatic (adaptive) brightness is running.
- private final AutomaticBrightnessStrategy mAutomaticBrightnessStrategy;
+ private final AutomaticBrightnessStrategy2 mAutomaticBrightnessStrategy;
+
+ // The automatic strategy which controls the brightness when adaptive mode is ON.
+ private final AutomaticBrightnessStrategy mAutomaticBrightnessStrategy1;
+
+ // The deprecated AutomaticBrightnessStrategy. Avoid using it for any new features without
+ // consulting with the display frameworks team. Use {@link AutomaticBrightnessStrategy} instead.
+ // This will be removed once the flag
+ // {@link DisplayManagerFlags#isRefactorDisplayPowerControllerEnabled is fully rolled out
+ private final AutomaticBrightnessStrategy2 mAutomaticBrightnessStrategy2;
// Controls the brightness if adaptive brightness is on and there exists an active offload
// session. Brightness value is provided by the offload session.
@Nullable
@@ -101,7 +111,15 @@
mBoostBrightnessStrategy = injector.getBoostBrightnessStrategy();
mFollowerBrightnessStrategy = injector.getFollowerBrightnessStrategy(displayId);
mInvalidBrightnessStrategy = injector.getInvalidBrightnessStrategy();
- mAutomaticBrightnessStrategy = injector.getAutomaticBrightnessStrategy(context, displayId);
+ mAutomaticBrightnessStrategy1 =
+ (!mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled()) ? null
+ : injector.getAutomaticBrightnessStrategy1(context, displayId);
+ mAutomaticBrightnessStrategy2 =
+ (mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled()) ? null
+ : injector.getAutomaticBrightnessStrategy2(context, displayId);
+ mAutomaticBrightnessStrategy =
+ (mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled())
+ ? mAutomaticBrightnessStrategy1 : mAutomaticBrightnessStrategy2;
if (flags.isDisplayOffloadEnabled()) {
mOffloadBrightnessStrategy = injector.getOffloadBrightnessStrategy();
} else {
@@ -110,7 +128,7 @@
mDisplayBrightnessStrategies = new DisplayBrightnessStrategy[]{mInvalidBrightnessStrategy,
mScreenOffBrightnessStrategy, mDozeBrightnessStrategy, mFollowerBrightnessStrategy,
mBoostBrightnessStrategy, mOverrideBrightnessStrategy, mTemporaryBrightnessStrategy,
- mOffloadBrightnessStrategy};
+ mAutomaticBrightnessStrategy1, mOffloadBrightnessStrategy};
mAllowAutoBrightnessWhileDozingConfig = context.getResources().getBoolean(
R.bool.config_allowAutoBrightnessWhileDozing);
mOldBrightnessStrategyName = mInvalidBrightnessStrategy.getName();
@@ -142,6 +160,9 @@
} else if (BrightnessUtils.isValidBrightnessValue(
mTemporaryBrightnessStrategy.getTemporaryScreenBrightness())) {
displayBrightnessStrategy = mTemporaryBrightnessStrategy;
+ } else if (mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled()
+ && isAutomaticBrightnessStrategyValid(strategySelectionRequest)) {
+ displayBrightnessStrategy = mAutomaticBrightnessStrategy1;
} else if (mAutomaticBrightnessStrategy.shouldUseAutoBrightness()
&& mOffloadBrightnessStrategy != null && BrightnessUtils.isValidBrightnessValue(
mOffloadBrightnessStrategy.getOffloadScreenBrightness())) {
@@ -149,7 +170,8 @@
}
if (mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled()) {
- postProcess(constructStrategySelectionNotifyRequest(displayBrightnessStrategy));
+ postProcess(constructStrategySelectionNotifyRequest(displayBrightnessStrategy,
+ strategySelectionRequest));
}
if (!mOldBrightnessStrategyName.equals(displayBrightnessStrategy.getName())) {
@@ -170,7 +192,7 @@
return mFollowerBrightnessStrategy;
}
- public AutomaticBrightnessStrategy getAutomaticBrightnessStrategy() {
+ public AutomaticBrightnessStrategy2 getAutomaticBrightnessStrategy() {
return mAutomaticBrightnessStrategy;
}
@@ -206,9 +228,28 @@
}
}
+ private boolean isAutomaticBrightnessStrategyValid(
+ StrategySelectionRequest strategySelectionRequest) {
+ mAutomaticBrightnessStrategy1.setAutoBrightnessState(
+ strategySelectionRequest.getTargetDisplayState(),
+ mAllowAutoBrightnessWhileDozingConfig,
+ BrightnessReason.REASON_UNKNOWN,
+ strategySelectionRequest.getDisplayPowerRequest().policy,
+ strategySelectionRequest.getLastUserSetScreenBrightness(),
+ strategySelectionRequest.isUserSetBrightnessChanged());
+ return mAutomaticBrightnessStrategy1.isAutoBrightnessValid();
+ }
+
private StrategySelectionNotifyRequest constructStrategySelectionNotifyRequest(
- DisplayBrightnessStrategy selectedDisplayBrightnessStrategy) {
- return new StrategySelectionNotifyRequest(selectedDisplayBrightnessStrategy);
+ DisplayBrightnessStrategy selectedDisplayBrightnessStrategy,
+ StrategySelectionRequest strategySelectionRequest) {
+ return new StrategySelectionNotifyRequest(
+ strategySelectionRequest.getDisplayPowerRequest(),
+ strategySelectionRequest.getTargetDisplayState(),
+ selectedDisplayBrightnessStrategy,
+ strategySelectionRequest.getLastUserSetScreenBrightness(),
+ strategySelectionRequest.isUserSetBrightnessChanged(),
+ isAllowAutoBrightnessWhileDozingConfig());
}
private void postProcess(StrategySelectionNotifyRequest strategySelectionNotifyRequest) {
@@ -263,10 +304,16 @@
return new InvalidBrightnessStrategy();
}
- AutomaticBrightnessStrategy getAutomaticBrightnessStrategy(Context context, int displayId) {
+ AutomaticBrightnessStrategy getAutomaticBrightnessStrategy1(Context context,
+ int displayId) {
return new AutomaticBrightnessStrategy(context, displayId);
}
+ AutomaticBrightnessStrategy2 getAutomaticBrightnessStrategy2(Context context,
+ int displayId) {
+ return new AutomaticBrightnessStrategy2(context, displayId);
+ }
+
OffloadBrightnessStrategy getOffloadBrightnessStrategy() {
return new OffloadBrightnessStrategy();
}
diff --git a/services/core/java/com/android/server/display/brightness/StrategySelectionNotifyRequest.java b/services/core/java/com/android/server/display/brightness/StrategySelectionNotifyRequest.java
index d8bd2e4..6e6c972 100644
--- a/services/core/java/com/android/server/display/brightness/StrategySelectionNotifyRequest.java
+++ b/services/core/java/com/android/server/display/brightness/StrategySelectionNotifyRequest.java
@@ -16,6 +16,8 @@
package com.android.server.display.brightness;
+import android.hardware.display.DisplayManagerInternal;
+
import com.android.server.display.brightness.strategy.DisplayBrightnessStrategy;
import java.util.Objects;
@@ -25,11 +27,36 @@
* DisplayBrightnessStrategy
*/
public final class StrategySelectionNotifyRequest {
+ // The request to change the associated display's state and brightness
+ private DisplayManagerInternal.DisplayPowerRequest mDisplayPowerRequest;
+
+ // The display state to which the screen is switching to
+ private int mTargetDisplayState;
+
// The strategy that was selected with the current request
private final DisplayBrightnessStrategy mSelectedDisplayBrightnessStrategy;
- public StrategySelectionNotifyRequest(DisplayBrightnessStrategy displayBrightnessStrategy) {
+ // The last brightness that was set by the user and not temporary. Set to
+ // PowerManager.BRIGHTNESS_INVALID_FLOAT when a brightness has yet to be recorded.
+ private float mLastUserSetScreenBrightness;
+
+ // Represents if the user set screen brightness was changed or not.
+ private boolean mUserSetBrightnessChanged;
+
+ // True if light sensor is to be used to automatically determine doze screen brightness.
+ private final boolean mAllowAutoBrightnessWhileDozingConfig;
+
+ public StrategySelectionNotifyRequest(
+ DisplayManagerInternal.DisplayPowerRequest displayPowerRequest, int targetDisplayState,
+ DisplayBrightnessStrategy displayBrightnessStrategy,
+ float lastUserSetScreenBrightness,
+ boolean userSetBrightnessChanged, boolean allowAutoBrightnessWhileDozingConfig) {
+ mDisplayPowerRequest = displayPowerRequest;
+ mTargetDisplayState = targetDisplayState;
mSelectedDisplayBrightnessStrategy = displayBrightnessStrategy;
+ mLastUserSetScreenBrightness = lastUserSetScreenBrightness;
+ mUserSetBrightnessChanged = userSetBrightnessChanged;
+ mAllowAutoBrightnessWhileDozingConfig = allowAutoBrightnessWhileDozingConfig;
}
public DisplayBrightnessStrategy getSelectedDisplayBrightnessStrategy() {
@@ -43,11 +70,52 @@
}
StrategySelectionNotifyRequest other = (StrategySelectionNotifyRequest) obj;
return other.getSelectedDisplayBrightnessStrategy()
- == getSelectedDisplayBrightnessStrategy();
+ == getSelectedDisplayBrightnessStrategy()
+ && Objects.equals(mDisplayPowerRequest, other.getDisplayPowerRequest())
+ && mTargetDisplayState == other.getTargetDisplayState()
+ && mUserSetBrightnessChanged == other.isUserSetBrightnessChanged()
+ && mLastUserSetScreenBrightness == other.getLastUserSetScreenBrightness()
+ && mAllowAutoBrightnessWhileDozingConfig
+ == other.isAllowAutoBrightnessWhileDozingConfig();
}
@Override
public int hashCode() {
- return Objects.hash(mSelectedDisplayBrightnessStrategy);
+ return Objects.hash(mSelectedDisplayBrightnessStrategy, mDisplayPowerRequest,
+ mTargetDisplayState, mUserSetBrightnessChanged, mLastUserSetScreenBrightness,
+ mAllowAutoBrightnessWhileDozingConfig);
+ }
+
+ public float getLastUserSetScreenBrightness() {
+ return mLastUserSetScreenBrightness;
+ }
+
+ public boolean isUserSetBrightnessChanged() {
+ return mUserSetBrightnessChanged;
+ }
+
+ public DisplayManagerInternal.DisplayPowerRequest getDisplayPowerRequest() {
+ return mDisplayPowerRequest;
+ }
+
+ public int getTargetDisplayState() {
+ return mTargetDisplayState;
+ }
+
+ public boolean isAllowAutoBrightnessWhileDozingConfig() {
+ return mAllowAutoBrightnessWhileDozingConfig;
+ }
+
+ /**
+ * A utility to stringify a StrategySelectionNotifyRequest
+ */
+ public String toString() {
+ return "StrategySelectionNotifyRequest:"
+ + " mDisplayPowerRequest=" + mDisplayPowerRequest
+ + " mTargetDisplayState=" + mTargetDisplayState
+ + " mSelectedDisplayBrightnessStrategy=" + mSelectedDisplayBrightnessStrategy
+ + " mLastUserSetScreenBrightness=" + mLastUserSetScreenBrightness
+ + " mUserSetBrightnessChanged=" + mUserSetBrightnessChanged
+ + " mAllowAutoBrightnessWhileDozingConfig=" + mAllowAutoBrightnessWhileDozingConfig;
}
}
diff --git a/services/core/java/com/android/server/display/brightness/StrategySelectionRequest.java b/services/core/java/com/android/server/display/brightness/StrategySelectionRequest.java
index e618596..ae745efc 100644
--- a/services/core/java/com/android/server/display/brightness/StrategySelectionRequest.java
+++ b/services/core/java/com/android/server/display/brightness/StrategySelectionRequest.java
@@ -31,10 +31,20 @@
// The display state to which the screen is switching to
private int mTargetDisplayState;
+ // The last brightness that was set by the user and not temporary. Set to
+ // PowerManager.BRIGHTNESS_INVALID_FLOAT when a brightness has yet to be recorded.
+ private float mLastUserSetScreenBrightness;
+
+ // Represents if the user set screen brightness was changed or not.
+ private boolean mUserSetBrightnessChanged;
+
public StrategySelectionRequest(DisplayManagerInternal.DisplayPowerRequest displayPowerRequest,
- int targetDisplayState) {
+ int targetDisplayState, float lastUserSetScreenBrightness,
+ boolean userSetBrightnessChanged) {
mDisplayPowerRequest = displayPowerRequest;
mTargetDisplayState = targetDisplayState;
+ mLastUserSetScreenBrightness = lastUserSetScreenBrightness;
+ mUserSetBrightnessChanged = userSetBrightnessChanged;
}
public DisplayManagerInternal.DisplayPowerRequest getDisplayPowerRequest() {
@@ -45,18 +55,30 @@
return mTargetDisplayState;
}
+
+ public float getLastUserSetScreenBrightness() {
+ return mLastUserSetScreenBrightness;
+ }
+
+ public boolean isUserSetBrightnessChanged() {
+ return mUserSetBrightnessChanged;
+ }
+
@Override
public boolean equals(Object obj) {
if (!(obj instanceof StrategySelectionRequest)) {
return false;
}
StrategySelectionRequest other = (StrategySelectionRequest) obj;
- return Objects.equals(other.getDisplayPowerRequest(), getDisplayPowerRequest())
- && other.getTargetDisplayState() == getTargetDisplayState();
+ return Objects.equals(mDisplayPowerRequest, other.getDisplayPowerRequest())
+ && mTargetDisplayState == other.getTargetDisplayState()
+ && mLastUserSetScreenBrightness == other.getLastUserSetScreenBrightness()
+ && mUserSetBrightnessChanged == other.isUserSetBrightnessChanged();
}
@Override
public int hashCode() {
- return Objects.hash(mDisplayPowerRequest, mTargetDisplayState);
+ return Objects.hash(mDisplayPowerRequest, mTargetDisplayState,
+ mLastUserSetScreenBrightness, mUserSetBrightnessChanged);
}
}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
index 08d4cfd..4be7332 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy.java
@@ -20,6 +20,7 @@
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.display.BrightnessConfiguration;
+import android.hardware.display.DisplayManagerInternal;
import android.os.PowerManager;
import android.os.UserHandle;
import android.provider.Settings;
@@ -27,9 +28,11 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.AutomaticBrightnessController;
+import com.android.server.display.DisplayBrightnessState;
import com.android.server.display.brightness.BrightnessEvent;
import com.android.server.display.brightness.BrightnessReason;
import com.android.server.display.brightness.BrightnessUtils;
+import com.android.server.display.brightness.StrategySelectionNotifyRequest;
import java.io.PrintWriter;
@@ -40,7 +43,8 @@
* that it is being executed from the power thread, and hence doesn't synchronize
* any of its resources
*/
-public class AutomaticBrightnessStrategy {
+public class AutomaticBrightnessStrategy extends AutomaticBrightnessStrategy2
+ implements DisplayBrightnessStrategy{
private final Context mContext;
// The DisplayId of the associated logical display
private final int mDisplayId;
@@ -88,7 +92,12 @@
@Nullable
private BrightnessConfiguration mBrightnessConfiguration;
+ // Indicates if the strategy is already configured for a request, in which case we wouldn't
+ // want to re-evaluate the auto-brightness state
+ private boolean mIsConfigured;
+
public AutomaticBrightnessStrategy(Context context, int displayId) {
+ super(context, displayId);
mContext = context;
mDisplayId = displayId;
mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
@@ -112,7 +121,7 @@
mAutoBrightnessDisabledDueToDisplayOff = shouldUseAutoBrightness()
&& !(targetDisplayState == Display.STATE_ON || autoBrightnessEnabledInDoze);
final int autoBrightnessState = mIsAutoBrightnessEnabled
- && brightnessReason != BrightnessReason.REASON_FOLLOWER
+ && brightnessReason != BrightnessReason.REASON_FOLLOWER
? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
: mAutoBrightnessDisabledDueToDisplayOff
? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE
@@ -120,12 +129,36 @@
accommodateUserBrightnessChanges(userSetBrightnessChanged, lastUserSetScreenBrightness,
policy, targetDisplayState, mBrightnessConfiguration, autoBrightnessState);
+ mIsConfigured = true;
+ }
+
+ public void setIsConfigured(boolean configure) {
+ mIsConfigured = configure;
}
public boolean isAutoBrightnessEnabled() {
return mIsAutoBrightnessEnabled;
}
+ /**
+ * Validates if the auto-brightness strategy is valid or not considering the current system
+ * state.
+ */
+ public boolean isAutoBrightnessValid() {
+ boolean isValid = false;
+ if (isAutoBrightnessEnabled()) {
+ float brightness = (mAutomaticBrightnessController != null)
+ ? mAutomaticBrightnessController.getAutomaticScreenBrightness(null)
+ : PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ if (BrightnessUtils.isValidBrightnessValue(brightness)
+ || brightness == PowerManager.BRIGHTNESS_OFF_FLOAT) {
+ isValid = true;
+ }
+ }
+ setAutoBrightnessApplied(isValid);
+ return isValid;
+ }
+
public boolean isAutoBrightnessDisabledDueToDisplayOff() {
return mAutoBrightnessDisabledDueToDisplayOff;
}
@@ -217,6 +250,29 @@
mTemporaryAutoBrightnessAdjustment = temporaryAutoBrightnessAdjustment;
}
+ @Override
+ public DisplayBrightnessState updateBrightness(
+ DisplayManagerInternal.DisplayPowerRequest displayPowerRequest) {
+ BrightnessReason brightnessReason = new BrightnessReason();
+ brightnessReason.setReason(BrightnessReason.REASON_AUTOMATIC);
+ BrightnessEvent brightnessEvent = new BrightnessEvent(mDisplayId);
+ float brightness = getAutomaticScreenBrightness(brightnessEvent);
+ return new DisplayBrightnessState.Builder()
+ .setBrightness(brightness)
+ .setSdrBrightness(brightness)
+ .setBrightnessReason(brightnessReason)
+ .setDisplayBrightnessStrategyName(getName())
+ .setIsSlowChange(hasAppliedAutoBrightness()
+ && !getAutoBrightnessAdjustmentChanged())
+ .setBrightnessEvent(brightnessEvent)
+ .build();
+ }
+
+ @Override
+ public String getName() {
+ return "AutomaticBrightnessStrategy";
+ }
+
/**
* Dumps the state of this class.
*/
@@ -238,6 +294,26 @@
+ mAutoBrightnessAdjustmentReasonsFlags);
}
+ @Override
+ public void strategySelectionPostProcessor(
+ StrategySelectionNotifyRequest strategySelectionNotifyRequest) {
+ if (!mIsConfigured) {
+ setAutoBrightnessState(strategySelectionNotifyRequest.getTargetDisplayState(),
+ strategySelectionNotifyRequest.isAllowAutoBrightnessWhileDozingConfig(),
+ strategySelectionNotifyRequest.getSelectedDisplayBrightnessStrategy()
+ .getReason(),
+ strategySelectionNotifyRequest.getDisplayPowerRequest().policy,
+ strategySelectionNotifyRequest.getLastUserSetScreenBrightness(),
+ strategySelectionNotifyRequest.isUserSetBrightnessChanged());
+ }
+ mIsConfigured = false;
+ }
+
+ @Override
+ public int getReason() {
+ return BrightnessReason.REASON_AUTOMATIC;
+ }
+
/**
* Indicates if any auto-brightness adjustments have happened since the last auto-brightness was
* set.
diff --git a/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2.java b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2.java
new file mode 100644
index 0000000..25e8b23
--- /dev/null
+++ b/services/core/java/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2.java
@@ -0,0 +1,430 @@
+/*
+ * Copyright (C) 2024 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.display.brightness.strategy;
+
+import static android.hardware.display.DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.display.BrightnessConfiguration;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.view.Display;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.display.AutomaticBrightnessController;
+import com.android.server.display.brightness.BrightnessEvent;
+import com.android.server.display.brightness.BrightnessReason;
+import com.android.server.display.brightness.BrightnessUtils;
+import com.android.server.display.feature.DisplayManagerFlags;
+
+import java.io.PrintWriter;
+
+/**
+ * Helps manage the brightness based on the ambient environment (Ambient Light/lux sensor) using
+ * mappings from lux to nits to brightness, configured in the
+ * {@link com.android.server.display.DisplayDeviceConfig} class. This class inherently assumes
+ * that it is being executed from the power thread, and hence doesn't synchronize
+ * any of its resources
+ *
+ * @deprecated This class is relevant only while the
+ * {@link DisplayManagerFlags#isRefactorDisplayPowerControllerEnabled()} is not fully rolled out.
+ * Till then, please replicated your changes to {@link AutomaticBrightnessStrategy} as well.
+ */
+@Deprecated
+public class AutomaticBrightnessStrategy2 {
+ private final Context mContext;
+ // The DisplayId of the associated logical display
+ private final int mDisplayId;
+ // The last auto brightness adjustment that was set by the user and is not temporary. Set to
+ // Float.NaN when an auto-brightness adjustment hasn't been recorded yet.
+ private float mAutoBrightnessAdjustment;
+ // The pending auto brightness adjustment that will take effect on the next power state update.
+ private float mPendingAutoBrightnessAdjustment;
+ // The temporary auto brightness adjustment. This was historically used when a user interacts
+ // with the adjustment slider but hasn't settled on a choice yet.
+ // Set to PowerManager.BRIGHTNESS_INVALID_FLOAT when there's no temporary adjustment set.
+ private float mTemporaryAutoBrightnessAdjustment;
+ // Indicates if the temporary auto brightness adjustment has been applied while updating the
+ // associated display brightness
+ private boolean mAppliedTemporaryAutoBrightnessAdjustment;
+ // Indicates if the auto brightness adjustment has happened.
+ private boolean mAutoBrightnessAdjustmentChanged;
+ // Indicates the reasons for the auto-brightness adjustment
+ private int mAutoBrightnessAdjustmentReasonsFlags = 0;
+ // Indicates if the short term model should be reset before fetching the new brightness
+ // Todo(273543270): Short term model is an internal information of
+ // AutomaticBrightnessController and shouldn't be exposed outside of that class
+ private boolean mShouldResetShortTermModel = false;
+ // Remembers whether the auto-brightness has been applied in the latest brightness update.
+ private boolean mAppliedAutoBrightness = false;
+ // The controller for the automatic brightness level.
+ @Nullable
+ private AutomaticBrightnessController mAutomaticBrightnessController;
+ // The system setting denoting if the auto-brightness for the current user is enabled or not
+ private boolean mUseAutoBrightness = false;
+ // Indicates if the auto-brightness is currently enabled or not. It's possible that even if
+ // the user has enabled the auto-brightness from the settings, it is disabled because the
+ // display is off
+ private boolean mIsAutoBrightnessEnabled = false;
+ // Indicates if auto-brightness is disabled due to the display being off. Needed for metric
+ // purposes.
+ private boolean mAutoBrightnessDisabledDueToDisplayOff;
+ // If the auto-brightness model for the last manual changes done by the user.
+ private boolean mIsShortTermModelActive = false;
+
+ // The BrightnessConfiguration currently being used
+ // Todo(273543270): BrightnessConfiguration is an internal implementation detail of
+ // AutomaticBrightnessController, and AutomaticBrightnessStrategy shouldn't be aware of its
+ // existence.
+ @Nullable
+ private BrightnessConfiguration mBrightnessConfiguration;
+
+ public AutomaticBrightnessStrategy2(Context context, int displayId) {
+ mContext = context;
+ mDisplayId = displayId;
+ mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
+ mPendingAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ mTemporaryAutoBrightnessAdjustment = PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ }
+
+ /**
+ * Sets up the automatic brightness states of this class. Also configures
+ * AutomaticBrightnessController accounting for any manual changes made by the user.
+ */
+ public void setAutoBrightnessState(int targetDisplayState,
+ boolean allowAutoBrightnessWhileDozingConfig, int brightnessReason, int policy,
+ float lastUserSetScreenBrightness, boolean userSetBrightnessChanged) {
+ final boolean autoBrightnessEnabledInDoze =
+ allowAutoBrightnessWhileDozingConfig && policy == POLICY_DOZE;
+ mIsAutoBrightnessEnabled = shouldUseAutoBrightness()
+ && (targetDisplayState == Display.STATE_ON || autoBrightnessEnabledInDoze)
+ && brightnessReason != BrightnessReason.REASON_OVERRIDE
+ && mAutomaticBrightnessController != null;
+ mAutoBrightnessDisabledDueToDisplayOff = shouldUseAutoBrightness()
+ && !(targetDisplayState == Display.STATE_ON || autoBrightnessEnabledInDoze);
+ final int autoBrightnessState = mIsAutoBrightnessEnabled
+ && brightnessReason != BrightnessReason.REASON_FOLLOWER
+ ? AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED
+ : mAutoBrightnessDisabledDueToDisplayOff
+ ? AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE
+ : AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED;
+
+ accommodateUserBrightnessChanges(userSetBrightnessChanged, lastUserSetScreenBrightness,
+ policy, targetDisplayState, mBrightnessConfiguration, autoBrightnessState);
+ }
+
+ public boolean isAutoBrightnessEnabled() {
+ return mIsAutoBrightnessEnabled;
+ }
+
+ public boolean isAutoBrightnessDisabledDueToDisplayOff() {
+ return mAutoBrightnessDisabledDueToDisplayOff;
+ }
+
+ /**
+ * Updates the {@link BrightnessConfiguration} that is currently being used by the associated
+ * display.
+ */
+ public void setBrightnessConfiguration(BrightnessConfiguration brightnessConfiguration,
+ boolean shouldResetShortTermModel) {
+ mBrightnessConfiguration = brightnessConfiguration;
+ setShouldResetShortTermModel(shouldResetShortTermModel);
+ }
+
+ /**
+ * Promotes the pending auto-brightness adjustments which are yet to be applied to the current
+ * adjustments. Note that this is not applying the new adjustments to the AutoBrightness mapping
+ * strategies, but is only accommodating the changes in this class.
+ */
+ public boolean processPendingAutoBrightnessAdjustments() {
+ mAutoBrightnessAdjustmentChanged = false;
+ if (Float.isNaN(mPendingAutoBrightnessAdjustment)) {
+ return false;
+ }
+ if (mAutoBrightnessAdjustment == mPendingAutoBrightnessAdjustment) {
+ mPendingAutoBrightnessAdjustment = Float.NaN;
+ return false;
+ }
+ mAutoBrightnessAdjustment = mPendingAutoBrightnessAdjustment;
+ mPendingAutoBrightnessAdjustment = Float.NaN;
+ mTemporaryAutoBrightnessAdjustment = Float.NaN;
+ mAutoBrightnessAdjustmentChanged = true;
+ return true;
+ }
+
+ /**
+ * Updates the associated AutomaticBrightnessController
+ */
+ public void setAutomaticBrightnessController(
+ AutomaticBrightnessController automaticBrightnessController) {
+ if (automaticBrightnessController == mAutomaticBrightnessController) {
+ return;
+ }
+ if (mAutomaticBrightnessController != null) {
+ mAutomaticBrightnessController.stop();
+ }
+ mAutomaticBrightnessController = automaticBrightnessController;
+ }
+
+ /**
+ * Returns if the auto-brightness of the associated display has been enabled or not
+ */
+ public boolean shouldUseAutoBrightness() {
+ return mUseAutoBrightness;
+ }
+
+ /**
+ * Sets the auto-brightness state of the associated display. Called when the user makes a change
+ * in the system setting to enable/disable the auto-brightness.
+ */
+ public void setUseAutoBrightness(boolean useAutoBrightness) {
+ mUseAutoBrightness = useAutoBrightness;
+ }
+
+ /**
+ * Returns if the user made brightness change events(Typically when they interact with the
+ * brightness slider) were accommodated in the auto-brightness mapping strategies. This doesn't
+ * account for the latest changes that have been made by the user.
+ */
+ public boolean isShortTermModelActive() {
+ return mIsShortTermModelActive;
+ }
+
+ /**
+ * Sets the pending auto-brightness adjustments in the system settings. Executed
+ * when there is a change in the brightness system setting, or when there is a user switch.
+ */
+ public void updatePendingAutoBrightnessAdjustments() {
+ final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(),
+ Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT);
+ mPendingAutoBrightnessAdjustment = Float.isNaN(adj) ? Float.NaN
+ : BrightnessUtils.clampBrightnessAdjustment(adj);
+ }
+
+ /**
+ * Sets the temporary auto-brightness adjustments
+ */
+ public void setTemporaryAutoBrightnessAdjustment(float temporaryAutoBrightnessAdjustment) {
+ mTemporaryAutoBrightnessAdjustment = temporaryAutoBrightnessAdjustment;
+ }
+
+ /**
+ * Dumps the state of this class.
+ */
+ public void dump(PrintWriter writer) {
+ writer.println("AutomaticBrightnessStrategy:");
+ writer.println(" mDisplayId=" + mDisplayId);
+ writer.println(" mAutoBrightnessAdjustment=" + mAutoBrightnessAdjustment);
+ writer.println(" mPendingAutoBrightnessAdjustment=" + mPendingAutoBrightnessAdjustment);
+ writer.println(
+ " mTemporaryAutoBrightnessAdjustment=" + mTemporaryAutoBrightnessAdjustment);
+ writer.println(" mShouldResetShortTermModel=" + mShouldResetShortTermModel);
+ writer.println(" mAppliedAutoBrightness=" + mAppliedAutoBrightness);
+ writer.println(" mAutoBrightnessAdjustmentChanged=" + mAutoBrightnessAdjustmentChanged);
+ writer.println(" mAppliedTemporaryAutoBrightnessAdjustment="
+ + mAppliedTemporaryAutoBrightnessAdjustment);
+ writer.println(" mUseAutoBrightness=" + mUseAutoBrightness);
+ writer.println(" mWasShortTermModelActive=" + mIsShortTermModelActive);
+ writer.println(" mAutoBrightnessAdjustmentReasonsFlags="
+ + mAutoBrightnessAdjustmentReasonsFlags);
+ }
+
+ /**
+ * Indicates if any auto-brightness adjustments have happened since the last auto-brightness was
+ * set.
+ */
+ public boolean getAutoBrightnessAdjustmentChanged() {
+ return mAutoBrightnessAdjustmentChanged;
+ }
+
+ /**
+ * Returns whether the latest temporary auto-brightness adjustments have been applied or not
+ */
+ public boolean isTemporaryAutoBrightnessAdjustmentApplied() {
+ return mAppliedTemporaryAutoBrightnessAdjustment;
+ }
+
+ /**
+ * Evaluates the target automatic brightness of the associated display.
+ * @param brightnessEvent Event object to populate with details about why the specific
+ * brightness was chosen.
+ */
+ public float getAutomaticScreenBrightness(BrightnessEvent brightnessEvent) {
+ float brightness = (mAutomaticBrightnessController != null)
+ ? mAutomaticBrightnessController.getAutomaticScreenBrightness(brightnessEvent)
+ : PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ adjustAutomaticBrightnessStateIfValid(brightness);
+ return brightness;
+ }
+
+ /**
+ * Get the automatic screen brightness based on the last observed lux reading. Used e.g. when
+ * entering doze - we disable the light sensor, invalidate the lux, but we still need to set
+ * the initial brightness in doze mode.
+ * @param brightnessEvent Event object to populate with details about why the specific
+ * brightness was chosen.
+ */
+ public float getAutomaticScreenBrightnessBasedOnLastObservedLux(
+ BrightnessEvent brightnessEvent) {
+ float brightness = (mAutomaticBrightnessController != null)
+ ? mAutomaticBrightnessController
+ .getAutomaticScreenBrightnessBasedOnLastObservedLux(brightnessEvent)
+ : PowerManager.BRIGHTNESS_INVALID_FLOAT;
+ adjustAutomaticBrightnessStateIfValid(brightness);
+ return brightness;
+ }
+
+ /**
+ * Gets the auto-brightness adjustment flag change reason
+ */
+ public int getAutoBrightnessAdjustmentReasonsFlags() {
+ return mAutoBrightnessAdjustmentReasonsFlags;
+ }
+
+ /**
+ * Returns if the auto brightness has been applied
+ */
+ public boolean hasAppliedAutoBrightness() {
+ return mAppliedAutoBrightness;
+ }
+
+ /**
+ * Used to adjust the state of this class when the automatic brightness value for the
+ * associated display is valid
+ */
+ @VisibleForTesting
+ void adjustAutomaticBrightnessStateIfValid(float brightnessState) {
+ mAutoBrightnessAdjustmentReasonsFlags = isTemporaryAutoBrightnessAdjustmentApplied()
+ ? BrightnessReason.ADJUSTMENT_AUTO_TEMP
+ : BrightnessReason.ADJUSTMENT_AUTO;
+ float newAutoBrightnessAdjustment =
+ (mAutomaticBrightnessController != null)
+ ? mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment()
+ : 0.0f;
+ if (!Float.isNaN(newAutoBrightnessAdjustment)
+ && mAutoBrightnessAdjustment != newAutoBrightnessAdjustment) {
+ // If the auto-brightness controller has decided to change the adjustment value
+ // used, make sure that's reflected in settings.
+ putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment);
+ } else {
+ mAutoBrightnessAdjustmentReasonsFlags = 0;
+ }
+ }
+
+ /**
+ * Sets up the system to reset the short term model. Note that this will not reset the model
+ * right away, but ensures that the reset happens whenever the next brightness change happens
+ */
+ @VisibleForTesting
+ void setShouldResetShortTermModel(boolean shouldResetShortTermModel) {
+ mShouldResetShortTermModel = shouldResetShortTermModel;
+ }
+
+ @VisibleForTesting
+ boolean shouldResetShortTermModel() {
+ return mShouldResetShortTermModel;
+ }
+
+ @VisibleForTesting
+ float getAutoBrightnessAdjustment() {
+ return mAutoBrightnessAdjustment;
+ }
+
+ @VisibleForTesting
+ float getPendingAutoBrightnessAdjustment() {
+ return mPendingAutoBrightnessAdjustment;
+ }
+
+ @VisibleForTesting
+ float getTemporaryAutoBrightnessAdjustment() {
+ return mTemporaryAutoBrightnessAdjustment;
+ }
+
+ @VisibleForTesting
+ void putAutoBrightnessAdjustmentSetting(float adjustment) {
+ if (mDisplayId == Display.DEFAULT_DISPLAY) {
+ mAutoBrightnessAdjustment = adjustment;
+ Settings.System.putFloatForUser(mContext.getContentResolver(),
+ Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adjustment,
+ UserHandle.USER_CURRENT);
+ }
+ }
+
+ /**
+ * Sets if the auto-brightness is applied on the latest brightness change.
+ */
+ public void setAutoBrightnessApplied(boolean autoBrightnessApplied) {
+ mAppliedAutoBrightness = autoBrightnessApplied;
+ }
+
+ /**
+ * Accommodates the latest manual changes made by the user. Also updates {@link
+ * AutomaticBrightnessController} about the changes and configures it accordingly.
+ */
+ @VisibleForTesting
+ void accommodateUserBrightnessChanges(boolean userSetBrightnessChanged,
+ float lastUserSetScreenBrightness, int policy, int displayState,
+ BrightnessConfiguration brightnessConfiguration, int autoBrightnessState) {
+ // Update the pending auto-brightness adjustments if any. This typically checks and adjusts
+ // the state of the class if the user moves the brightness slider and has settled to a
+ // different value
+ processPendingAutoBrightnessAdjustments();
+ // Update the temporary auto-brightness adjustments if any. This typically checks and
+ // adjusts the state of this class if the user is in the process of moving the brightness
+ // slider, but hasn't settled to any value yet
+ float autoBrightnessAdjustment = updateTemporaryAutoBrightnessAdjustments();
+ mIsShortTermModelActive = false;
+ // Configure auto-brightness.
+ if (mAutomaticBrightnessController != null) {
+ // Accommodate user changes if any in the auto-brightness model
+ mAutomaticBrightnessController.configure(autoBrightnessState,
+ brightnessConfiguration,
+ lastUserSetScreenBrightness,
+ userSetBrightnessChanged, autoBrightnessAdjustment,
+ mAutoBrightnessAdjustmentChanged, policy, displayState,
+ mShouldResetShortTermModel);
+ mShouldResetShortTermModel = false;
+ // We take note if the user brightness point is still being used in the current
+ // auto-brightness model.
+ mIsShortTermModelActive = mAutomaticBrightnessController.hasUserDataPoints();
+ }
+ }
+
+ /**
+ * Evaluates if there are any temporary auto-brightness adjustments which is not applied yet.
+ * Temporary brightness adjustments happen when the user moves the brightness slider in the
+ * auto-brightness mode, but hasn't settled to a value yet
+ */
+ private float updateTemporaryAutoBrightnessAdjustments() {
+ mAppliedTemporaryAutoBrightnessAdjustment =
+ !Float.isNaN(mTemporaryAutoBrightnessAdjustment);
+ // We do not update the mAutoBrightnessAdjustment with mTemporaryAutoBrightnessAdjustment
+ // since we have not settled to a value yet
+ return mAppliedTemporaryAutoBrightnessAdjustment
+ ? mTemporaryAutoBrightnessAdjustment : mAutoBrightnessAdjustment;
+ }
+
+ /**
+ * Returns the auto-brightness adjustment that is set in the system setting.
+ */
+ private float getAutoBrightnessAdjustmentSetting() {
+ final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(),
+ Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT);
+ return Float.isNaN(adj) ? 0.0f : BrightnessUtils.clampBrightnessAdjustment(adj);
+ }
+}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/BoostBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/BoostBrightnessStrategy.java
index 11edde9..9c1acea 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/BoostBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/BoostBrightnessStrategy.java
@@ -53,6 +53,11 @@
}
@Override
+ public int getReason() {
+ return BrightnessReason.REASON_BOOST;
+ }
+
+ @Override
public void dump(PrintWriter writer) {}
@Override
diff --git a/services/core/java/com/android/server/display/brightness/strategy/DisplayBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/DisplayBrightnessStrategy.java
index 7b49957..61dd6d5 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/DisplayBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/DisplayBrightnessStrategy.java
@@ -45,6 +45,11 @@
String getName();
/**
+ * Returns the reason for the change of the brightness
+ */
+ int getReason();
+
+ /**
* Dumps the state of the Strategy
* @param writer
*/
diff --git a/services/core/java/com/android/server/display/brightness/strategy/DozeBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/DozeBrightnessStrategy.java
index 5afdc42..1f7efd1 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/DozeBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/DozeBrightnessStrategy.java
@@ -53,4 +53,9 @@
StrategySelectionNotifyRequest strategySelectionNotifyRequest) {
// DO NOTHING
}
+
+ @Override
+ public int getReason() {
+ return BrightnessReason.REASON_DOZE;
+ }
}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/FollowerBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/FollowerBrightnessStrategy.java
index 0650c1c..baac276 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/FollowerBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/FollowerBrightnessStrategy.java
@@ -89,4 +89,9 @@
StrategySelectionNotifyRequest strategySelectionNotifyRequest) {
// DO NOTHING
}
+
+ @Override
+ public int getReason() {
+ return BrightnessReason.REASON_FOLLOWER;
+ }
}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/InvalidBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/InvalidBrightnessStrategy.java
index bf37ee0..4abd028 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/InvalidBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/InvalidBrightnessStrategy.java
@@ -51,4 +51,9 @@
StrategySelectionNotifyRequest strategySelectionNotifyRequest) {
// DO NOTHING
}
+
+ @Override
+ public int getReason() {
+ return BrightnessReason.REASON_UNKNOWN;
+ }
}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/OffloadBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/OffloadBrightnessStrategy.java
index d2bb1e2..64dc47c 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/OffloadBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/OffloadBrightnessStrategy.java
@@ -79,4 +79,9 @@
StrategySelectionNotifyRequest strategySelectionNotifyRequest) {
// DO NOTHING
}
+
+ @Override
+ public int getReason() {
+ return BrightnessReason.REASON_OFFLOAD;
+ }
}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/OverrideBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/OverrideBrightnessStrategy.java
index 653170c..9605a88 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/OverrideBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/OverrideBrightnessStrategy.java
@@ -52,4 +52,9 @@
StrategySelectionNotifyRequest strategySelectionNotifyRequest) {
// DO NOTHING
}
+
+ @Override
+ public int getReason() {
+ return BrightnessReason.REASON_OVERRIDE;
+ }
}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategy.java
index f0cce23..c9dc298 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/ScreenOffBrightnessStrategy.java
@@ -53,4 +53,9 @@
StrategySelectionNotifyRequest strategySelectionNotifyRequest) {
// DO NOTHING
}
+
+ @Override
+ public int getReason() {
+ return BrightnessReason.REASON_SCREEN_OFF;
+ }
}
diff --git a/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java b/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java
index 91e1d09..6a691d1 100644
--- a/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java
+++ b/services/core/java/com/android/server/display/brightness/strategy/TemporaryBrightnessStrategy.java
@@ -80,4 +80,9 @@
StrategySelectionNotifyRequest strategySelectionNotifyRequest) {
// DO NOTHING
}
+
+ @Override
+ public int getReason() {
+ return BrightnessReason.REASON_TEMPORARY;
+ }
}
diff --git a/services/core/java/com/android/server/display/config/EvenDimmerBrightnessData.java b/services/core/java/com/android/server/display/config/EvenDimmerBrightnessData.java
index 5556365..7e2e10a 100644
--- a/services/core/java/com/android/server/display/config/EvenDimmerBrightnessData.java
+++ b/services/core/java/com/android/server/display/config/EvenDimmerBrightnessData.java
@@ -66,6 +66,10 @@
* Spline, mapping between backlight and brightness
*/
public final Spline mBacklightToBrightness;
+
+ /**
+ * Spline, mapping the minimum nits for each lux condition.
+ */
public final Spline mMinLuxToNits;
@VisibleForTesting
@@ -114,34 +118,35 @@
return null;
}
- List<Float> nitsList = lbm.getNits();
- List<Float> backlightList = lbm.getBacklight();
- List<Float> brightnessList = lbm.getBrightness();
- float transitionPoints = lbm.getTransitionPoint().floatValue();
+ ComprehensiveBrightnessMap map = lbm.getBrightnessMapping();
+ if (map == null) {
+ return null;
+ }
+ String interpolation = map.getInterpolation();
- if (nitsList.isEmpty()
- || backlightList.size() != brightnessList.size()
- || backlightList.size() != nitsList.size()) {
- Slog.e(TAG, "Invalid even dimmer array lengths");
+ List<BrightnessPoint> brightnessPoints = map.getBrightnessPoint();
+ if (brightnessPoints.isEmpty()) {
return null;
}
- float[] nits = new float[nitsList.size()];
- float[] backlight = new float[nitsList.size()];
- float[] brightness = new float[nitsList.size()];
+ float[] nits = new float[brightnessPoints.size()];
+ float[] backlight = new float[brightnessPoints.size()];
+ float[] brightness = new float[brightnessPoints.size()];
- for (int i = 0; i < nitsList.size(); i++) {
- nits[i] = nitsList.get(i);
- backlight[i] = backlightList.get(i);
- brightness[i] = brightnessList.get(i);
+ for (int i = 0; i < brightnessPoints.size(); i++) {
+ BrightnessPoint val = brightnessPoints.get(i);
+ nits[i] = val.getNits().floatValue();
+ backlight[i] = val.getBacklight().floatValue();
+ brightness[i] = val.getBrightness().floatValue();
}
- final NitsMap map = lbm.getLuxToMinimumNitsMap();
- if (map == null) {
+ float transitionPoint = lbm.getTransitionPoint().floatValue();
+ final NitsMap minimumNitsMap = lbm.getLuxToMinimumNitsMap();
+ if (minimumNitsMap == null) {
Slog.e(TAG, "Invalid min lux to nits mapping");
return null;
}
- final List<Point> points = map.getPoint();
+ final List<Point> points = minimumNitsMap.getPoint();
final int size = points.size();
float[] minLux = new float[size];
@@ -164,7 +169,18 @@
++i;
}
- return new EvenDimmerBrightnessData(transitionPoints, nits, backlight, brightness,
+ // Explicitly choose linear interpolation.
+ if ("linear".equals(interpolation)) {
+ return new EvenDimmerBrightnessData(transitionPoint, nits, backlight, brightness,
+ new Spline.LinearSpline(backlight, nits),
+ new Spline.LinearSpline(nits, backlight),
+ new Spline.LinearSpline(brightness, backlight),
+ new Spline.LinearSpline(backlight, brightness),
+ new Spline.LinearSpline(minLux, minNits)
+ );
+ }
+
+ return new EvenDimmerBrightnessData(transitionPoint, nits, backlight, brightness,
Spline.createSpline(backlight, nits),
Spline.createSpline(nits, backlight),
Spline.createSpline(brightness, backlight),
diff --git a/services/core/java/com/android/server/flags/compaction.aconfig b/services/core/java/com/android/server/flags/compaction.aconfig
index 067a1c9..58cc560 100644
--- a/services/core/java/com/android/server/flags/compaction.aconfig
+++ b/services/core/java/com/android/server/flags/compaction.aconfig
@@ -1,5 +1,4 @@
package: "com.android.server.flags"
-container: "system"
flag {
name: "disable_system_compaction"
diff --git a/services/core/java/com/android/server/flags/pinner.aconfig b/services/core/java/com/android/server/flags/pinner.aconfig
index 16a45cd..606a6be 100644
--- a/services/core/java/com/android/server/flags/pinner.aconfig
+++ b/services/core/java/com/android/server/flags/pinner.aconfig
@@ -1,5 +1,4 @@
package: "com.android.server.flags"
-container: "system"
flag {
name: "pin_webview"
diff --git a/services/core/java/com/android/server/flags/services.aconfig b/services/core/java/com/android/server/flags/services.aconfig
index 8e0eb05..10b5eff 100644
--- a/services/core/java/com/android/server/flags/services.aconfig
+++ b/services/core/java/com/android/server/flags/services.aconfig
@@ -1,5 +1,4 @@
package: "com.android.server.flags"
-container: "system"
flag {
namespace: "wear_frameworks"
diff --git a/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionBackupHelper.java b/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionBackupHelper.java
index 5be0735..d494be5 100644
--- a/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionBackupHelper.java
+++ b/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionBackupHelper.java
@@ -17,6 +17,7 @@
package com.android.server.grammaticalinflection;
import android.app.backup.BackupManager;
+import android.content.AttributionSource;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -30,6 +31,7 @@
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.nio.ByteBuffer;
import java.time.Clock;
import java.time.Duration;
import java.util.HashMap;
@@ -47,6 +49,7 @@
private final PackageManager mPackageManager;
private final GrammaticalInflectionService mGrammaticalGenderService;
private final Clock mClock;
+ private final AttributionSource mAttributionSource;
static class StagedData {
final long mCreationTimeMillis;
@@ -58,8 +61,9 @@
}
}
- public GrammaticalInflectionBackupHelper(GrammaticalInflectionService grammaticalGenderService,
- PackageManager packageManager) {
+ public GrammaticalInflectionBackupHelper(AttributionSource attributionSource,
+ GrammaticalInflectionService grammaticalGenderService, PackageManager packageManager) {
+ mAttributionSource = attributionSource;
mGrammaticalGenderService = grammaticalGenderService;
mPackageManager = packageManager;
mClock = Clock.systemUTC();
@@ -115,6 +119,23 @@
}
}
+ /**
+ * Returns the system-gender to be backed up as a data-blob.
+ */
+ public byte[] getSystemBackupPayload(int userId) {
+ int gender = mGrammaticalGenderService.getSystemGrammaticalGender(mAttributionSource,
+ userId);
+ return intToByteArray(gender);
+ }
+
+ /**
+ * Restores the system-gender that were previously backed up.
+ */
+ public void applyRestoredSystemPayload(byte[] payload, int userId) {
+ int gender = convertByteArrayToInt(payload);
+ mGrammaticalGenderService.setSystemWideGrammaticalGender(gender, userId);
+ }
+
private boolean hasSetBeforeRestoring(String pkgName, int userId) {
return mGrammaticalGenderService.getApplicationGrammaticalGender(pkgName, userId)
!= Configuration.GRAMMATICAL_GENDER_NOT_SPECIFIED;
@@ -157,6 +178,17 @@
}
}
+ private byte[] intToByteArray(final int gender) {
+ ByteBuffer bb = ByteBuffer.allocate(4);
+ bb.putInt(gender);
+ return bb.array();
+ }
+
+ private int convertByteArrayToInt(byte[] intBytes) {
+ ByteBuffer byteBuffer = ByteBuffer.wrap(intBytes);
+ return byteBuffer.getInt();
+ }
+
private HashMap<String, Integer> readFromByteArray(byte[] payload) {
HashMap<String, Integer> data = new HashMap<>();
diff --git a/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionManagerInternal.java b/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionManagerInternal.java
index c2c82ed..2816d08 100644
--- a/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionManagerInternal.java
+++ b/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionManagerInternal.java
@@ -62,5 +62,16 @@
* Whether the package can get the system grammatical gender or not.
*/
public abstract boolean canGetSystemGrammaticalGender(int uid, @Nullable String packageName);
+
+
+ /**
+ * Returns the system-gender to be backed up as a data-blob.
+ */
+ public abstract @Nullable byte[] getSystemBackupPayload(int userId);
+
+ /**
+ * Restores the system-gender that were previously backed up.
+ */
+ public abstract void applyRestoredSystemPayload(byte[] payload, int userId);
}
diff --git a/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java b/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java
index 96d4bda..93a71b9 100644
--- a/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java
+++ b/services/core/java/com/android/server/grammaticalinflection/GrammaticalInflectionService.java
@@ -102,7 +102,8 @@
mContext = context;
mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
- mBackupHelper = new GrammaticalInflectionBackupHelper(this, context.getPackageManager());
+ mBackupHelper = new GrammaticalInflectionBackupHelper(mContext.getAttributionSource(), this,
+ context.getPackageManager());
mBinderService = new GrammaticalInflectionBinderService();
mPermissionManager = context.getSystemService(PermissionManager.class);
}
@@ -176,6 +177,18 @@
}
@Override
+ @Nullable
+ public byte[] getSystemBackupPayload(int userId) {
+ isCallerAllowed();
+ return mBackupHelper.getSystemBackupPayload(userId);
+ }
+
+ @Override
+ public void applyRestoredSystemPayload(byte[] payload, int userId) {
+ mBackupHelper.applyRestoredSystemPayload(payload, userId);
+ }
+
+ @Override
public int getSystemGrammaticalGender(int userId) {
return checkSystemTermsOfAddressIsEnabled()
? GrammaticalInflectionService.this.getSystemGrammaticalGender(
@@ -290,6 +303,7 @@
userId,
grammaticalGender != GRAMMATICAL_GENDER_NOT_SPECIFIED,
preValue != GRAMMATICAL_GENDER_NOT_SPECIFIED);
+ GrammaticalInflectionBackupHelper.notifyBackupManager();
} catch (RemoteException e) {
Log.w(TAG, "Can not update configuration", e);
}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 77119d5..f32c11d 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -1197,54 +1197,11 @@
}
@Override // Binder call
- public KeyboardLayout[] getKeyboardLayoutsForInputDevice(
- final InputDeviceIdentifier identifier) {
- return mKeyboardLayoutManager.getKeyboardLayoutsForInputDevice(identifier);
- }
-
- @Override // Binder call
public KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor) {
return mKeyboardLayoutManager.getKeyboardLayout(keyboardLayoutDescriptor);
}
@Override // Binder call
- public String getCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier) {
- return mKeyboardLayoutManager.getCurrentKeyboardLayoutForInputDevice(identifier);
- }
-
- @EnforcePermission(Manifest.permission.SET_KEYBOARD_LAYOUT)
- @Override // Binder call
- public void setCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
- String keyboardLayoutDescriptor) {
- super.setCurrentKeyboardLayoutForInputDevice_enforcePermission();
- mKeyboardLayoutManager.setCurrentKeyboardLayoutForInputDevice(identifier,
- keyboardLayoutDescriptor);
- }
-
- @Override // Binder call
- public String[] getEnabledKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) {
- return mKeyboardLayoutManager.getEnabledKeyboardLayoutsForInputDevice(identifier);
- }
-
- @EnforcePermission(Manifest.permission.SET_KEYBOARD_LAYOUT)
- @Override // Binder call
- public void addKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
- String keyboardLayoutDescriptor) {
- super.addKeyboardLayoutForInputDevice_enforcePermission();
- mKeyboardLayoutManager.addKeyboardLayoutForInputDevice(identifier,
- keyboardLayoutDescriptor);
- }
-
- @EnforcePermission(Manifest.permission.SET_KEYBOARD_LAYOUT)
- @Override // Binder call
- public void removeKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
- String keyboardLayoutDescriptor) {
- super.removeKeyboardLayoutForInputDevice_enforcePermission();
- mKeyboardLayoutManager.removeKeyboardLayoutForInputDevice(identifier,
- keyboardLayoutDescriptor);
- }
-
- @Override // Binder call
public KeyboardLayoutSelectionResult getKeyboardLayoutForInputDevice(
InputDeviceIdentifier identifier, @UserIdInt int userId,
@NonNull InputMethodInfo imeInfo, @Nullable InputMethodSubtype imeSubtype) {
@@ -1270,11 +1227,6 @@
imeInfo, imeSubtype);
}
-
- public void switchKeyboardLayout(int deviceId, int direction) {
- mKeyboardLayoutManager.switchKeyboardLayout(deviceId, direction);
- }
-
public void setFocusedApplication(int displayId, InputApplicationHandle application) {
mNative.setFocusedApplication(displayId, application);
}
diff --git a/services/core/java/com/android/server/input/KeyboardLayoutManager.java b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
index 6610081..9ba647f 100644
--- a/services/core/java/com/android/server/input/KeyboardLayoutManager.java
+++ b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
@@ -60,7 +60,6 @@
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArrayMap;
-import android.util.FeatureFlagUtils;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
@@ -69,7 +68,6 @@
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
-import android.widget.Toast;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -96,7 +94,6 @@
import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import java.util.stream.Stream;
/**
* A component of {@link InputManagerService} responsible for managing Physical Keyboard layouts.
@@ -112,9 +109,8 @@
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final int MSG_UPDATE_EXISTING_DEVICES = 1;
- private static final int MSG_SWITCH_KEYBOARD_LAYOUT = 2;
- private static final int MSG_RELOAD_KEYBOARD_LAYOUTS = 3;
- private static final int MSG_UPDATE_KEYBOARD_LAYOUTS = 4;
+ private static final int MSG_RELOAD_KEYBOARD_LAYOUTS = 2;
+ private static final int MSG_UPDATE_KEYBOARD_LAYOUTS = 3;
private final Context mContext;
private final NativeInputManagerService mNative;
@@ -126,13 +122,14 @@
// Connected keyboards with associated keyboard layouts (either auto-detected or manually
// selected layout).
private final SparseArray<KeyboardConfiguration> mConfiguredKeyboards = new SparseArray<>();
- private Toast mSwitchedKeyboardLayoutToast;
// This cache stores "best-matched" layouts so that we don't need to run the matching
// algorithm repeatedly.
@GuardedBy("mKeyboardLayoutCache")
private final Map<String, KeyboardLayoutSelectionResult> mKeyboardLayoutCache =
new ArrayMap<>();
+
+ private HashSet<String> mAvailableLayouts = new HashSet<>();
private final Object mImeInfoLock = new Object();
@Nullable
@GuardedBy("mImeInfoLock")
@@ -206,68 +203,51 @@
}
boolean needToShowNotification = false;
- if (!useNewSettingsUi()) {
- synchronized (mDataStore) {
- String layout = getCurrentKeyboardLayoutForInputDevice(inputDevice.getIdentifier());
- if (layout == null) {
- layout = getDefaultKeyboardLayout(inputDevice);
- if (layout != null) {
- setCurrentKeyboardLayoutForInputDevice(inputDevice.getIdentifier(), layout);
- }
- }
- if (layout == null) {
- // In old settings show notification always until user manually selects a
- // layout in the settings.
+ Set<String> selectedLayouts = new HashSet<>();
+ List<ImeInfo> imeInfoList = getImeInfoListForLayoutMapping();
+ List<KeyboardLayoutSelectionResult> resultList = new ArrayList<>();
+ boolean hasMissingLayout = false;
+ for (ImeInfo imeInfo : imeInfoList) {
+ // Check if the layout has been previously configured
+ KeyboardLayoutSelectionResult result = getKeyboardLayoutForInputDeviceInternal(
+ keyboardIdentifier, imeInfo);
+ if (result.getLayoutDescriptor() != null) {
+ selectedLayouts.add(result.getLayoutDescriptor());
+ } else {
+ hasMissingLayout = true;
+ }
+ resultList.add(result);
+ }
+
+ if (DEBUG) {
+ Slog.d(TAG,
+ "Layouts selected for input device: " + keyboardIdentifier
+ + " -> selectedLayouts: " + selectedLayouts);
+ }
+
+ // If even one layout not configured properly, we need to ask user to configure
+ // the keyboard properly from the Settings.
+ if (hasMissingLayout) {
+ selectedLayouts.clear();
+ }
+
+ config.setConfiguredLayouts(selectedLayouts);
+
+ synchronized (mDataStore) {
+ try {
+ final String key = keyboardIdentifier.toString();
+ if (mDataStore.setSelectedKeyboardLayouts(key, selectedLayouts)) {
+ // Need to show the notification only if layout selection changed
+ // from the previous configuration
needToShowNotification = true;
}
- }
- } else {
- Set<String> selectedLayouts = new HashSet<>();
- List<ImeInfo> imeInfoList = getImeInfoListForLayoutMapping();
- List<KeyboardLayoutSelectionResult> resultList = new ArrayList<>();
- boolean hasMissingLayout = false;
- for (ImeInfo imeInfo : imeInfoList) {
- // Check if the layout has been previously configured
- KeyboardLayoutSelectionResult result = getKeyboardLayoutForInputDeviceInternal(
- keyboardIdentifier, imeInfo);
- boolean noLayoutFound = result.getLayoutDescriptor() == null;
- if (!noLayoutFound) {
- selectedLayouts.add(result.getLayoutDescriptor());
+
+ if (shouldLogConfiguration) {
+ logKeyboardConfigurationEvent(inputDevice, imeInfoList, resultList,
+ !mDataStore.hasInputDeviceEntry(key));
}
- resultList.add(result);
- hasMissingLayout |= noLayoutFound;
- }
-
- if (DEBUG) {
- Slog.d(TAG,
- "Layouts selected for input device: " + keyboardIdentifier
- + " -> selectedLayouts: " + selectedLayouts);
- }
-
- // If even one layout not configured properly, we need to ask user to configure
- // the keyboard properly from the Settings.
- if (hasMissingLayout) {
- selectedLayouts.clear();
- }
-
- config.setConfiguredLayouts(selectedLayouts);
-
- synchronized (mDataStore) {
- try {
- final String key = keyboardIdentifier.toString();
- if (mDataStore.setSelectedKeyboardLayouts(key, selectedLayouts)) {
- // Need to show the notification only if layout selection changed
- // from the previous configuration
- needToShowNotification = true;
- }
-
- if (shouldLogConfiguration) {
- logKeyboardConfigurationEvent(inputDevice, imeInfoList, resultList,
- !mDataStore.hasInputDeviceEntry(key));
- }
- } finally {
- mDataStore.saveIfNeeded();
- }
+ } finally {
+ mDataStore.saveIfNeeded();
}
}
if (needToShowNotification) {
@@ -275,63 +255,6 @@
}
}
- private String getDefaultKeyboardLayout(final InputDevice inputDevice) {
- final Locale systemLocale = mContext.getResources().getConfiguration().locale;
- // If our locale doesn't have a language for some reason, then we don't really have a
- // reasonable default.
- if (TextUtils.isEmpty(systemLocale.getLanguage())) {
- return null;
- }
- final List<KeyboardLayout> layouts = new ArrayList<>();
- visitAllKeyboardLayouts((resources, keyboardLayoutResId, layout) -> {
- // Only select a default when we know the layout is appropriate. For now, this
- // means it's a custom layout for a specific keyboard.
- if (layout.getVendorId() != inputDevice.getVendorId()
- || layout.getProductId() != inputDevice.getProductId()) {
- return;
- }
- final LocaleList locales = layout.getLocales();
- for (int localeIndex = 0; localeIndex < locales.size(); ++localeIndex) {
- final Locale locale = locales.get(localeIndex);
- if (locale != null && isCompatibleLocale(systemLocale, locale)) {
- layouts.add(layout);
- break;
- }
- }
- });
-
- if (layouts.isEmpty()) {
- return null;
- }
-
- // First sort so that ones with higher priority are listed at the top
- Collections.sort(layouts);
- // Next we want to try to find an exact match of language, country and variant.
- for (KeyboardLayout layout : layouts) {
- final LocaleList locales = layout.getLocales();
- for (int localeIndex = 0; localeIndex < locales.size(); ++localeIndex) {
- final Locale locale = locales.get(localeIndex);
- if (locale != null && locale.getCountry().equals(systemLocale.getCountry())
- && locale.getVariant().equals(systemLocale.getVariant())) {
- return layout.getDescriptor();
- }
- }
- }
- // Then try an exact match of language and country
- for (KeyboardLayout layout : layouts) {
- final LocaleList locales = layout.getLocales();
- for (int localeIndex = 0; localeIndex < locales.size(); ++localeIndex) {
- final Locale locale = locales.get(localeIndex);
- if (locale != null && locale.getCountry().equals(systemLocale.getCountry())) {
- return layout.getDescriptor();
- }
- }
- }
-
- // Give up and just use the highest priority layout with matching language
- return layouts.get(0).getDescriptor();
- }
-
private static boolean isCompatibleLocale(Locale systemLocale, Locale keyboardLocale) {
// Different languages are never compatible
if (!systemLocale.getLanguage().equals(keyboardLocale.getLanguage())) {
@@ -343,11 +266,19 @@
|| systemLocale.getCountry().equals(keyboardLocale.getCountry());
}
+ @MainThread
private void updateKeyboardLayouts() {
// Scan all input devices state for keyboard layouts that have been uninstalled.
- final HashSet<String> availableKeyboardLayouts = new HashSet<String>();
+ final HashSet<String> availableKeyboardLayouts = new HashSet<>();
visitAllKeyboardLayouts((resources, keyboardLayoutResId, layout) ->
availableKeyboardLayouts.add(layout.getDescriptor()));
+
+ // If available layouts don't change, there is no need to reload layouts.
+ if (mAvailableLayouts.equals(availableKeyboardLayouts)) {
+ return;
+ }
+ mAvailableLayouts = availableKeyboardLayouts;
+
synchronized (mDataStore) {
try {
mDataStore.removeUninstalledKeyboardLayouts(availableKeyboardLayouts);
@@ -374,53 +305,6 @@
}
@AnyThread
- public KeyboardLayout[] getKeyboardLayoutsForInputDevice(
- final InputDeviceIdentifier identifier) {
- if (useNewSettingsUi()) {
- // Provide all supported keyboard layouts since Ime info is not provided
- return getKeyboardLayouts();
- }
- final String[] enabledLayoutDescriptors =
- getEnabledKeyboardLayoutsForInputDevice(identifier);
- final ArrayList<KeyboardLayout> enabledLayouts =
- new ArrayList<>(enabledLayoutDescriptors.length);
- final ArrayList<KeyboardLayout> potentialLayouts = new ArrayList<>();
- visitAllKeyboardLayouts(new KeyboardLayoutVisitor() {
- boolean mHasSeenDeviceSpecificLayout;
-
- @Override
- public void visitKeyboardLayout(Resources resources,
- int keyboardLayoutResId, KeyboardLayout layout) {
- // First check if it's enabled. If the keyboard layout is enabled then we always
- // want to return it as a possible layout for the device.
- for (String s : enabledLayoutDescriptors) {
- if (s != null && s.equals(layout.getDescriptor())) {
- enabledLayouts.add(layout);
- return;
- }
- }
- // Next find any potential layouts that aren't yet enabled for the device. For
- // devices that have special layouts we assume there's a reason that the generic
- // layouts don't work for them so we don't want to return them since it's likely
- // to result in a poor user experience.
- if (layout.getVendorId() == identifier.getVendorId()
- && layout.getProductId() == identifier.getProductId()) {
- if (!mHasSeenDeviceSpecificLayout) {
- mHasSeenDeviceSpecificLayout = true;
- potentialLayouts.clear();
- }
- potentialLayouts.add(layout);
- } else if (layout.getVendorId() == -1 && layout.getProductId() == -1
- && !mHasSeenDeviceSpecificLayout) {
- potentialLayouts.add(layout);
- }
- }
- });
- return Stream.concat(enabledLayouts.stream(), potentialLayouts.stream()).toArray(
- KeyboardLayout[]::new);
- }
-
- @AnyThread
@Nullable
public KeyboardLayout getKeyboardLayout(@NonNull String keyboardLayoutDescriptor) {
Objects.requireNonNull(keyboardLayoutDescriptor,
@@ -580,195 +464,16 @@
return LocaleList.forLanguageTags(languageTags.replace('|', ','));
}
- @AnyThread
- @Nullable
- public String getCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier) {
- if (useNewSettingsUi()) {
- Slog.e(TAG, "getCurrentKeyboardLayoutForInputDevice API not supported");
- return null;
- }
- String key = new KeyboardIdentifier(identifier).toString();
- synchronized (mDataStore) {
- String layout;
- // try loading it using the layout descriptor if we have it
- layout = mDataStore.getCurrentKeyboardLayout(key);
- if (layout == null && !key.equals(identifier.getDescriptor())) {
- // if it doesn't exist fall back to the device descriptor
- layout = mDataStore.getCurrentKeyboardLayout(identifier.getDescriptor());
- }
- if (DEBUG) {
- Slog.d(TAG, "getCurrentKeyboardLayoutForInputDevice() "
- + identifier.toString() + ": " + layout);
- }
- return layout;
- }
- }
-
- @AnyThread
- public void setCurrentKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
- String keyboardLayoutDescriptor) {
- if (useNewSettingsUi()) {
- Slog.e(TAG, "setCurrentKeyboardLayoutForInputDevice API not supported");
- return;
- }
-
- Objects.requireNonNull(keyboardLayoutDescriptor,
- "keyboardLayoutDescriptor must not be null");
- String key = new KeyboardIdentifier(identifier).toString();
- synchronized (mDataStore) {
- try {
- if (mDataStore.setCurrentKeyboardLayout(key, keyboardLayoutDescriptor)) {
- if (DEBUG) {
- Slog.d(TAG, "setCurrentKeyboardLayoutForInputDevice() " + identifier
- + " key: " + key
- + " keyboardLayoutDescriptor: " + keyboardLayoutDescriptor);
- }
- mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS);
- }
- } finally {
- mDataStore.saveIfNeeded();
- }
- }
- }
-
- @AnyThread
- public String[] getEnabledKeyboardLayoutsForInputDevice(InputDeviceIdentifier identifier) {
- if (useNewSettingsUi()) {
- Slog.e(TAG, "getEnabledKeyboardLayoutsForInputDevice API not supported");
- return new String[0];
- }
- String key = new KeyboardIdentifier(identifier).toString();
- synchronized (mDataStore) {
- String[] layouts = mDataStore.getKeyboardLayouts(key);
- if ((layouts == null || layouts.length == 0)
- && !key.equals(identifier.getDescriptor())) {
- layouts = mDataStore.getKeyboardLayouts(identifier.getDescriptor());
- }
- return layouts;
- }
- }
-
- @AnyThread
- public void addKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
- String keyboardLayoutDescriptor) {
- if (useNewSettingsUi()) {
- Slog.e(TAG, "addKeyboardLayoutForInputDevice API not supported");
- return;
- }
- Objects.requireNonNull(keyboardLayoutDescriptor,
- "keyboardLayoutDescriptor must not be null");
-
- String key = new KeyboardIdentifier(identifier).toString();
- synchronized (mDataStore) {
- try {
- String oldLayout = mDataStore.getCurrentKeyboardLayout(key);
- if (oldLayout == null && !key.equals(identifier.getDescriptor())) {
- oldLayout = mDataStore.getCurrentKeyboardLayout(identifier.getDescriptor());
- }
- if (mDataStore.addKeyboardLayout(key, keyboardLayoutDescriptor)
- && !Objects.equals(oldLayout,
- mDataStore.getCurrentKeyboardLayout(key))) {
- mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS);
- }
- } finally {
- mDataStore.saveIfNeeded();
- }
- }
- }
-
- @AnyThread
- public void removeKeyboardLayoutForInputDevice(InputDeviceIdentifier identifier,
- String keyboardLayoutDescriptor) {
- if (useNewSettingsUi()) {
- Slog.e(TAG, "removeKeyboardLayoutForInputDevice API not supported");
- return;
- }
- Objects.requireNonNull(keyboardLayoutDescriptor,
- "keyboardLayoutDescriptor must not be null");
-
- String key = new KeyboardIdentifier(identifier).toString();
- synchronized (mDataStore) {
- try {
- String oldLayout = mDataStore.getCurrentKeyboardLayout(key);
- if (oldLayout == null && !key.equals(identifier.getDescriptor())) {
- oldLayout = mDataStore.getCurrentKeyboardLayout(identifier.getDescriptor());
- }
- boolean removed = mDataStore.removeKeyboardLayout(key, keyboardLayoutDescriptor);
- if (!key.equals(identifier.getDescriptor())) {
- // We need to remove from both places to ensure it is gone
- removed |= mDataStore.removeKeyboardLayout(identifier.getDescriptor(),
- keyboardLayoutDescriptor);
- }
- if (removed && !Objects.equals(oldLayout,
- mDataStore.getCurrentKeyboardLayout(key))) {
- mHandler.sendEmptyMessage(MSG_RELOAD_KEYBOARD_LAYOUTS);
- }
- } finally {
- mDataStore.saveIfNeeded();
- }
- }
- }
-
- @AnyThread
- public void switchKeyboardLayout(int deviceId, int direction) {
- if (useNewSettingsUi()) {
- Slog.e(TAG, "switchKeyboardLayout API not supported");
- return;
- }
- mHandler.obtainMessage(MSG_SWITCH_KEYBOARD_LAYOUT, deviceId, direction).sendToTarget();
- }
-
- @MainThread
- private void handleSwitchKeyboardLayout(int deviceId, int direction) {
- final InputDevice device = getInputDevice(deviceId);
- if (device != null) {
- final boolean changed;
- final String keyboardLayoutDescriptor;
-
- String key = new KeyboardIdentifier(device.getIdentifier()).toString();
- synchronized (mDataStore) {
- try {
- changed = mDataStore.switchKeyboardLayout(key, direction);
- keyboardLayoutDescriptor = mDataStore.getCurrentKeyboardLayout(
- key);
- } finally {
- mDataStore.saveIfNeeded();
- }
- }
-
- if (changed) {
- if (mSwitchedKeyboardLayoutToast != null) {
- mSwitchedKeyboardLayoutToast.cancel();
- mSwitchedKeyboardLayoutToast = null;
- }
- if (keyboardLayoutDescriptor != null) {
- KeyboardLayout keyboardLayout = getKeyboardLayout(keyboardLayoutDescriptor);
- if (keyboardLayout != null) {
- mSwitchedKeyboardLayoutToast = Toast.makeText(
- mContext, keyboardLayout.getLabel(), Toast.LENGTH_SHORT);
- mSwitchedKeyboardLayoutToast.show();
- }
- }
-
- reloadKeyboardLayouts();
- }
- }
- }
-
@Nullable
@AnyThread
public String[] getKeyboardLayoutOverlay(InputDeviceIdentifier identifier, String languageTag,
String layoutType) {
String keyboardLayoutDescriptor;
- if (useNewSettingsUi()) {
- synchronized (mImeInfoLock) {
- KeyboardLayoutSelectionResult result = getKeyboardLayoutForInputDeviceInternal(
- new KeyboardIdentifier(identifier, languageTag, layoutType),
- mCurrentImeInfo);
- keyboardLayoutDescriptor = result.getLayoutDescriptor();
- }
- } else {
- keyboardLayoutDescriptor = getCurrentKeyboardLayoutForInputDevice(identifier);
+ synchronized (mImeInfoLock) {
+ KeyboardLayoutSelectionResult result = getKeyboardLayoutForInputDeviceInternal(
+ new KeyboardIdentifier(identifier, languageTag, layoutType),
+ mCurrentImeInfo);
+ keyboardLayoutDescriptor = result.getLayoutDescriptor();
}
if (keyboardLayoutDescriptor == null) {
return null;
@@ -797,10 +502,6 @@
public KeyboardLayoutSelectionResult getKeyboardLayoutForInputDevice(
InputDeviceIdentifier identifier, @UserIdInt int userId,
@NonNull InputMethodInfo imeInfo, @Nullable InputMethodSubtype imeSubtype) {
- if (!useNewSettingsUi()) {
- Slog.e(TAG, "getKeyboardLayoutForInputDevice() API not supported");
- return FAILED;
- }
InputDevice inputDevice = getInputDevice(identifier);
if (inputDevice == null || inputDevice.isVirtual() || !inputDevice.isFullKeyboard()) {
return FAILED;
@@ -820,10 +521,6 @@
@UserIdInt int userId, @NonNull InputMethodInfo imeInfo,
@Nullable InputMethodSubtype imeSubtype,
String keyboardLayoutDescriptor) {
- if (!useNewSettingsUi()) {
- Slog.e(TAG, "setKeyboardLayoutForInputDevice() API not supported");
- return;
- }
Objects.requireNonNull(keyboardLayoutDescriptor,
"keyboardLayoutDescriptor must not be null");
InputDevice inputDevice = getInputDevice(identifier);
@@ -854,10 +551,6 @@
public KeyboardLayout[] getKeyboardLayoutListForInputDevice(InputDeviceIdentifier identifier,
@UserIdInt int userId, @NonNull InputMethodInfo imeInfo,
@Nullable InputMethodSubtype imeSubtype) {
- if (!useNewSettingsUi()) {
- Slog.e(TAG, "getKeyboardLayoutListForInputDevice() API not supported");
- return new KeyboardLayout[0];
- }
InputDevice inputDevice = getInputDevice(identifier);
if (inputDevice == null || inputDevice.isVirtual() || !inputDevice.isFullKeyboard()) {
return new KeyboardLayout[0];
@@ -923,10 +616,6 @@
public void onInputMethodSubtypeChanged(@UserIdInt int userId,
@Nullable InputMethodSubtypeHandle subtypeHandle,
@Nullable InputMethodSubtype subtype) {
- if (!useNewSettingsUi()) {
- Slog.e(TAG, "onInputMethodSubtypeChanged() API not supported");
- return;
- }
if (subtypeHandle == null) {
if (DEBUG) {
Slog.d(TAG, "No InputMethod is running, ignoring change");
@@ -1289,9 +978,6 @@
onInputDeviceAdded(deviceId);
}
return true;
- case MSG_SWITCH_KEYBOARD_LAYOUT:
- handleSwitchKeyboardLayout(msg.arg1, msg.arg2);
- return true;
case MSG_RELOAD_KEYBOARD_LAYOUTS:
reloadKeyboardLayouts();
return true;
@@ -1303,10 +989,6 @@
}
}
- private boolean useNewSettingsUi() {
- return FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI);
- }
-
@Nullable
private InputDevice getInputDevice(int deviceId) {
InputManager inputManager = mContext.getSystemService(InputManager.class);
diff --git a/services/core/java/com/android/server/input/PersistentDataStore.java b/services/core/java/com/android/server/input/PersistentDataStore.java
index 31083fd..7859253 100644
--- a/services/core/java/com/android/server/input/PersistentDataStore.java
+++ b/services/core/java/com/android/server/input/PersistentDataStore.java
@@ -27,7 +27,6 @@
import android.view.Surface;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
import com.android.internal.util.XmlUtils;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
@@ -42,7 +41,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -74,7 +72,7 @@
new HashMap<String, InputDeviceState>();
// The interface for methods which should be replaced by the test harness.
- private Injector mInjector;
+ private final Injector mInjector;
// True if the data has been loaded.
private boolean mLoaded;
@@ -83,7 +81,7 @@
private boolean mDirty;
// Storing key remapping
- private Map<Integer, Integer> mKeyRemapping = new HashMap<>();
+ private final Map<Integer, Integer> mKeyRemapping = new HashMap<>();
public PersistentDataStore() {
this(new Injector());
@@ -130,22 +128,6 @@
}
@Nullable
- public String getCurrentKeyboardLayout(String inputDeviceDescriptor) {
- InputDeviceState state = getInputDeviceState(inputDeviceDescriptor);
- return state != null ? state.getCurrentKeyboardLayout() : null;
- }
-
- public boolean setCurrentKeyboardLayout(String inputDeviceDescriptor,
- String keyboardLayoutDescriptor) {
- InputDeviceState state = getOrCreateInputDeviceState(inputDeviceDescriptor);
- if (state.setCurrentKeyboardLayout(keyboardLayoutDescriptor)) {
- setDirty();
- return true;
- }
- return false;
- }
-
- @Nullable
public String getKeyboardLayout(String inputDeviceDescriptor, String key) {
InputDeviceState state = getInputDeviceState(inputDeviceDescriptor);
return state != null ? state.getKeyboardLayout(key) : null;
@@ -171,43 +153,6 @@
return false;
}
- public String[] getKeyboardLayouts(String inputDeviceDescriptor) {
- InputDeviceState state = getInputDeviceState(inputDeviceDescriptor);
- if (state == null) {
- return (String[])ArrayUtils.emptyArray(String.class);
- }
- return state.getKeyboardLayouts();
- }
-
- public boolean addKeyboardLayout(String inputDeviceDescriptor,
- String keyboardLayoutDescriptor) {
- InputDeviceState state = getOrCreateInputDeviceState(inputDeviceDescriptor);
- if (state.addKeyboardLayout(keyboardLayoutDescriptor)) {
- setDirty();
- return true;
- }
- return false;
- }
-
- public boolean removeKeyboardLayout(String inputDeviceDescriptor,
- String keyboardLayoutDescriptor) {
- InputDeviceState state = getOrCreateInputDeviceState(inputDeviceDescriptor);
- if (state.removeKeyboardLayout(keyboardLayoutDescriptor)) {
- setDirty();
- return true;
- }
- return false;
- }
-
- public boolean switchKeyboardLayout(String inputDeviceDescriptor, int direction) {
- InputDeviceState state = getInputDeviceState(inputDeviceDescriptor);
- if (state != null && state.switchKeyboardLayout(direction)) {
- setDirty();
- return true;
- }
- return false;
- }
-
public boolean setKeyboardBacklightBrightness(String inputDeviceDescriptor, int lightId,
int brightness) {
InputDeviceState state = getOrCreateInputDeviceState(inputDeviceDescriptor);
@@ -417,9 +362,6 @@
"x_ymix", "x_offset", "y_xmix", "y_scale", "y_offset" };
private final TouchCalibration[] mTouchCalibration = new TouchCalibration[4];
- @Nullable
- private String mCurrentKeyboardLayout;
- private final ArrayList<String> mKeyboardLayouts = new ArrayList<String>();
private final SparseIntArray mKeyboardBacklightBrightnessMap = new SparseIntArray();
private final Map<String, String> mKeyboardLayoutMap = new ArrayMap<>();
@@ -465,49 +407,6 @@
return true;
}
- @Nullable
- public String getCurrentKeyboardLayout() {
- return mCurrentKeyboardLayout;
- }
-
- public boolean setCurrentKeyboardLayout(String keyboardLayout) {
- if (Objects.equals(mCurrentKeyboardLayout, keyboardLayout)) {
- return false;
- }
- addKeyboardLayout(keyboardLayout);
- mCurrentKeyboardLayout = keyboardLayout;
- return true;
- }
-
- public String[] getKeyboardLayouts() {
- if (mKeyboardLayouts.isEmpty()) {
- return (String[])ArrayUtils.emptyArray(String.class);
- }
- return mKeyboardLayouts.toArray(new String[mKeyboardLayouts.size()]);
- }
-
- public boolean addKeyboardLayout(String keyboardLayout) {
- int index = Collections.binarySearch(mKeyboardLayouts, keyboardLayout);
- if (index >= 0) {
- return false;
- }
- mKeyboardLayouts.add(-index - 1, keyboardLayout);
- if (mCurrentKeyboardLayout == null) {
- mCurrentKeyboardLayout = keyboardLayout;
- }
- return true;
- }
-
- public boolean removeKeyboardLayout(String keyboardLayout) {
- int index = Collections.binarySearch(mKeyboardLayouts, keyboardLayout);
- if (index < 0) {
- return false;
- }
- mKeyboardLayouts.remove(index);
- updateCurrentKeyboardLayoutIfRemoved(keyboardLayout, index);
- return true;
- }
-
public boolean setKeyboardBacklightBrightness(int lightId, int brightness) {
if (mKeyboardBacklightBrightnessMap.get(lightId, INVALID_VALUE) == brightness) {
return false;
@@ -521,48 +420,8 @@
return brightness == INVALID_VALUE ? OptionalInt.empty() : OptionalInt.of(brightness);
}
- private void updateCurrentKeyboardLayoutIfRemoved(
- String removedKeyboardLayout, int removedIndex) {
- if (Objects.equals(mCurrentKeyboardLayout, removedKeyboardLayout)) {
- if (!mKeyboardLayouts.isEmpty()) {
- int index = removedIndex;
- if (index == mKeyboardLayouts.size()) {
- index = 0;
- }
- mCurrentKeyboardLayout = mKeyboardLayouts.get(index);
- } else {
- mCurrentKeyboardLayout = null;
- }
- }
- }
-
- public boolean switchKeyboardLayout(int direction) {
- final int size = mKeyboardLayouts.size();
- if (size < 2) {
- return false;
- }
- int index = Collections.binarySearch(mKeyboardLayouts, mCurrentKeyboardLayout);
- assert index >= 0;
- if (direction > 0) {
- index = (index + 1) % size;
- } else {
- index = (index + size - 1) % size;
- }
- mCurrentKeyboardLayout = mKeyboardLayouts.get(index);
- return true;
- }
-
public boolean removeUninstalledKeyboardLayouts(Set<String> availableKeyboardLayouts) {
boolean changed = false;
- for (int i = mKeyboardLayouts.size(); i-- > 0; ) {
- String keyboardLayout = mKeyboardLayouts.get(i);
- if (!availableKeyboardLayouts.contains(keyboardLayout)) {
- Slog.i(TAG, "Removing uninstalled keyboard layout " + keyboardLayout);
- mKeyboardLayouts.remove(i);
- updateCurrentKeyboardLayoutIfRemoved(keyboardLayout, i);
- changed = true;
- }
- }
List<String> removedEntries = new ArrayList<>();
for (String key : mKeyboardLayoutMap.keySet()) {
if (!availableKeyboardLayouts.contains(mKeyboardLayoutMap.get(key))) {
@@ -582,27 +441,7 @@
throws IOException, XmlPullParserException {
final int outerDepth = parser.getDepth();
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
- if (parser.getName().equals("keyboard-layout")) {
- String descriptor = parser.getAttributeValue(null, "descriptor");
- if (descriptor == null) {
- throw new XmlPullParserException(
- "Missing descriptor attribute on keyboard-layout.");
- }
- String current = parser.getAttributeValue(null, "current");
- if (mKeyboardLayouts.contains(descriptor)) {
- throw new XmlPullParserException(
- "Found duplicate keyboard layout.");
- }
-
- mKeyboardLayouts.add(descriptor);
- if (current != null && current.equals("true")) {
- if (mCurrentKeyboardLayout != null) {
- throw new XmlPullParserException(
- "Found multiple current keyboard layouts.");
- }
- mCurrentKeyboardLayout = descriptor;
- }
- } else if (parser.getName().equals("keyed-keyboard-layout")) {
+ if (parser.getName().equals("keyed-keyboard-layout")) {
String key = parser.getAttributeValue(null, "key");
if (key == null) {
throw new XmlPullParserException(
@@ -676,27 +515,9 @@
}
}
}
-
- // Maintain invariant that layouts are sorted.
- Collections.sort(mKeyboardLayouts);
-
- // Maintain invariant that there is always a current keyboard layout unless
- // there are none installed.
- if (mCurrentKeyboardLayout == null && !mKeyboardLayouts.isEmpty()) {
- mCurrentKeyboardLayout = mKeyboardLayouts.get(0);
- }
}
public void saveToXml(TypedXmlSerializer serializer) throws IOException {
- for (String layout : mKeyboardLayouts) {
- serializer.startTag(null, "keyboard-layout");
- serializer.attribute(null, "descriptor", layout);
- if (layout.equals(mCurrentKeyboardLayout)) {
- serializer.attributeBoolean(null, "current", true);
- }
- serializer.endTag(null, "keyboard-layout");
- }
-
for (String key : mKeyboardLayoutMap.keySet()) {
serializer.startTag(null, "keyed-keyboard-layout");
serializer.attribute(null, "key", key);
diff --git a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
index 31ce630..ffc2319 100644
--- a/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
+++ b/services/core/java/com/android/server/inputmethod/ZeroJankProxy.java
@@ -196,7 +196,10 @@
return true;
}
- private void sendResultReceiverFailure(ResultReceiver resultReceiver) {
+ private void sendResultReceiverFailure(@Nullable ResultReceiver resultReceiver) {
+ if (resultReceiver == null) {
+ return;
+ }
resultReceiver.send(
mIsInputShown.getAsBoolean()
? InputMethodManager.RESULT_UNCHANGED_SHOWN
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 5931744..19562ef 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -102,8 +102,10 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.storage.ICeStorageLockEventListener;
import android.os.storage.IStorageManager;
import android.os.storage.StorageManager;
+import android.os.storage.StorageManagerInternal;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.security.AndroidKeyStoreMaintenance;
@@ -338,6 +340,8 @@
private final CopyOnWriteArrayList<LockSettingsStateListener> mLockSettingsStateListeners =
new CopyOnWriteArrayList<>();
+ private final StorageManagerInternal mStorageManagerInternal;
+
// This class manages life cycle events for encrypted users on File Based Encryption (FBE)
// devices. The most basic of these is to show/hide notifications about missing features until
// the user unlocks the account and credential-encrypted storage is available.
@@ -577,6 +581,10 @@
return null;
}
+ public StorageManagerInternal getStorageManagerInternal() {
+ return LocalServices.getService(StorageManagerInternal.class);
+ }
+
public SyntheticPasswordManager getSyntheticPasswordManager(LockSettingsStorage storage) {
return new SyntheticPasswordManager(getContext(), storage, getUserManager(),
new PasswordSlotManager());
@@ -672,6 +680,7 @@
mNotificationManager = injector.getNotificationManager();
mUserManager = injector.getUserManager();
mStorageManager = injector.getStorageManager();
+ mStorageManagerInternal = injector.getStorageManagerInternal();
mStrongAuthTracker = injector.getStrongAuthTracker();
mStrongAuthTracker.register(mStrongAuth);
mGatekeeperPasswords = new LongSparseArray<>();
@@ -925,8 +934,34 @@
mStorage.prefetchUser(UserHandle.USER_SYSTEM);
mBiometricDeferredQueue.systemReady(mInjector.getFingerprintManager(),
mInjector.getFaceManager(), mInjector.getBiometricManager());
+ if (android.os.Flags.allowPrivateProfile()
+ && android.multiuser.Flags.enablePrivateSpaceFeatures()
+ && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()) {
+ mStorageManagerInternal.registerStorageLockEventListener(mCeStorageLockEventListener);
+ }
}
+ private final ICeStorageLockEventListener mCeStorageLockEventListener =
+ new ICeStorageLockEventListener() {
+ @Override
+ public void onStorageLocked(int userId) {
+ Slog.i(TAG, "Storage lock event received for " + userId);
+ if (android.os.Flags.allowPrivateProfile()
+ && android.multiuser.Flags.enablePrivateSpaceFeatures()
+ && android.multiuser.Flags.enableBiometricsToUnlockPrivateSpace()) {
+ mHandler.post(() -> {
+ UserProperties userProperties =
+ mUserManager.getUserProperties(UserHandle.of(userId));
+ if (userProperties != null
+ && userProperties.getAllowStoppingUserWithDelayedLocking()) {
+ int strongAuthRequired = LockPatternUtils.StrongAuthTracker
+ .getDefaultFlags(mContext);
+ requireStrongAuth(strongAuthRequired, userId);
+ }
+ });
+ }
+ }};
+
private void loadEscrowData() {
mRebootEscrowManager.loadRebootEscrowDataIfAvailable(mHandler);
}
diff --git a/services/core/java/com/android/server/locksettings/TEST_MAPPING b/services/core/java/com/android/server/locksettings/TEST_MAPPING
index ddf3d76..256d9ba 100644
--- a/services/core/java/com/android/server/locksettings/TEST_MAPPING
+++ b/services/core/java/com/android/server/locksettings/TEST_MAPPING
@@ -24,5 +24,11 @@
}
]
}
+ ],
+ "postsubmit": [
+ {
+ // TODO(b/332974906): Promote in presubmit-large.
+ "name": "CtsDevicePolicyManagerTestCases_LockSettings_NoFlakes"
+ }
]
}
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index eb4e6e4..62a9471 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -849,7 +849,7 @@
}
}
if (deadCallbackHolders != null) {
- mControllerCallbackHolders.removeAll(deadCallbackHolders);
+ removeControllerHoldersSafely(deadCallbackHolders);
}
}
@@ -876,7 +876,7 @@
}
}
if (deadCallbackHolders != null) {
- mControllerCallbackHolders.removeAll(deadCallbackHolders);
+ removeControllerHoldersSafely(deadCallbackHolders);
}
}
@@ -911,7 +911,7 @@
}
}
if (deadCallbackHolders != null) {
- mControllerCallbackHolders.removeAll(deadCallbackHolders);
+ removeControllerHoldersSafely(deadCallbackHolders);
}
}
@@ -938,7 +938,7 @@
}
}
if (deadCallbackHolders != null) {
- mControllerCallbackHolders.removeAll(deadCallbackHolders);
+ removeControllerHoldersSafely(deadCallbackHolders);
}
}
@@ -965,7 +965,7 @@
}
}
if (deadCallbackHolders != null) {
- mControllerCallbackHolders.removeAll(deadCallbackHolders);
+ removeControllerHoldersSafely(deadCallbackHolders);
}
}
@@ -992,7 +992,7 @@
}
}
if (deadCallbackHolders != null) {
- mControllerCallbackHolders.removeAll(deadCallbackHolders);
+ removeControllerHoldersSafely(deadCallbackHolders);
}
}
@@ -1017,7 +1017,7 @@
}
}
if (deadCallbackHolders != null) {
- mControllerCallbackHolders.removeAll(deadCallbackHolders);
+ removeControllerHoldersSafely(deadCallbackHolders);
}
}
@@ -1042,7 +1042,7 @@
}
}
// After notifying clear all listeners
- mControllerCallbackHolders.clear();
+ removeControllerHoldersSafely(null);
}
private PlaybackState getStateWithUpdatedPosition() {
@@ -1090,6 +1090,17 @@
return -1;
}
+ private void removeControllerHoldersSafely(
+ Collection<ISessionControllerCallbackHolder> holders) {
+ synchronized (mLock) {
+ if (holders == null) {
+ mControllerCallbackHolders.clear();
+ } else {
+ mControllerCallbackHolders.removeAll(holders);
+ }
+ }
+ }
+
private PlaybackInfo getVolumeAttributes() {
int volumeType;
AudioAttributes attributes;
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 7b12d86..68e0eaa 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -27,6 +27,10 @@
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
+import com.android.tools.r8.keepanno.annotations.KeepItemKind;
+import com.android.tools.r8.keepanno.annotations.KeepTarget;
+import com.android.tools.r8.keepanno.annotations.UsesReflection;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
@@ -44,7 +48,13 @@
private final Context mContext;
private final RankingHandler mRankingHandler;
-
+ @UsesReflection(
+ value = {
+ @KeepTarget(
+ kind = KeepItemKind.CLASS_AND_MEMBERS,
+ instanceOfClassConstantExclusive = NotificationSignalExtractor.class,
+ methodName = "<init>")
+ })
public RankingHelper(Context context, RankingHandler rankingHandler, RankingConfig config,
ZenModeHelper zenHelper, NotificationUsageStats usageStats, String[] extractorNames) {
mContext = context;
diff --git a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
index 4eb8b2b..c8fd7e4 100644
--- a/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
+++ b/services/core/java/com/android/server/os/BugreportManagerServiceImpl.java
@@ -184,6 +184,16 @@
throwInvalidBugreportFileForCallerException(
bugreportFile, callingInfo.second);
}
+
+ boolean keepBugreportOnRetrieval = false;
+ if (onboardingBugreportV2Enabled()) {
+ keepBugreportOnRetrieval = mBugreportFilesToPersist.contains(
+ bugreportFile);
+ }
+
+ if (!keepBugreportOnRetrieval) {
+ bugreportFilesForUid.remove(bugreportFile);
+ }
} else {
ArraySet<String> bugreportFilesForCaller = mBugreportFiles.get(callingInfo);
if (bugreportFilesForCaller != null
diff --git a/services/core/java/com/android/server/os/TEST_MAPPING b/services/core/java/com/android/server/os/TEST_MAPPING
index d937af1..50c8964 100644
--- a/services/core/java/com/android/server/os/TEST_MAPPING
+++ b/services/core/java/com/android/server/os/TEST_MAPPING
@@ -45,6 +45,10 @@
},
{
"file_patterns": ["Bugreport[^/]*\\.java"],
+ "name": "CtsRootBugreportTestCases"
+ },
+ {
+ "file_patterns": ["Bugreport[^/]*\\.java"],
"name": "ShellTests"
}
]
diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java
index e2f4d18..fda4dc6 100644
--- a/services/core/java/com/android/server/pm/PackageArchiver.java
+++ b/services/core/java/com/android/server/pm/PackageArchiver.java
@@ -187,7 +187,7 @@
}
public static boolean isArchivingEnabled() {
- return Flags.archiving() || SystemProperties.getBoolean("pm.archiving.enabled", false);
+ return Flags.archiving();
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 3eeeae7..80a5f3a 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -1085,11 +1085,17 @@
final boolean isUpdateOwnershipEnforcementEnabled =
mPm.isUpdateOwnershipEnforcementAvailable()
&& existingUpdateOwnerPackageName != null;
+ // For an installation that un-archives an app, if the installer doesn't have the
+ // INSTALL_PACKAGES permission, the user should have already been prompted to confirm the
+ // un-archive request. There's no need for another confirmation during the installation.
+ final boolean isInstallUnarchive =
+ (params.installFlags & PackageManager.INSTALL_UNARCHIVE) != 0;
// Device owners and affiliated profile owners are allowed to silently install packages, so
// the permission check is waived if the installer is the device owner.
final boolean noUserActionNecessary = isInstallerRoot || isInstallerSystem
- || isInstallerDeviceOwnerOrAffiliatedProfileOwner() || isEmergencyInstall;
+ || isInstallerDeviceOwnerOrAffiliatedProfileOwner() || isEmergencyInstall
+ || isInstallUnarchive;
if (noUserActionNecessary) {
return userActionNotTypicallyNeededResponse;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 7db83d7..b4919a4 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -174,7 +174,6 @@
import android.service.vr.IPersistentVrStateCallbacks;
import android.speech.RecognizerIntent;
import android.telecom.TelecomManager;
-import android.util.FeatureFlagUtils;
import android.util.Log;
import android.util.MathUtils;
import android.util.MutableBoolean;
@@ -4121,14 +4120,10 @@
private void handleSwitchKeyboardLayout(@NonNull KeyEvent event, int direction,
IBinder focusedToken) {
- if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI)) {
- IBinder targetWindowToken =
- mWindowManagerInternal.getTargetWindowTokenFromInputToken(focusedToken);
- InputMethodManagerInternal.get().onSwitchKeyboardLayoutShortcut(direction,
- event.getDisplayId(), targetWindowToken);
- } else {
- mWindowManagerFuncs.switchKeyboardLayout(event.getDeviceId(), direction);
- }
+ IBinder targetWindowToken =
+ mWindowManagerInternal.getTargetWindowTokenFromInputToken(focusedToken);
+ InputMethodManagerInternal.get().onSwitchKeyboardLayoutShortcut(direction,
+ event.getDisplayId(), targetWindowToken);
}
private boolean interceptFallback(IBinder focusedToken, KeyEvent fallbackEvent,
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 2623025..9ca4e27 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -251,12 +251,6 @@
*/
public int getCameraLensCoverState();
- /**
- * Switch the keyboard layout for the given device.
- * Direction should be +1 or -1 to go to the next or previous keyboard layout.
- */
- public void switchKeyboardLayout(int deviceId, int direction);
-
public void shutdown(boolean confirm);
public void reboot(boolean confirm);
public void rebootSafeMode(boolean confirm);
diff --git a/services/core/java/com/android/server/powerstats/PowerStatsService.java b/services/core/java/com/android/server/powerstats/PowerStatsService.java
index 9f0a975..8f99d28 100644
--- a/services/core/java/com/android/server/powerstats/PowerStatsService.java
+++ b/services/core/java/com/android/server/powerstats/PowerStatsService.java
@@ -568,23 +568,25 @@
int index = 0;
Channel[] channels = getEnergyMeterInfo();
- for (Channel channel : channels) {
- PowerMonitor monitor = new PowerMonitor(index++,
- PowerMonitor.POWER_MONITOR_TYPE_MEASUREMENT,
- getChannelName(channel));
- monitors.add(monitor);
- states.add(new PowerMonitorState(monitor, channel.id));
+ if (channels != null) {
+ for (Channel channel : channels) {
+ PowerMonitor monitor = new PowerMonitor(index++,
+ PowerMonitor.POWER_MONITOR_TYPE_MEASUREMENT,
+ getChannelName(channel));
+ monitors.add(monitor);
+ states.add(new PowerMonitorState(monitor, channel.id));
+ }
}
-
EnergyConsumer[] energyConsumers = getEnergyConsumerInfo();
- for (EnergyConsumer consumer : energyConsumers) {
- PowerMonitor monitor = new PowerMonitor(index++,
- PowerMonitor.POWER_MONITOR_TYPE_CONSUMER,
- getEnergyConsumerName(consumer, energyConsumers));
- monitors.add(monitor);
- states.add(new PowerMonitorState(monitor, consumer.id));
+ if (energyConsumers != null) {
+ for (EnergyConsumer consumer : energyConsumers) {
+ PowerMonitor monitor = new PowerMonitor(index++,
+ PowerMonitor.POWER_MONITOR_TYPE_CONSUMER,
+ getEnergyConsumerName(consumer, energyConsumers));
+ monitors.add(monitor);
+ states.add(new PowerMonitorState(monitor, consumer.id));
+ }
}
-
mPowerMonitors = monitors.toArray(new PowerMonitor[monitors.size()]);
mPowerMonitorStates = states.toArray(new PowerMonitorState[monitors.size()]);
}
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
index 3c0547e..c24240b 100644
--- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@@ -30,6 +30,7 @@
import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NO_PROVIDER;
import android.annotation.IntDef;
+import android.annotation.Nullable;
import android.apex.CompressedApexInfo;
import android.apex.CompressedApexInfoList;
import android.content.Context;
@@ -37,6 +38,7 @@
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.hardware.boot.IBootControl;
+import android.hardware.security.secretkeeper.ISecretkeeper;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.os.Binder;
@@ -52,6 +54,7 @@
import android.os.ShellCallback;
import android.os.SystemProperties;
import android.provider.DeviceConfig;
+import android.security.AndroidKeyStoreMaintenance;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.FastImmutableArraySet;
@@ -68,6 +71,7 @@
import com.android.server.Watchdog;
import com.android.server.pm.ApexManager;
import com.android.server.recoverysystem.hal.BootControlHIDL;
+import com.android.server.utils.Slogf;
import libcore.io.IoUtils;
@@ -122,6 +126,8 @@
static final String LSKF_CAPTURED_TIMESTAMP_PREF = "lskf_captured_timestamp";
static final String LSKF_CAPTURED_COUNT_PREF = "lskf_captured_count";
+ static final String RECOVERY_WIPE_DATA_COMMAND = "--wipe_data";
+
private final Injector mInjector;
private final Context mContext;
@@ -525,18 +531,57 @@
@Override // Binder call
public void rebootRecoveryWithCommand(String command) {
if (DEBUG) Slog.d(TAG, "rebootRecoveryWithCommand: [" + command + "]");
+
+ boolean isForcedWipe = command != null && command.contains(RECOVERY_WIPE_DATA_COMMAND);
synchronized (sRequestLock) {
if (!setupOrClearBcb(true, command)) {
Slog.e(TAG, "rebootRecoveryWithCommand failed to setup BCB");
return;
}
+ if (isForcedWipe) {
+ deleteSecrets();
+ // TODO: consider adding a dedicated forced-wipe-reboot method to PowerManager and
+ // calling here.
+ }
+
// Having set up the BCB, go ahead and reboot.
PowerManager pm = mInjector.getPowerManager();
pm.reboot(PowerManager.REBOOT_RECOVERY);
}
}
+ private static void deleteSecrets() {
+ Slogf.w(TAG, "deleteSecrets");
+ try {
+ AndroidKeyStoreMaintenance.deleteAllKeys();
+ } catch (android.security.KeyStoreException e) {
+ Log.wtf(TAG, "Failed to delete all keys from keystore.", e);
+ }
+
+ try {
+ ISecretkeeper secretKeeper = getSecretKeeper();
+ if (secretKeeper != null) {
+ Slogf.i(TAG, "ISecretkeeper.deleteAll();");
+ secretKeeper.deleteAll();
+ }
+ } catch (RemoteException e) {
+ Log.wtf(TAG, "Failed to delete all secrets from secretkeeper.", e);
+ }
+ }
+
+ private static @Nullable ISecretkeeper getSecretKeeper() {
+ ISecretkeeper result = null;
+ try {
+ result = ISecretkeeper.Stub.asInterface(
+ ServiceManager.waitForDeclaredService(ISecretkeeper.DESCRIPTOR + "/default"));
+ } catch (SecurityException e) {
+ Slog.w(TAG, "Does not have permissions to get AIDL secretkeeper service");
+ }
+
+ return result;
+ }
+
private void enforcePermissionForResumeOnReboot() {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.RECOVERY)
!= PackageManager.PERMISSION_GRANTED
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 8c4c0de..9a5961a 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -42,6 +42,7 @@
import static com.android.server.wallpaper.WallpaperUtils.getWallpaperDir;
import static com.android.server.wallpaper.WallpaperUtils.makeWallpaperIdLocked;
import static com.android.window.flags.Flags.multiCrop;
+import static com.android.window.flags.Flags.offloadColorExtraction;
import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -131,6 +132,9 @@
import com.android.server.wallpaper.WallpaperData.BindSource;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerInternal;
+import com.android.tools.r8.keepanno.annotations.KeepItemKind;
+import com.android.tools.r8.keepanno.annotations.KeepTarget;
+import com.android.tools.r8.keepanno.annotations.UsesReflection;
import org.xmlpull.v1.XmlPullParserException;
@@ -166,6 +170,13 @@
}
@Override
+ @UsesReflection(
+ value = {
+ @KeepTarget(
+ kind = KeepItemKind.CLASS_AND_MEMBERS,
+ instanceOfClassConstantExclusive = IWallpaperManagerService.class,
+ methodName = "<init>")
+ })
public void onStart() {
try {
final Class<? extends IWallpaperManagerService> klass =
@@ -380,7 +391,7 @@
}
// Outside of the lock since it will synchronize itself
- notifyWallpaperColorsChanged(wallpaper);
+ if (!offloadColorExtraction()) notifyWallpaperColorsChanged(wallpaper);
}
@Override
@@ -403,12 +414,16 @@
}
void notifyWallpaperColorsChanged(@NonNull WallpaperData wallpaper) {
+ notifyWallpaperColorsChanged(wallpaper, wallpaper.mWhich);
+ }
+
+ private void notifyWallpaperColorsChanged(@NonNull WallpaperData wallpaper, int which) {
if (DEBUG) {
Slog.i(TAG, "Notifying wallpaper colors changed");
}
if (wallpaper.connection != null) {
wallpaper.connection.forEachDisplayConnector(connector ->
- notifyWallpaperColorsChangedOnDisplay(wallpaper, connector.mDisplayId));
+ notifyWallpaperColorsChangedOnDisplay(wallpaper, connector.mDisplayId, which));
}
}
@@ -425,6 +440,11 @@
private void notifyWallpaperColorsChangedOnDisplay(@NonNull WallpaperData wallpaper,
int displayId) {
+ notifyWallpaperColorsChangedOnDisplay(wallpaper, displayId, wallpaper.mWhich);
+ }
+
+ private void notifyWallpaperColorsChangedOnDisplay(@NonNull WallpaperData wallpaper,
+ int displayId, int which) {
boolean needsExtraction;
synchronized (mLock) {
final RemoteCallbackList<IWallpaperManagerCallback> currentUserColorListeners =
@@ -449,8 +469,8 @@
notify = extractColors(wallpaper);
}
if (notify) {
- notifyColorListeners(getAdjustedWallpaperColorsOnDimming(wallpaper),
- wallpaper.mWhich, wallpaper.userId, displayId);
+ notifyColorListeners(getAdjustedWallpaperColorsOnDimming(wallpaper), which,
+ wallpaper.userId, displayId);
}
}
@@ -504,6 +524,7 @@
* @return true unless the wallpaper changed during the color computation
*/
private boolean extractColors(WallpaperData wallpaper) {
+ if (offloadColorExtraction()) return !mImageWallpaper.equals(wallpaper.wallpaperComponent);
String cropFile = null;
boolean defaultImageWallpaper = false;
int wallpaperId;
@@ -1148,10 +1169,16 @@
synchronized (mLock) {
// Do not broadcast changes on ImageWallpaper since it's handled
// internally by this class.
- if (mImageWallpaper.equals(mWallpaper.wallpaperComponent)) {
+ boolean isImageWallpaper = mImageWallpaper.equals(mWallpaper.wallpaperComponent);
+ if (isImageWallpaper && (!offloadColorExtraction() || primaryColors == null)) {
return;
}
mWallpaper.primaryColors = primaryColors;
+ // only save the colors for ImageWallpaper - for live wallpapers, the colors
+ // are always recomputed after a reboot.
+ if (offloadColorExtraction() && isImageWallpaper) {
+ saveSettingsLocked(mWallpaper.userId);
+ }
}
notifyWallpaperColorsChangedOnDisplay(mWallpaper, displayId);
}
@@ -1177,7 +1204,9 @@
try {
// This will trigger onComputeColors in the wallpaper engine.
// It's fine to be locked in here since the binder is oneway.
- connector.mEngine.requestWallpaperColors();
+ if (!offloadColorExtraction() || mWallpaper.primaryColors == null) {
+ connector.mEngine.requestWallpaperColors();
+ }
} catch (RemoteException e) {
Slog.w(TAG, "Failed to request wallpaper colors", e);
}
@@ -1811,6 +1840,7 @@
// Offload color extraction to another thread since switchUser will be called
// from the main thread.
FgThread.getHandler().post(() -> {
+ if (offloadColorExtraction()) return;
notifyWallpaperColorsChanged(systemWallpaper);
if (lockWallpaper != systemWallpaper) notifyWallpaperColorsChanged(lockWallpaper);
notifyWallpaperColorsChanged(mFallbackWallpaper);
@@ -2722,8 +2752,10 @@
});
// Need to extract colors again to re-calculate dark hints after
// applying dimming.
- wp.mIsColorExtractedFromDim = true;
- pendingColorExtraction.add(wp);
+ if (!offloadColorExtraction()) {
+ wp.mIsColorExtractedFromDim = true;
+ pendingColorExtraction.add(wp);
+ }
changed = true;
}
}
@@ -2732,7 +2764,7 @@
}
}
for (WallpaperData wp: pendingColorExtraction) {
- notifyWallpaperColorsChanged(wp);
+ if (!offloadColorExtraction()) notifyWallpaperColorsChanged(wp);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -2927,6 +2959,7 @@
}
wallpaper.allowBackup = allowBackup;
wallpaper.mWallpaperDimAmount = getWallpaperDimAmount();
+ if (offloadColorExtraction()) wallpaper.primaryColors = null;
}
return pfd;
} finally {
@@ -3069,6 +3102,10 @@
checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
boolean shouldNotifyColors = false;
+
+ // If the lockscreen wallpaper is set to the same as the home screen, notify that the
+ // lockscreen wallpaper colors changed, even if we don't bind a new wallpaper engine.
+ boolean shouldNotifyLockscreenColors = false;
boolean bindSuccess;
final WallpaperData newWallpaper;
@@ -3114,7 +3151,7 @@
bindSuccess = bindWallpaperComponentLocked(name, /* force */
forceRebind, /* fromUser */ true, newWallpaper, reply);
if (bindSuccess) {
- if (!same) {
+ if (!same || (offloadColorExtraction() && forceRebind)) {
newWallpaper.primaryColors = null;
} else {
if (newWallpaper.connection != null) {
@@ -3138,6 +3175,11 @@
newWallpaper.wallpaperId = makeWallpaperIdLocked();
notifyCallbacksLocked(newWallpaper);
shouldNotifyColors = true;
+ if (offloadColorExtraction()) {
+ shouldNotifyColors = false;
+ shouldNotifyLockscreenColors = !force && same && !systemIsBoth
+ && which == (FLAG_SYSTEM | FLAG_LOCK);
+ }
if (which == (FLAG_SYSTEM | FLAG_LOCK)) {
if (DEBUG) {
@@ -3166,6 +3208,10 @@
if (shouldNotifyColors) {
notifyWallpaperColorsChanged(newWallpaper);
}
+ if (shouldNotifyLockscreenColors) {
+ notifyWallpaperColorsChanged(newWallpaper, FLAG_LOCK);
+ }
+
return bindSuccess;
}
diff --git a/services/core/java/com/android/server/webkit/flags.aconfig b/services/core/java/com/android/server/webkit/flags.aconfig
index 84dc1d7..2afbcd6 100644
--- a/services/core/java/com/android/server/webkit/flags.aconfig
+++ b/services/core/java/com/android/server/webkit/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.webkit"
-container: "system"
flag {
name: "update_service_v2"
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 4036d55..207d42b6 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -8645,7 +8645,7 @@
// Override starts here.
final Rect stableInsets = mDisplayContent.getDisplayPolicy().getDecorInsetsInfo(
- rotation, fullBounds.width(), fullBounds.height()).mLegacyConfigInsets;
+ rotation, fullBounds.width(), fullBounds.height()).mOverrideConfigInsets;
// This should be the only place override the configuration for ActivityRecord. Override
// the value if not calculated yet.
Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
@@ -8681,7 +8681,7 @@
mDisplayContent.getDisplay().getDisplayInfo(info);
mDisplayContent.computeSizeRanges(info, rotated, info.logicalWidth,
info.logicalHeight, mDisplayContent.getDisplayMetrics().density,
- inOutConfig, true /* legacyConfig */);
+ inOutConfig, true /* overrideConfig */);
}
// It's possible that screen size will be considered in different orientation with or
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
index efeb85f..d49a507 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
@@ -40,6 +40,10 @@
import android.os.Bundle;
import android.text.TextUtils;
+import com.android.tools.r8.keepanno.annotations.KeepItemKind;
+import com.android.tools.r8.keepanno.annotations.KeepTarget;
+import com.android.tools.r8.keepanno.annotations.UsesReflection;
+
import java.util.ArrayList;
import java.util.List;
@@ -184,6 +188,13 @@
/**
* Instantiates the device-specific {@link Provider}.
*/
+ @UsesReflection(
+ value = {
+ @KeepTarget(
+ kind = KeepItemKind.CLASS_AND_MEMBERS,
+ instanceOfClassConstantExclusive = Provider.class,
+ methodName = "<init>")
+ })
static Provider fromResources(Resources res) {
String name = res.getString(
com.android.internal.R.string.config_deviceSpecificDisplayAreaPolicyProvider);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index cde3e68..00dc3ec 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2277,7 +2277,7 @@
}
computeSizeRanges(mDisplayInfo, rotated, dw, dh, mDisplayMetrics.density, outConfig,
- false /* legacyConfig */);
+ false /* overrideConfig */);
setDisplayInfoOverride();
@@ -2414,7 +2414,7 @@
final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(rotation);
displayInfo.displayCutout = displayCutout.isEmpty() ? null : displayCutout;
computeSizeRanges(displayInfo, rotated, dw, dh, mDisplayMetrics.density, outConfig,
- false /* legacyConfig */);
+ false /* overrideConfig */);
return displayInfo;
}
@@ -2588,11 +2588,10 @@
* @param dh Display Height in current rotation.
* @param density Display density.
* @param outConfig The output configuration to
- * @param legacyConfig Whether we need to report the legacy result, which is excluding system
- * decorations.
+ * @param overrideConfig Whether we need to report the override config result
*/
void computeSizeRanges(DisplayInfo displayInfo, boolean rotated,
- int dw, int dh, float density, Configuration outConfig, boolean legacyConfig) {
+ int dw, int dh, float density, Configuration outConfig, boolean overrideConfig) {
// We need to determine the smallest width that will occur under normal
// operation. To this, start with the base screen size and compute the
@@ -2610,10 +2609,12 @@
displayInfo.smallestNominalAppHeight = 1<<30;
displayInfo.largestNominalAppWidth = 0;
displayInfo.largestNominalAppHeight = 0;
- adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh, legacyConfig);
- adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw, legacyConfig);
- adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh, legacyConfig);
- adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw, legacyConfig);
+ adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh, overrideConfig);
+ adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw, overrideConfig);
+ adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh,
+ overrideConfig);
+ adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw,
+ overrideConfig);
if (outConfig == null) {
return;
@@ -2623,17 +2624,17 @@
}
private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh,
- boolean legacyConfig) {
+ boolean overrideConfig) {
final DisplayPolicy.DecorInsets.Info info = mDisplayPolicy.getDecorInsetsInfo(
rotation, dw, dh);
final int w;
final int h;
- if (!legacyConfig) {
+ if (!overrideConfig) {
w = info.mConfigFrame.width();
h = info.mConfigFrame.height();
} else {
- w = info.mLegacyConfigFrame.width();
- h = info.mLegacyConfigFrame.height();
+ w = info.mOverrideConfigFrame.width();
+ h = info.mOverrideConfigFrame.height();
}
if (w < displayInfo.smallestNominalAppWidth) {
displayInfo.smallestNominalAppWidth = w;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index a5037ea..5e0d4f9 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -1935,9 +1935,9 @@
final Rect mConfigInsets = new Rect();
/**
- * Legacy value of mConfigInsets for app compatibility purpose.
+ * Override value of mConfigInsets for app compatibility purpose.
*/
- final Rect mLegacyConfigInsets = new Rect();
+ final Rect mOverrideConfigInsets = new Rect();
/** The display frame available after excluding {@link #mNonDecorInsets}. */
final Rect mNonDecorFrame = new Rect();
@@ -1950,9 +1950,9 @@
final Rect mConfigFrame = new Rect();
/**
- * Legacy value of mConfigFrame for app compatibility purpose.
+ * Override value of mConfigFrame for app compatibility purpose.
*/
- final Rect mLegacyConfigFrame = new Rect();
+ final Rect mOverrideConfigFrame = new Rect();
private boolean mNeedUpdate = true;
@@ -1968,22 +1968,22 @@
? decor
: insetsState.calculateInsets(displayFrame, dc.mWmService.mConfigTypes,
true /* ignoreVisibility */);
- final Insets legacyConfigInsets = dc.mWmService.mConfigTypes
- == dc.mWmService.mLegacyConfigTypes
+ final Insets overrideConfigInsets = dc.mWmService.mConfigTypes
+ == dc.mWmService.mOverrideConfigTypes
? configInsets
: insetsState.calculateInsets(displayFrame,
- dc.mWmService.mLegacyConfigTypes, true /* ignoreVisibility */);
+ dc.mWmService.mOverrideConfigTypes, true /* ignoreVisibility */);
mNonDecorInsets.set(decor.left, decor.top, decor.right, decor.bottom);
mConfigInsets.set(configInsets.left, configInsets.top, configInsets.right,
configInsets.bottom);
- mLegacyConfigInsets.set(legacyConfigInsets.left, legacyConfigInsets.top,
- legacyConfigInsets.right, legacyConfigInsets.bottom);
+ mOverrideConfigInsets.set(overrideConfigInsets.left, overrideConfigInsets.top,
+ overrideConfigInsets.right, overrideConfigInsets.bottom);
mNonDecorFrame.set(displayFrame);
mNonDecorFrame.inset(mNonDecorInsets);
mConfigFrame.set(displayFrame);
mConfigFrame.inset(mConfigInsets);
- mLegacyConfigFrame.set(displayFrame);
- mLegacyConfigFrame.inset(mLegacyConfigInsets);
+ mOverrideConfigFrame.set(displayFrame);
+ mOverrideConfigFrame.inset(mOverrideConfigInsets);
mNeedUpdate = false;
return insetsState;
}
@@ -1991,10 +1991,10 @@
void set(Info other) {
mNonDecorInsets.set(other.mNonDecorInsets);
mConfigInsets.set(other.mConfigInsets);
- mLegacyConfigInsets.set(other.mLegacyConfigInsets);
+ mOverrideConfigInsets.set(other.mOverrideConfigInsets);
mNonDecorFrame.set(other.mNonDecorFrame);
mConfigFrame.set(other.mConfigFrame);
- mLegacyConfigFrame.set(other.mLegacyConfigFrame);
+ mOverrideConfigFrame.set(other.mOverrideConfigFrame);
mNeedUpdate = false;
}
@@ -2107,7 +2107,7 @@
final InsetsState newInsetsState = newInfo.update(mDisplayContent, rotation, dw, dh);
final DecorInsets.Info currentInfo = getDecorInsetsInfo(rotation, dw, dh);
if (newInfo.mConfigFrame.equals(currentInfo.mConfigFrame)
- && newInfo.mLegacyConfigFrame.equals(currentInfo.mLegacyConfigFrame)) {
+ && newInfo.mOverrideConfigFrame.equals(currentInfo.mOverrideConfigFrame)) {
// Even if the config frame is not changed in current rotation, it may change the
// insets in other rotations if the frame of insets source is changed.
final InsetsState currentInsetsState = mDisplayContent.mDisplayFrames.mInsetsState;
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index b8bb258..0ad601d 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -61,6 +61,7 @@
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.policy.WindowManagerPolicy;
+import com.android.window.flags.Flags;
import java.io.PrintWriter;
@@ -225,13 +226,16 @@
if (keyguardShowing) {
state.mDismissalRequested = false;
}
- if (goingAwayRemoved) {
- // Keyguard dismiss is canceled. Send a transition to undo the changes and clean up
- // before holding the sleep token again.
+ if (goingAwayRemoved || (keyguardShowing && Flags.keyguardAppearTransition())) {
+ // Keyguard decided to show or stopped going away. Send a transition to animate back
+ // to the locked state before holding the sleep token again
final DisplayContent dc = mRootWindowContainer.getDefaultDisplay();
dc.requestTransitionAndLegacyPrepare(
TRANSIT_TO_FRONT, TRANSIT_FLAG_KEYGUARD_APPEARING);
- mWindowManager.executeAppTransition();
+ if (Flags.keyguardAppearTransition()) {
+ dc.mWallpaperController.adjustWallpaperWindows();
+ }
+ dc.executeAppTransition();
}
}
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index bd1503f..129af90 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -2427,7 +2427,7 @@
if (!useLegacyInsetsForStableBounds) {
intersectWithInsetsIfFits(outStableBounds, mTmpBounds, info.mConfigInsets);
} else {
- intersectWithInsetsIfFits(outStableBounds, mTmpBounds, info.mLegacyConfigInsets);
+ intersectWithInsetsIfFits(outStableBounds, mTmpBounds, info.mOverrideConfigInsets);
}
}
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index c8cb934..59bda54 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -857,10 +857,6 @@
}
public void updateWallpaperTokens(boolean keyguardLocked) {
- if (DEBUG_WALLPAPER) {
- Slog.v(TAG, "Wallpaper vis: target " + mWallpaperTarget + " prev="
- + mPrevWallpaperTarget);
- }
updateWallpaperTokens(mWallpaperTarget != null || mPrevWallpaperTarget != null,
keyguardLocked);
}
@@ -869,6 +865,8 @@
* Change the visibility of the top wallpaper to {@param visibility} and hide all the others.
*/
private void updateWallpaperTokens(boolean visibility, boolean keyguardLocked) {
+ ProtoLog.v(WM_DEBUG_WALLPAPER, "updateWallpaperTokens requestedVisibility=%b on"
+ + " keyguardLocked=%b", visibility, keyguardLocked);
WindowState topWallpaper = mFindResults.getTopWallpaper(keyguardLocked);
WallpaperWindowToken topWallpaperToken =
topWallpaper == null ? null : topWallpaper.mToken.asWallpaperToken();
diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index 55eeaf2..5c24eee 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -274,6 +274,12 @@
}
@Override
+ boolean isSyncFinished(BLASTSyncEngine.SyncGroup group) {
+ // TODO(b/233286785): Support sync state for wallpaper. See WindowState#prepareSync.
+ return !mVisibleRequested || !hasVisibleNotDrawnWallpaper();
+ }
+
+ @Override
public String toString() {
if (stringName == null) {
StringBuilder sb = new StringBuilder();
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index aeefc34..74616ac 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -567,7 +567,7 @@
/** Device default insets types shall be excluded from config app sizes. */
final int mConfigTypes;
- final int mLegacyConfigTypes;
+ final int mOverrideConfigTypes;
final boolean mLimitedAlphaCompositing;
final int mMaxUiWidth;
@@ -1238,20 +1238,18 @@
if (mFlags.mInsetsDecoupledConfiguration) {
mDecorTypes = 0;
mConfigTypes = 0;
- } else if (isScreenSizeDecoupledFromStatusBarAndCutout) {
- mDecorTypes = WindowInsets.Type.navigationBars();
- mConfigTypes = WindowInsets.Type.navigationBars();
} else {
mDecorTypes = WindowInsets.Type.displayCutout() | WindowInsets.Type.navigationBars();
mConfigTypes = WindowInsets.Type.displayCutout() | WindowInsets.Type.statusBars()
| WindowInsets.Type.navigationBars();
}
- if (isScreenSizeDecoupledFromStatusBarAndCutout) {
- // Do not fallback to legacy value for enabled devices.
- mLegacyConfigTypes = WindowInsets.Type.navigationBars();
+ if (isScreenSizeDecoupledFromStatusBarAndCutout && !mFlags.mInsetsDecoupledConfiguration) {
+ // If the global new behavior is not there, but the partial decouple flag is on.
+ mOverrideConfigTypes = 0;
} else {
- mLegacyConfigTypes = WindowInsets.Type.displayCutout() | WindowInsets.Type.statusBars()
- | WindowInsets.Type.navigationBars();
+ mOverrideConfigTypes =
+ WindowInsets.Type.displayCutout() | WindowInsets.Type.statusBars()
+ | WindowInsets.Type.navigationBars();
}
mLetterboxConfiguration = new LetterboxConfiguration(
@@ -3685,12 +3683,6 @@
// Called by window manager policy. Not exposed externally.
@Override
- public void switchKeyboardLayout(int deviceId, int direction) {
- mInputManager.switchKeyboardLayout(deviceId, direction);
- }
-
- // Called by window manager policy. Not exposed externally.
- @Override
public void shutdown(boolean confirm) {
// Pass in the UI context, since ShutdownThread requires it (to show UI).
ShutdownThread.shutdown(ActivityThread.currentActivityThread().getSystemUiContext(),
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index aac567c..9d8246d 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -110,8 +110,8 @@
private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
- private static final int MAX_RAPID_ACTIVITY_LAUNCH_COUNT = 500;
- private static final long RAPID_ACTIVITY_LAUNCH_MS = 300;
+ private static final int MAX_RAPID_ACTIVITY_LAUNCH_COUNT = 50;
+ private static final long RAPID_ACTIVITY_LAUNCH_MS = 500;
private static final long RESET_RAPID_ACTIVITY_LAUNCH_MS = 5 * RAPID_ACTIVITY_LAUNCH_MS;
public static final int STOPPED_STATE_NOT_STOPPED = 0;
@@ -639,9 +639,15 @@
}
if (mRapidActivityLaunchCount > MAX_RAPID_ACTIVITY_LAUNCH_COUNT) {
- Slog.w(TAG, "Killing " + mPid + " because of rapid activity launch");
- r.getRootTask().moveTaskToBack(r.getTask());
- mAtm.mH.post(() -> mAtm.mAmInternal.killProcess(mName, mUid, "rapidActivityLaunch"));
+ mRapidActivityLaunchCount = 0;
+ final Task task = r.getTask();
+ Slog.w(TAG, "Removing task " + task.mTaskId + " because of rapid activity launch");
+ mAtm.mH.post(() -> {
+ synchronized (mAtm.mGlobalLock) {
+ task.removeImmediately("rapid-activity-launch");
+ }
+ mAtm.mAmInternal.killProcess(mName, mUid, "rapidActivityLaunch");
+ });
}
}
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index 8598023..f1962cb 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -226,11 +226,8 @@
<xs:element name="transitionPoint" type="nonNegativeDecimal" minOccurs="1"
maxOccurs="1">
</xs:element>
- <xs:element name="nits" type="xs:float" maxOccurs="unbounded">
- </xs:element>
- <xs:element name="backlight" type="xs:float" maxOccurs="unbounded">
- </xs:element>
- <xs:element name="brightness" type="xs:float" maxOccurs="unbounded">
+ <!-- Mapping of nits -> backlight -> brightness -->
+ <xs:element name="brightnessMapping" type="comprehensiveBrightnessMap" maxOccurs="1">
</xs:element>
<!-- Mapping of current lux to minimum allowed nits values. -->
<xs:element name="luxToMinimumNitsMap" type="nitsMap" maxOccurs="1">
@@ -449,6 +446,35 @@
</xs:sequence>
</xs:complexType>
+ <xs:complexType name="comprehensiveBrightnessMap">
+ <xs:sequence>
+ <xs:element name="brightnessPoint" type="brightnessPoint" maxOccurs="unbounded" minOccurs="2">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ </xs:sequence>
+ <!-- valid value of interpolation if specified: linear -->
+ <xs:attribute name="interpolation" type="xs:string" use="optional"/>
+ </xs:complexType>
+
+ <xs:complexType name="brightnessPoint">
+ <xs:sequence>
+ <xs:element type="nonNegativeDecimal" name="nits">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ <xs:element type="nonNegativeDecimal" name="backlight">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ <xs:element type="nonNegativeDecimal" name="brightness">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+
<xs:complexType name="sdrHdrRatioMap">
<xs:sequence>
<xs:element name="point" type="sdrHdrRatioPoint" maxOccurs="unbounded" minOccurs="2">
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index 4ce4cc3..170434c 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -53,6 +53,16 @@
method public final void setType(@NonNull com.android.server.display.config.PredefinedBrightnessLimitNames);
}
+ public class BrightnessPoint {
+ ctor public BrightnessPoint();
+ method @NonNull public final java.math.BigDecimal getBacklight();
+ method @NonNull public final java.math.BigDecimal getBrightness();
+ method @NonNull public final java.math.BigDecimal getNits();
+ method public final void setBacklight(@NonNull java.math.BigDecimal);
+ method public final void setBrightness(@NonNull java.math.BigDecimal);
+ method public final void setNits(@NonNull java.math.BigDecimal);
+ }
+
public class BrightnessThresholds {
ctor public BrightnessThresholds();
method public final com.android.server.display.config.ThresholdPoints getBrightnessThresholdPoints();
@@ -76,6 +86,13 @@
method public final void setThermalStatus(@NonNull com.android.server.display.config.ThermalStatus);
}
+ public class ComprehensiveBrightnessMap {
+ ctor public ComprehensiveBrightnessMap();
+ method @NonNull public final java.util.List<com.android.server.display.config.BrightnessPoint> getBrightnessPoint();
+ method public String getInterpolation();
+ method public void setInterpolation(String);
+ }
+
public class Density {
ctor public Density();
method @NonNull public final java.math.BigInteger getDensity();
@@ -183,12 +200,11 @@
public class EvenDimmerMode {
ctor public EvenDimmerMode();
- method public java.util.List<java.lang.Float> getBacklight();
- method public java.util.List<java.lang.Float> getBrightness();
+ method public com.android.server.display.config.ComprehensiveBrightnessMap getBrightnessMapping();
method public boolean getEnabled();
method public com.android.server.display.config.NitsMap getLuxToMinimumNitsMap();
- method public java.util.List<java.lang.Float> getNits();
method public java.math.BigDecimal getTransitionPoint();
+ method public void setBrightnessMapping(com.android.server.display.config.ComprehensiveBrightnessMap);
method public void setEnabled(boolean);
method public void setLuxToMinimumNitsMap(com.android.server.display.config.NitsMap);
method public void setTransitionPoint(java.math.BigDecimal);
diff --git a/services/devicepolicy/TEST_MAPPING b/services/devicepolicy/TEST_MAPPING
index 0d5534b..b8cb4a9 100644
--- a/services/devicepolicy/TEST_MAPPING
+++ b/services/devicepolicy/TEST_MAPPING
@@ -26,5 +26,12 @@
}
]
}
+ ],
+ "postsubmit": [
+ {
+ // TODO(b/332974906): Promote in presubmit presubmit-devicepolicy.
+ "name": "CtsDevicePolicyManagerTestCases_NoFlakes_NoLarge",
+ "name": "CtsDevicePolicyManagerTestCases_ParentProfileApiDisabled"
+ }
]
}
diff --git a/services/java/com/android/server/flags.aconfig b/services/java/com/android/server/flags.aconfig
index 854bc0f..4b578af 100644
--- a/services/java/com/android/server/flags.aconfig
+++ b/services/java/com/android/server/flags.aconfig
@@ -1,5 +1,4 @@
package: "android.server"
-container: "system"
flag {
namespace: "system_performance"
diff --git a/services/proguard.flags b/services/proguard.flags
index a01e7dc..f84eff7 100644
--- a/services/proguard.flags
+++ b/services/proguard.flags
@@ -33,12 +33,6 @@
-keep,allowoptimization,allowaccessmodification class * extends com.android.server.SystemService {
public <methods>;
}
--keep,allowoptimization,allowaccessmodification class * extends com.android.server.devicepolicy.BaseIDevicePolicyManager {
- public <init>(...);
-}
--keep,allowoptimization,allowaccessmodification class com.android.server.wallpaper.WallpaperManagerService {
- public <init>(...);
-}
# Accessed from com.android.compos APEX
-keep,allowoptimization,allowaccessmodification class com.android.internal.art.ArtStatsLog {
@@ -68,13 +62,6 @@
-keep public class android.hidl.manager.** { *; }
-keep public class com.android.server.wm.WindowManagerInternal { *; }
-# Notification extractors
-# TODO(b/210510433): Revisit and consider generating from frameworks/base/core/res/res/values/config.xml.
--keep,allowoptimization,allowaccessmodification public class com.android.server.notification.** implements com.android.server.notification.NotificationSignalExtractor
-
-# OEM provided DisplayAreaPolicy.Provider defined in frameworks/base/core/res/res/values/config.xml.
--keep,allowoptimization,allowaccessmodification class com.android.server.wm.** implements com.android.server.wm.DisplayAreaPolicy$Provider
-
# JNI keep rules
# The global keep rule for native methods allows stripping of such methods if they're unreferenced
# in Java. However, because system_server explicitly registers these methods from native code,
@@ -118,9 +105,6 @@
# Miscellaneous reflection keep rules
# TODO(b/210510433): Revisit and fix with @Keep.
--keep,allowoptimization,allowaccessmodification class com.android.server.usage.AppStandbyController {
- public <init>(...);
-}
-keep,allowoptimization,allowaccessmodification class android.hardware.usb.gadget.** { *; }
# Needed when optimizations enabled
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayBrightnessStateTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayBrightnessStateTest.java
index ad4d91f..6d89e80 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayBrightnessStateTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayBrightnessStateTest.java
@@ -27,6 +27,8 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Objects;
+
@SmallTest
@RunWith(AndroidJUnit4.class)
public class DisplayBrightnessStateTest {
@@ -101,7 +103,9 @@
.append("\n customAnimationRate:")
.append(displayBrightnessState.getCustomAnimationRate())
.append("\n shouldUpdateScreenBrightnessSetting:")
- .append(displayBrightnessState.shouldUpdateScreenBrightnessSetting());
+ .append(displayBrightnessState.shouldUpdateScreenBrightnessSetting())
+ .append("\n mBrightnessEvent:")
+ .append(Objects.toString(displayBrightnessState.getBrightnessEvent(), "null"));
return sb.toString();
}
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
index b80d44f..5897d76 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -924,7 +924,7 @@
getValidProxSensor(), /* includeIdleMode= */ false, /* enableEvenDimmer */ true));
assertTrue(mDisplayDeviceConfig.isEvenDimmerAvailable());
- assertEquals(0.0001f, mDisplayDeviceConfig.getBacklightFromBrightness(0.1f), ZERO_DELTA);
+ assertEquals(0.01f, mDisplayDeviceConfig.getBacklightFromBrightness(0.002f), ZERO_DELTA);
assertEquals(0.2f, mDisplayDeviceConfig.getNitsFromBacklight(0.0f), ZERO_DELTA);
}
@@ -1649,18 +1649,28 @@
private String evenDimmerConfig(boolean enabled) {
return (enabled ? "<evenDimmer enabled=\"true\">" : "<evenDimmer enabled=\"false\">")
+ " <transitionPoint>0.1</transitionPoint>\n"
- + " <nits>0.2</nits>\n"
- + " <nits>2.0</nits>\n"
- + " <nits>500.0</nits>\n"
- + " <nits>1000.0</nits>\n"
- + " <backlight>0</backlight>\n"
- + " <backlight>0.0001</backlight>\n"
- + " <backlight>0.5</backlight>\n"
- + " <backlight>1.0</backlight>\n"
- + " <brightness>0</brightness>\n"
- + " <brightness>0.1</brightness>\n"
- + " <brightness>0.5</brightness>\n"
- + " <brightness>1.0</brightness>\n"
+ + " <brightnessMapping>\n"
+ + " <brightnessPoint>\n"
+ + " <nits>0.2</nits>\n"
+ + " <backlight>0</backlight>\n"
+ + " <brightness>0</brightness>\n"
+ + " </brightnessPoint>\n"
+ + " <brightnessPoint>\n"
+ + " <nits>2.0</nits>\n"
+ + " <backlight>0.01</backlight>\n"
+ + " <brightness>0.002</brightness>\n"
+ + " </brightnessPoint>\n"
+ + " <brightnessPoint>\n"
+ + " <nits>500.0</nits>\n"
+ + " <backlight>0.5</backlight>\n"
+ + " <brightness>0.5</brightness>\n"
+ + " </brightnessPoint>\n"
+ + " <brightnessPoint>\n"
+ + " <nits>1000</nits>\n"
+ + " <backlight>1.0</backlight>\n"
+ + " <brightness>1.0</brightness>\n"
+ + " </brightnessPoint>\n"
+ + " </brightnessMapping>\n"
+ " <luxToMinimumNitsMap>\n"
+ " <point>\n"
+ " <value>10</value> <nits>0.3</nits>\n"
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
index 6ed8238..1ae4099 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
@@ -19,7 +19,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -111,8 +111,7 @@
DisplayBrightnessStrategy displayBrightnessStrategy = mock(DisplayBrightnessStrategy.class);
int targetDisplayState = Display.STATE_DOZE;
when(mDisplayBrightnessStrategySelector.selectStrategy(
- eq(new StrategySelectionRequest(displayPowerRequest, targetDisplayState))))
- .thenReturn(displayBrightnessStrategy);
+ any(StrategySelectionRequest.class))).thenReturn(displayBrightnessStrategy);
mDisplayBrightnessController.updateBrightness(displayPowerRequest, targetDisplayState);
verify(displayBrightnessStrategy).updateBrightness(displayPowerRequest);
assertEquals(mDisplayBrightnessController.getCurrentDisplayBrightnessStrategy(),
@@ -164,6 +163,7 @@
// No brightness is set if the pending brightness is invalid
mDisplayBrightnessController.setPendingScreenBrightness(Float.NaN);
assertFalse(mDisplayBrightnessController.updateUserSetScreenBrightness());
+ assertFalse(mDisplayBrightnessController.getIsUserSetScreenBrightnessUpdated());
// user set brightness is not set if the current and the pending brightness are same.
float currentBrightness = 0.4f;
@@ -175,6 +175,7 @@
mDisplayBrightnessController.setPendingScreenBrightness(currentBrightness);
mDisplayBrightnessController.setTemporaryBrightness(currentBrightness);
assertFalse(mDisplayBrightnessController.updateUserSetScreenBrightness());
+ assertFalse(mDisplayBrightnessController.getIsUserSetScreenBrightnessUpdated());
verify(temporaryBrightnessStrategy).setTemporaryScreenBrightness(
PowerManager.BRIGHTNESS_INVALID_FLOAT);
assertEquals(mDisplayBrightnessController.getPendingScreenBrightness(),
@@ -188,6 +189,7 @@
mDisplayBrightnessController.setPendingScreenBrightness(pendingScreenBrightness);
mDisplayBrightnessController.setTemporaryBrightness(temporaryScreenBrightness);
assertTrue(mDisplayBrightnessController.updateUserSetScreenBrightness());
+ assertTrue(mDisplayBrightnessController.getIsUserSetScreenBrightnessUpdated());
assertEquals(mDisplayBrightnessController.getCurrentBrightness(),
pendingScreenBrightness, /* delta= */ 0.0f);
assertEquals(mDisplayBrightnessController.getLastUserSetScreenBrightness(),
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java
index 4c9dd58..b8858cc 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessStrategySelectorTest.java
@@ -22,6 +22,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.content.ContentResolver;
@@ -40,6 +41,7 @@
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.internal.util.test.FakeSettingsProviderRule;
import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy;
+import com.android.server.display.brightness.strategy.AutomaticBrightnessStrategy2;
import com.android.server.display.brightness.strategy.BoostBrightnessStrategy;
import com.android.server.display.brightness.strategy.DozeBrightnessStrategy;
import com.android.server.display.brightness.strategy.FollowerBrightnessStrategy;
@@ -80,6 +82,8 @@
@Mock
private AutomaticBrightnessStrategy mAutomaticBrightnessStrategy;
@Mock
+ private AutomaticBrightnessStrategy2 mAutomaticBrightnessStrategy2;
+ @Mock
private OffloadBrightnessStrategy mOffloadBrightnessStrategy;
@Mock
private Resources mResources;
@@ -126,12 +130,18 @@
}
@Override
- AutomaticBrightnessStrategy getAutomaticBrightnessStrategy(Context context,
+ AutomaticBrightnessStrategy getAutomaticBrightnessStrategy1(Context context,
int displayId) {
return mAutomaticBrightnessStrategy;
}
@Override
+ AutomaticBrightnessStrategy2 getAutomaticBrightnessStrategy2(Context context,
+ int displayId) {
+ return mAutomaticBrightnessStrategy2;
+ }
+
+ @Override
OffloadBrightnessStrategy getOffloadBrightnessStrategy() {
return mOffloadBrightnessStrategy;
}
@@ -162,7 +172,8 @@
when(mResources.getBoolean(R.bool.config_allowAutoBrightnessWhileDozing)).thenReturn(
DISALLOW_AUTO_BRIGHTNESS_WHILE_DOZING);
assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
- new StrategySelectionRequest(displayPowerRequest, Display.STATE_DOZE)),
+ new StrategySelectionRequest(displayPowerRequest, Display.STATE_DOZE,
+ 0.1f, false)),
mDozeBrightnessModeStrategy);
}
@@ -175,7 +186,8 @@
when(mResources.getBoolean(R.bool.config_allowAutoBrightnessWhileDozing)).thenReturn(
DISALLOW_AUTO_BRIGHTNESS_WHILE_DOZING);
assertNotEquals(mDisplayBrightnessStrategySelector.selectStrategy(
- new StrategySelectionRequest(displayPowerRequest, Display.STATE_DOZE)),
+ new StrategySelectionRequest(displayPowerRequest, Display.STATE_DOZE,
+ 0.1f, false)),
mDozeBrightnessModeStrategy);
}
@@ -184,7 +196,8 @@
DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock(
DisplayManagerInternal.DisplayPowerRequest.class);
assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
- new StrategySelectionRequest(displayPowerRequest, Display.STATE_OFF)),
+ new StrategySelectionRequest(displayPowerRequest, Display.STATE_OFF,
+ 0.1f, false)),
mScreenOffBrightnessModeStrategy);
}
@@ -195,7 +208,8 @@
displayPowerRequest.screenBrightnessOverride = 0.4f;
when(mFollowerBrightnessStrategy.getBrightnessToFollow()).thenReturn(Float.NaN);
assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
- new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON)),
+ new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
+ 0.1f, false)),
mOverrideBrightnessStrategy);
}
@@ -207,7 +221,8 @@
when(mFollowerBrightnessStrategy.getBrightnessToFollow()).thenReturn(Float.NaN);
when(mTemporaryBrightnessStrategy.getTemporaryScreenBrightness()).thenReturn(0.3f);
assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
- new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON)),
+ new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
+ 0.1f, false)),
mTemporaryBrightnessStrategy);
}
@@ -220,7 +235,8 @@
displayPowerRequest.screenBrightnessOverride = Float.NaN;
when(mTemporaryBrightnessStrategy.getTemporaryScreenBrightness()).thenReturn(Float.NaN);
assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
- new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON)),
+ new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
+ 0.1f, false)),
mBoostBrightnessStrategy);
}
@@ -233,7 +249,8 @@
when(mTemporaryBrightnessStrategy.getTemporaryScreenBrightness()).thenReturn(Float.NaN);
when(mOffloadBrightnessStrategy.getOffloadScreenBrightness()).thenReturn(Float.NaN);
assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
- new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON)),
+ new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
+ 0.1f, false)),
mInvalidBrightnessStrategy);
}
@@ -243,7 +260,8 @@
DisplayManagerInternal.DisplayPowerRequest.class);
when(mFollowerBrightnessStrategy.getBrightnessToFollow()).thenReturn(0.3f);
assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
- new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON)),
+ new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
+ 0.1f, false)),
mFollowerBrightnessStrategy);
}
@@ -257,14 +275,39 @@
displayPowerRequest.screenBrightnessOverride = Float.NaN;
when(mFollowerBrightnessStrategy.getBrightnessToFollow()).thenReturn(Float.NaN);
when(mTemporaryBrightnessStrategy.getTemporaryScreenBrightness()).thenReturn(Float.NaN);
- when(mAutomaticBrightnessStrategy.shouldUseAutoBrightness()).thenReturn(true);
+ when(mAutomaticBrightnessStrategy2.shouldUseAutoBrightness()).thenReturn(true);
when(mOffloadBrightnessStrategy.getOffloadScreenBrightness()).thenReturn(0.3f);
assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
- new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON)),
+ new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
+ 0.1f, false)),
mOffloadBrightnessStrategy);
}
@Test
+ public void selectStrategy_selectsAutomaticStrategyWhenValid() {
+ when(mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled()).thenReturn(true);
+ mDisplayBrightnessStrategySelector = new DisplayBrightnessStrategySelector(mContext,
+ mInjector, DISPLAY_ID, mDisplayManagerFlags);
+ DisplayManagerInternal.DisplayPowerRequest displayPowerRequest = mock(
+ DisplayManagerInternal.DisplayPowerRequest.class);
+ displayPowerRequest.policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
+ displayPowerRequest.screenBrightnessOverride = Float.NaN;
+ when(mFollowerBrightnessStrategy.getBrightnessToFollow()).thenReturn(Float.NaN);
+ when(mTemporaryBrightnessStrategy.getTemporaryScreenBrightness()).thenReturn(Float.NaN);
+ when(mAutomaticBrightnessStrategy.shouldUseAutoBrightness()).thenReturn(true);
+ when(mAutomaticBrightnessStrategy.isAutoBrightnessValid()).thenReturn(true);
+ assertEquals(mDisplayBrightnessStrategySelector.selectStrategy(
+ new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
+ 0.1f, false)),
+ mAutomaticBrightnessStrategy);
+ verifyZeroInteractions(mOffloadBrightnessStrategy);
+ verify(mAutomaticBrightnessStrategy).setAutoBrightnessState(Display.STATE_ON,
+ false, BrightnessReason.REASON_UNKNOWN,
+ DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT, 0.1f, false);
+
+ }
+
+ @Test
public void selectStrategyDoesNotSelectOffloadStrategyWhenFeatureFlagDisabled() {
when(mDisplayManagerFlags.isDisplayOffloadEnabled()).thenReturn(false);
mDisplayBrightnessStrategySelector = new DisplayBrightnessStrategySelector(mContext,
@@ -277,7 +320,8 @@
when(mOffloadBrightnessStrategy.getOffloadScreenBrightness()).thenReturn(0.3f);
assertNotEquals(mOffloadBrightnessStrategy,
mDisplayBrightnessStrategySelector.selectStrategy(
- new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON)));
+ new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
+ 0.1f, false)));
}
@Test
@@ -290,10 +334,13 @@
when(mFollowerBrightnessStrategy.getBrightnessToFollow()).thenReturn(0.3f);
mDisplayBrightnessStrategySelector.selectStrategy(
- new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON));
+ new StrategySelectionRequest(displayPowerRequest, Display.STATE_ON,
+ 0.1f, false));
StrategySelectionNotifyRequest strategySelectionNotifyRequest =
- new StrategySelectionNotifyRequest(mFollowerBrightnessStrategy);
+ new StrategySelectionNotifyRequest(displayPowerRequest, Display.STATE_ON,
+ mFollowerBrightnessStrategy, 0.1f,
+ false, false);
verify(mInvalidBrightnessStrategy).strategySelectionPostProcessor(
eq(strategySelectionNotifyRequest));
verify(mScreenOffBrightnessModeStrategy).strategySelectionPostProcessor(
@@ -308,5 +355,22 @@
eq(strategySelectionNotifyRequest));
verify(mTemporaryBrightnessStrategy).strategySelectionPostProcessor(
eq(strategySelectionNotifyRequest));
+ verify(mAutomaticBrightnessStrategy).strategySelectionPostProcessor(
+ eq(strategySelectionNotifyRequest));
+ }
+
+ @Test
+ public void getAutomaticBrightnessStrategy_getsAutomaticStrategy2IfRefactoringFlagIsNotSet() {
+ assertEquals(mAutomaticBrightnessStrategy2,
+ mDisplayBrightnessStrategySelector.getAutomaticBrightnessStrategy());
+ }
+
+ @Test
+ public void getAutomaticBrightnessStrategy_getsAutomaticStrategyIfRefactoringFlagIsSet() {
+ when(mDisplayManagerFlags.isRefactorDisplayPowerControllerEnabled()).thenReturn(true);
+ mDisplayBrightnessStrategySelector = new DisplayBrightnessStrategySelector(mContext,
+ mInjector, DISPLAY_ID, mDisplayManagerFlags);
+ assertEquals(mAutomaticBrightnessStrategy,
+ mDisplayBrightnessStrategySelector.getAutomaticBrightnessStrategy());
}
}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2Test.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2Test.java
new file mode 100644
index 0000000..fd43720
--- /dev/null
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategy2Test.java
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2024 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.display.brightness.strategy;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.hardware.display.BrightnessConfiguration;
+import android.hardware.display.DisplayManagerInternal;
+import android.os.PowerManager;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.test.mock.MockContentResolver;
+import android.view.Display;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.internal.util.test.FakeSettingsProviderRule;
+import com.android.server.display.AutomaticBrightnessController;
+import com.android.server.display.brightness.BrightnessEvent;
+import com.android.server.display.brightness.BrightnessReason;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AutomaticBrightnessStrategy2Test {
+ private static final int DISPLAY_ID = 0;
+ @Rule
+ public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule();
+
+ @Mock
+ private AutomaticBrightnessController mAutomaticBrightnessController;
+
+ private BrightnessConfiguration mBrightnessConfiguration;
+ private float mDefaultScreenAutoBrightnessAdjustment;
+ private Context mContext;
+ private AutomaticBrightnessStrategy2 mAutomaticBrightnessStrategy;
+
+ @Before
+ public void before() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(new ContextWrapper(ApplicationProvider.getApplicationContext()));
+ final MockContentResolver resolver = mSettingsProviderRule.mockContentResolver(mContext);
+ when(mContext.getContentResolver()).thenReturn(resolver);
+ mDefaultScreenAutoBrightnessAdjustment = Settings.System.getFloat(
+ mContext.getContentResolver(),
+ Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, Float.NaN);
+ Settings.System.putFloat(mContext.getContentResolver(),
+ Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.5f);
+ mAutomaticBrightnessStrategy = new AutomaticBrightnessStrategy2(mContext, DISPLAY_ID);
+
+ mBrightnessConfiguration = new BrightnessConfiguration.Builder(
+ new float[]{0f, 1f}, new float[]{0, PowerManager.BRIGHTNESS_ON}).build();
+ when(mAutomaticBrightnessController.hasUserDataPoints()).thenReturn(true);
+ mAutomaticBrightnessStrategy.setAutomaticBrightnessController(
+ mAutomaticBrightnessController);
+ mAutomaticBrightnessStrategy.setBrightnessConfiguration(mBrightnessConfiguration,
+ true);
+ }
+
+ @After
+ public void after() {
+ Settings.System.putFloat(mContext.getContentResolver(),
+ Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, mDefaultScreenAutoBrightnessAdjustment);
+ }
+
+ @Test
+ public void testAutoBrightnessState_AutoBrightnessDisabled() {
+ mAutomaticBrightnessStrategy.setUseAutoBrightness(false);
+ int targetDisplayState = Display.STATE_ON;
+ boolean allowAutoBrightnessWhileDozing = false;
+ int brightnessReason = BrightnessReason.REASON_UNKNOWN;
+ int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
+ float lastUserSetBrightness = 0.2f;
+ boolean userSetBrightnessChanged = true;
+ mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments();
+ mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
+ allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+ userSetBrightnessChanged);
+ verify(mAutomaticBrightnessController)
+ .configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED,
+ mBrightnessConfiguration,
+ lastUserSetBrightness,
+ userSetBrightnessChanged, /* adjustment */ 0.5f,
+ /* userChangedAutoBrightnessAdjustment= */ false, policy,
+ targetDisplayState, /* shouldResetShortTermModel */ true);
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
+ }
+
+ @Test
+ public void testAutoBrightnessState_DisplayIsOff() {
+ mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
+ int targetDisplayState = Display.STATE_OFF;
+ boolean allowAutoBrightnessWhileDozing = false;
+ int brightnessReason = BrightnessReason.REASON_UNKNOWN;
+ int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_OFF;
+ float lastUserSetBrightness = 0.2f;
+ boolean userSetBrightnessChanged = true;
+ mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments();
+ mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
+ allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+ userSetBrightnessChanged);
+ verify(mAutomaticBrightnessController)
+ .configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE,
+ mBrightnessConfiguration,
+ lastUserSetBrightness,
+ userSetBrightnessChanged, /* adjustment */ 0.5f,
+ /* userChangedAutoBrightnessAdjustment= */ false, policy,
+ targetDisplayState, /* shouldResetShortTermModel */ true);
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+ assertTrue(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
+ }
+
+ @Test
+ public void testAutoBrightnessState_DisplayIsInDoze_ConfigDoesNotAllow() {
+ mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
+ int targetDisplayState = Display.STATE_DOZE;
+ boolean allowAutoBrightnessWhileDozing = false;
+ int brightnessReason = BrightnessReason.REASON_UNKNOWN;
+ int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
+ float lastUserSetBrightness = 0.2f;
+ boolean userSetBrightnessChanged = true;
+ mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments();
+ mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
+ allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+ userSetBrightnessChanged);
+ verify(mAutomaticBrightnessController)
+ .configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_OFF_DUE_TO_DISPLAY_STATE,
+ mBrightnessConfiguration,
+ lastUserSetBrightness,
+ userSetBrightnessChanged, /* adjustment */ 0.5f,
+ /* userChangedAutoBrightnessAdjustment= */ false, policy,
+ targetDisplayState, /* shouldResetShortTermModel */ true);
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+ assertTrue(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
+ }
+
+ @Test
+ public void testAutoBrightnessState_BrightnessReasonIsOverride() {
+ mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
+ int targetDisplayState = Display.STATE_ON;
+ boolean allowAutoBrightnessWhileDozing = false;
+ int brightnessReason = BrightnessReason.REASON_OVERRIDE;
+ int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
+ float lastUserSetBrightness = 0.2f;
+ boolean userSetBrightnessChanged = true;
+ mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments();
+ mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
+ allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+ userSetBrightnessChanged);
+ verify(mAutomaticBrightnessController)
+ .configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_DISABLED,
+ mBrightnessConfiguration,
+ lastUserSetBrightness,
+ userSetBrightnessChanged, /* adjustment */ 0.5f,
+ /* userChangedAutoBrightnessAdjustment= */ false, policy,
+ targetDisplayState, /* shouldResetShortTermModel */ true);
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
+ }
+
+ @Test
+ public void testAutoBrightnessState_DisplayIsInDoze_ConfigDoesAllow() {
+ mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
+ int targetDisplayState = Display.STATE_DOZE;
+ boolean allowAutoBrightnessWhileDozing = true;
+ int brightnessReason = BrightnessReason.REASON_UNKNOWN;
+ int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_DOZE;
+ float lastUserSetBrightness = 0.2f;
+ boolean userSetBrightnessChanged = true;
+ Settings.System.putFloat(mContext.getContentResolver(),
+ Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.4f);
+ mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments();
+ mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
+ allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+ userSetBrightnessChanged);
+ verify(mAutomaticBrightnessController)
+ .configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED,
+ mBrightnessConfiguration,
+ lastUserSetBrightness,
+ userSetBrightnessChanged, /* adjustment */ 0.4f,
+ /* userChangedAutoBrightnessAdjustment= */ true, policy,
+ targetDisplayState, /* shouldResetShortTermModel */ true);
+ assertTrue(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
+ }
+
+ @Test
+ public void testAutoBrightnessState_DisplayIsOn() {
+ mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
+ int targetDisplayState = Display.STATE_ON;
+ boolean allowAutoBrightnessWhileDozing = false;
+ int brightnessReason = BrightnessReason.REASON_UNKNOWN;
+ float lastUserSetBrightness = 0.2f;
+ boolean userSetBrightnessChanged = true;
+ int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
+ float pendingBrightnessAdjustment = 0.1f;
+ Settings.System.putFloat(mContext.getContentResolver(),
+ Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, pendingBrightnessAdjustment);
+ mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments();
+ mAutomaticBrightnessStrategy.setAutoBrightnessState(targetDisplayState,
+ allowAutoBrightnessWhileDozing, brightnessReason, policy, lastUserSetBrightness,
+ userSetBrightnessChanged);
+ verify(mAutomaticBrightnessController)
+ .configure(AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED,
+ mBrightnessConfiguration,
+ lastUserSetBrightness,
+ userSetBrightnessChanged, pendingBrightnessAdjustment,
+ /* userChangedAutoBrightnessAdjustment= */ true, policy, targetDisplayState,
+ /* shouldResetShortTermModel */ true);
+ assertTrue(mAutomaticBrightnessStrategy.isAutoBrightnessEnabled());
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessDisabledDueToDisplayOff());
+ }
+
+ @Test
+ public void accommodateUserBrightnessChangesWorksAsExpected() {
+ // Verify the state if automaticBrightnessController is configured.
+ assertFalse(mAutomaticBrightnessStrategy.isShortTermModelActive());
+ boolean userSetBrightnessChanged = true;
+ float lastUserSetScreenBrightness = 0.2f;
+ int policy = DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT;
+ int targetDisplayState = Display.STATE_ON;
+ BrightnessConfiguration brightnessConfiguration = new BrightnessConfiguration.Builder(
+ new float[]{0f, 1f}, new float[]{0, PowerManager.BRIGHTNESS_ON}).build();
+ int autoBrightnessState = AutomaticBrightnessController.AUTO_BRIGHTNESS_ENABLED;
+ float temporaryAutoBrightnessAdjustments = 0.4f;
+ mAutomaticBrightnessStrategy.setShouldResetShortTermModel(true);
+ setTemporaryAutoBrightnessAdjustment(temporaryAutoBrightnessAdjustments);
+ mAutomaticBrightnessStrategy.accommodateUserBrightnessChanges(userSetBrightnessChanged,
+ lastUserSetScreenBrightness, policy, targetDisplayState, brightnessConfiguration,
+ autoBrightnessState);
+ verify(mAutomaticBrightnessController).configure(autoBrightnessState,
+ brightnessConfiguration,
+ lastUserSetScreenBrightness,
+ userSetBrightnessChanged, temporaryAutoBrightnessAdjustments,
+ /* userChangedAutoBrightnessAdjustment= */ false, policy, targetDisplayState,
+ /* shouldResetShortTermModel= */ true);
+ assertTrue(mAutomaticBrightnessStrategy.isTemporaryAutoBrightnessAdjustmentApplied());
+ assertFalse(mAutomaticBrightnessStrategy.shouldResetShortTermModel());
+ assertTrue(mAutomaticBrightnessStrategy.isShortTermModelActive());
+ // Verify the state when automaticBrightnessController is not configured
+ setTemporaryAutoBrightnessAdjustment(Float.NaN);
+ mAutomaticBrightnessStrategy.setAutomaticBrightnessController(null);
+ mAutomaticBrightnessStrategy.setShouldResetShortTermModel(true);
+ mAutomaticBrightnessStrategy.accommodateUserBrightnessChanges(userSetBrightnessChanged,
+ lastUserSetScreenBrightness, policy, targetDisplayState, brightnessConfiguration,
+ autoBrightnessState);
+ assertFalse(mAutomaticBrightnessStrategy.isTemporaryAutoBrightnessAdjustmentApplied());
+ assertTrue(mAutomaticBrightnessStrategy.shouldResetShortTermModel());
+ assertFalse(mAutomaticBrightnessStrategy.isShortTermModelActive());
+ }
+
+ @Test
+ public void adjustAutomaticBrightnessStateIfValid() throws Settings.SettingNotFoundException {
+ float brightnessState = 0.3f;
+ float autoBrightnessAdjustment = 0.2f;
+ when(mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment()).thenReturn(
+ autoBrightnessAdjustment);
+ mAutomaticBrightnessStrategy.adjustAutomaticBrightnessStateIfValid(brightnessState);
+ assertEquals(autoBrightnessAdjustment,
+ mAutomaticBrightnessStrategy.getAutoBrightnessAdjustment(), 0.0f);
+ assertEquals(autoBrightnessAdjustment, Settings.System.getFloatForUser(
+ mContext.getContentResolver(),
+ Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ,
+ UserHandle.USER_CURRENT), 0.0f);
+ assertEquals(BrightnessReason.ADJUSTMENT_AUTO,
+ mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentReasonsFlags());
+ float invalidBrightness = -0.5f;
+ mAutomaticBrightnessStrategy
+ .adjustAutomaticBrightnessStateIfValid(invalidBrightness);
+ assertEquals(autoBrightnessAdjustment,
+ mAutomaticBrightnessStrategy.getAutoBrightnessAdjustment(), 0.0f);
+ assertEquals(0,
+ mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentReasonsFlags());
+ }
+
+ @Test
+ public void updatePendingAutoBrightnessAdjustments() {
+ // Verify the state when the pendingAutoBrightnessAdjustments are not present
+ setPendingAutoBrightnessAdjustment(Float.NaN);
+ assertFalse(mAutomaticBrightnessStrategy.processPendingAutoBrightnessAdjustments());
+ assertFalse(mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentChanged());
+ // Verify the state when the pendingAutoBrightnessAdjustments are present, but
+ // pendingAutoBrightnessAdjustments and autoBrightnessAdjustments are the same
+ float autoBrightnessAdjustment = 0.3f;
+ setPendingAutoBrightnessAdjustment(autoBrightnessAdjustment);
+ setAutoBrightnessAdjustment(autoBrightnessAdjustment);
+ assertFalse(mAutomaticBrightnessStrategy.processPendingAutoBrightnessAdjustments());
+ assertFalse(mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentChanged());
+ assertEquals(Float.NaN, mAutomaticBrightnessStrategy.getPendingAutoBrightnessAdjustment(),
+ 0.0f);
+ // Verify the state when the pendingAutoBrightnessAdjustments are present, and
+ // pendingAutoBrightnessAdjustments and autoBrightnessAdjustments are not the same
+ float pendingAutoBrightnessAdjustment = 0.2f;
+ setPendingAutoBrightnessAdjustment(pendingAutoBrightnessAdjustment);
+ setTemporaryAutoBrightnessAdjustment(0.1f);
+ assertTrue(mAutomaticBrightnessStrategy.processPendingAutoBrightnessAdjustments());
+ assertTrue(mAutomaticBrightnessStrategy.getAutoBrightnessAdjustmentChanged());
+ assertEquals(pendingAutoBrightnessAdjustment,
+ mAutomaticBrightnessStrategy.getAutoBrightnessAdjustment(), 0.0f);
+ assertEquals(Float.NaN, mAutomaticBrightnessStrategy.getPendingAutoBrightnessAdjustment(),
+ 0.0f);
+ assertEquals(Float.NaN, mAutomaticBrightnessStrategy.getTemporaryAutoBrightnessAdjustment(),
+ 0.0f);
+ }
+
+ @Test
+ public void setAutomaticBrightnessWorksAsExpected() {
+ float automaticScreenBrightness = 0.3f;
+ AutomaticBrightnessController automaticBrightnessController = mock(
+ AutomaticBrightnessController.class);
+ when(automaticBrightnessController.getAutomaticScreenBrightness(any(BrightnessEvent.class)))
+ .thenReturn(automaticScreenBrightness);
+ when(automaticBrightnessController.getAutomaticScreenBrightnessBasedOnLastObservedLux(
+ any(BrightnessEvent.class)))
+ .thenReturn(automaticScreenBrightness);
+ mAutomaticBrightnessStrategy.setAutomaticBrightnessController(
+ automaticBrightnessController);
+ assertEquals(automaticScreenBrightness,
+ mAutomaticBrightnessStrategy.getAutomaticScreenBrightness(
+ new BrightnessEvent(DISPLAY_ID)), 0.0f);
+ assertEquals(automaticScreenBrightness,
+ mAutomaticBrightnessStrategy.getAutomaticScreenBrightnessBasedOnLastObservedLux(
+ new BrightnessEvent(DISPLAY_ID)), 0.0f);
+ }
+
+ @Test
+ public void shouldUseAutoBrightness() {
+ mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
+ assertTrue(mAutomaticBrightnessStrategy.shouldUseAutoBrightness());
+ }
+
+ @Test
+ public void setPendingAutoBrightnessAdjustments() throws Settings.SettingNotFoundException {
+ float pendingAutoBrightnessAdjustments = 0.3f;
+ setPendingAutoBrightnessAdjustment(pendingAutoBrightnessAdjustments);
+ assertEquals(pendingAutoBrightnessAdjustments,
+ mAutomaticBrightnessStrategy.getPendingAutoBrightnessAdjustment(), 0.0f);
+ assertEquals(pendingAutoBrightnessAdjustments, Settings.System.getFloatForUser(
+ mContext.getContentResolver(),
+ Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ,
+ UserHandle.USER_CURRENT), 0.0f);
+ }
+
+ @Test
+ public void setTemporaryAutoBrightnessAdjustment() {
+ float temporaryAutoBrightnessAdjustment = 0.3f;
+ mAutomaticBrightnessStrategy.setTemporaryAutoBrightnessAdjustment(
+ temporaryAutoBrightnessAdjustment);
+ assertEquals(temporaryAutoBrightnessAdjustment,
+ mAutomaticBrightnessStrategy.getTemporaryAutoBrightnessAdjustment(), 0.0f);
+ }
+
+ @Test
+ public void setAutoBrightnessApplied() {
+ mAutomaticBrightnessStrategy.setAutoBrightnessApplied(true);
+ assertTrue(mAutomaticBrightnessStrategy.hasAppliedAutoBrightness());
+ }
+
+ @Test
+ public void testVerifyNoAutoBrightnessAdjustmentsArePopulatedForNonDefaultDisplay() {
+ int newDisplayId = 1;
+ mAutomaticBrightnessStrategy = new AutomaticBrightnessStrategy2(mContext, newDisplayId);
+ mAutomaticBrightnessStrategy.putAutoBrightnessAdjustmentSetting(0.3f);
+ assertEquals(0.5f, mAutomaticBrightnessStrategy.getAutoBrightnessAdjustment(),
+ 0.0f);
+ }
+
+ private void setPendingAutoBrightnessAdjustment(float pendingAutoBrightnessAdjustment) {
+ Settings.System.putFloat(mContext.getContentResolver(),
+ Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, pendingAutoBrightnessAdjustment);
+ mAutomaticBrightnessStrategy.updatePendingAutoBrightnessAdjustments();
+ }
+
+ private void setTemporaryAutoBrightnessAdjustment(float temporaryAutoBrightnessAdjustment) {
+ mAutomaticBrightnessStrategy.setTemporaryAutoBrightnessAdjustment(
+ temporaryAutoBrightnessAdjustment);
+ }
+
+ private void setAutoBrightnessAdjustment(float autoBrightnessAdjustment) {
+ mAutomaticBrightnessStrategy.putAutoBrightnessAdjustmentSetting(autoBrightnessAdjustment);
+ }
+}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
index 4e55270..6e163ca 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/strategy/AutomaticBrightnessStrategyTest.java
@@ -398,6 +398,34 @@
0.0f);
}
+ @Test
+ public void isAutoBrightnessValid_returnsFalseWhenAutoBrightnessIsDisabled() {
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessValid());
+ }
+
+ @Test
+ public void isAutoBrightnessValid_returnsFalseWhenBrightnessIsInvalid() {
+ mAutomaticBrightnessStrategy.setAutoBrightnessState(Display.STATE_ON, true,
+ BrightnessReason.REASON_UNKNOWN,
+ DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT, 0.1f,
+ false);
+ when(mAutomaticBrightnessController.getAutomaticScreenBrightness(null))
+ .thenReturn(Float.NaN);
+ assertFalse(mAutomaticBrightnessStrategy.isAutoBrightnessValid());
+ }
+
+ @Test
+ public void isAutoBrightnessValid_returnsTrueWhenBrightnessIsValid() {
+ mAutomaticBrightnessStrategy.setUseAutoBrightness(true);
+ mAutomaticBrightnessStrategy.setAutoBrightnessState(Display.STATE_ON, true,
+ BrightnessReason.REASON_UNKNOWN,
+ DisplayManagerInternal.DisplayPowerRequest.POLICY_BRIGHT, 0.1f,
+ false);
+ when(mAutomaticBrightnessController.getAutomaticScreenBrightness(null))
+ .thenReturn(0.2f);
+ assertTrue(mAutomaticBrightnessStrategy.isAutoBrightnessValid());
+ }
+
private void setPendingAutoBrightnessAdjustment(float pendingAutoBrightnessAdjustment) {
Settings.System.putFloat(mContext.getContentResolver(),
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, pendingAutoBrightnessAdjustment);
diff --git a/services/tests/mockingservicestests/src/com/android/server/OWNERS b/services/tests/mockingservicestests/src/com/android/server/OWNERS
index 0eb8639..dc5cb8d6 100644
--- a/services/tests/mockingservicestests/src/com/android/server/OWNERS
+++ b/services/tests/mockingservicestests/src/com/android/server/OWNERS
@@ -3,3 +3,5 @@
per-file *DeviceIdleController* = file:/apex/jobscheduler/OWNERS
per-file SensitiveContentProtectionManagerService* = file:/core/java/android/permission/OWNERS
per-file RescuePartyTest.java = file:/packages/CrashRecovery/OWNERS
+per-file *Storage* = file:/core/java/android/os/storage/OWNERS
+
diff --git a/services/tests/mockingservicestests/src/com/android/server/StorageManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/StorageManagerServiceTest.java
new file mode 100644
index 0000000..2e4b97e
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/StorageManagerServiceTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2024 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;
+
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.spy;
+
+import android.content.Context;
+import android.multiuser.Flags;
+import android.os.UserManager;
+import android.os.storage.ICeStorageLockEventListener;
+import android.os.storage.StorageManagerInternal;
+import android.platform.test.flag.junit.SetFlagsRule;
+
+import com.android.modules.utils.testing.ExtendedMockitoRule;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.concurrent.CopyOnWriteArrayList;
+
+public class StorageManagerServiceTest {
+
+ private final Context mRealContext = androidx.test.platform.app.InstrumentationRegistry
+ .getInstrumentation().getTargetContext();
+ private StorageManagerService mStorageManagerService;
+ private StorageManagerInternal mStorageManagerInternal;
+
+ private static final int TEST_USER_ID = 1001;
+
+ @Rule
+ public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this)
+ .spyStatic(UserManager.class)
+ .build();
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+ private static class TestStorageEventListener implements ICeStorageLockEventListener {
+
+ private int mExpectedUserId;
+
+ private TestStorageEventListener(int userId) {
+ mExpectedUserId = userId;
+ }
+
+ @Override
+ public void onStorageLocked(int userId) {
+ assertThat(userId).isEqualTo(mExpectedUserId);
+ }
+ }
+
+
+ @Before
+ public void setFixtures() {
+ // Called when WatchedUserStates is constructed
+ doNothing().when(() -> UserManager.invalidateIsUserUnlockedCache());
+
+ mStorageManagerService = new StorageManagerService(mRealContext);
+ mStorageManagerInternal = LocalServices.getService(StorageManagerInternal.class);
+ assertWithMessage("LocalServices.getService(StorageManagerInternal.class)")
+ .that(mStorageManagerInternal).isNotNull();
+ }
+
+ @After
+ public void tearDown() {
+ LocalServices.removeServiceForTest(StorageManagerInternal.class);
+ }
+
+ @Test
+ public void testRegisterLockEventListener() {
+ mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
+ Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE,
+ Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE);
+ CopyOnWriteArrayList<ICeStorageLockEventListener> storageLockEventListeners =
+ mStorageManagerService.getCeStorageEventCallbacks();
+ assertThat(storageLockEventListeners).isNotNull();
+ int registeredCallbackCount = storageLockEventListeners.size();
+ TestStorageEventListener testStorageEventListener =
+ new TestStorageEventListener(TEST_USER_ID);
+ mStorageManagerInternal.registerStorageLockEventListener(testStorageEventListener);
+ assertNumberOfStorageCallbackReceivers(registeredCallbackCount + 1);
+
+ mStorageManagerInternal.unregisterStorageLockEventListener(testStorageEventListener);
+ assertNumberOfStorageCallbackReceivers(registeredCallbackCount);
+ }
+
+ @Test
+ public void testDispatchCeStorageLockEvent() {
+ mSetFlagsRule.enableFlags(android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
+ Flags.FLAG_ENABLE_BIOMETRICS_TO_UNLOCK_PRIVATE_SPACE,
+ Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
+
+ assertThat(mStorageManagerService.getCeStorageEventCallbacks()).isNotNull();
+ int callbackReceiverSize = mStorageManagerService.getCeStorageEventCallbacks().size();
+ TestStorageEventListener testStorageEventListener =
+ spy(new TestStorageEventListener(TEST_USER_ID));
+
+ // Add testStorageEventListener to the list of storage callback listeners
+ mStorageManagerService.getCeStorageEventCallbacks().add(testStorageEventListener);
+ assertNumberOfStorageCallbackReceivers(callbackReceiverSize + 1);
+
+ mStorageManagerService.dispatchCeStorageLockedEvent(TEST_USER_ID);
+ verify(testStorageEventListener).onStorageLocked(eq(TEST_USER_ID));
+
+ // Remove testStorageEventListener from the list of storage callback listeners
+ mStorageManagerService.getCeStorageEventCallbacks().remove(testStorageEventListener);
+ assertNumberOfStorageCallbackReceivers(callbackReceiverSize);
+ }
+
+ private void assertNumberOfStorageCallbackReceivers(int callbackReceiverSize) {
+ assertThat(mStorageManagerService.getCeStorageEventCallbacks()).isNotNull();
+ assertThat(mStorageManagerService.getCeStorageEventCallbacks().size())
+ .isEqualTo(callbackReceiverSize);
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/SystemBackupAgentTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/SystemBackupAgentTest.java
index 18dc114..7e17909 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/SystemBackupAgentTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/SystemBackupAgentTest.java
@@ -18,6 +18,8 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.when;
+
import android.annotation.NonNull;
import android.app.backup.BackupHelper;
import android.app.backup.BackupHelperWithLogger;
@@ -29,8 +31,6 @@
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.ArraySet;
-import static org.mockito.Mockito.when;
-
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@@ -92,7 +92,8 @@
"people",
"app_locales",
"app_gender",
- "companion");
+ "companion",
+ "system_gender");
}
@Test
@@ -116,7 +117,8 @@
"people",
"app_locales",
"app_gender",
- "companion");
+ "companion",
+ "system_gender");
}
@Test
@@ -132,7 +134,9 @@
"notifications",
"permissions",
"app_locales",
- "companion");
+ "companion",
+ "app_gender",
+ "system_gender");
}
@Test
@@ -152,7 +156,9 @@
"account_manager",
"usage_stats",
"shortcut_manager",
- "companion");
+ "companion",
+ "app_gender",
+ "system_gender");
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index e189098..ab36ba2 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -26,6 +26,7 @@
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.nullable;
import static org.mockito.Mockito.times;
@@ -45,6 +46,7 @@
import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -57,6 +59,7 @@
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
import android.content.pm.UserInfo;
+import android.content.res.Resources;
import android.database.Cursor;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
@@ -155,6 +158,8 @@
mPackageInfo.applicationInfo = new ApplicationInfo();
mPackageInfo.applicationInfo.privateFlags = ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
when(mMockPackageManager.getPackageInfo(anyString(), anyInt())).thenReturn(mPackageInfo);
+ when(mMockPackageManager.getPackageInfoAsUser(
+ anyString(), anyInt(), anyInt())).thenReturn(mPackageInfo);
when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mMockAppOpsManager);
when(mMockContext.getSystemService(Context.USER_SERVICE)).thenReturn(mMockUserManager);
when(mMockContext.getSystemServiceName(AppOpsManager.class)).thenReturn(
@@ -3586,6 +3591,19 @@
}
@Override
+ public Resources getResources() {
+ Resources mockResources = mock(Resources.class);
+ // config_canRemoveFirstAccount = true
+ when(mockResources.getBoolean(anyInt())).thenReturn(true);
+ return mockResources;
+ }
+
+ @Override
+ public ContentResolver getContentResolver() {
+ return mock(ContentResolver.class);
+ }
+
+ @Override
public void sendBroadcastAsUser(Intent intent, UserHandle user) {
sendBroadcastAsUser(intent, user, null, null);
}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java
index 9f3f297..e4c56a7 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/FaceServiceTest.java
@@ -176,6 +176,21 @@
}
@Test
+ @RequiresFlagsEnabled({Flags.FLAG_DE_HIDL, Flags.FLAG_FACE_VHAL_FEATURE})
+ public void registerAuthenticatorsLegacy_virtualFaceOnly() throws Exception {
+ initService();
+ Settings.Secure.putInt(mSettingsRule.mockContentResolver(mContext),
+ Settings.Secure.BIOMETRIC_FACE_VIRTUAL_ENABLED, 1);
+
+ mFaceService.mServiceWrapper.registerAuthenticatorsLegacy(mFaceSensorConfigurations);
+ waitForRegistration();
+
+ verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL),
+ eq(BiometricAuthenticator.TYPE_FACE),
+ eq(Utils.propertyStrengthToAuthenticatorStrength(STRENGTH_STRONG)), any());
+ }
+
+ @Test
@RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
public void registerAuthenticatorsLegacy_virtualAlwaysWhenNoOther() throws Exception {
mFaceSensorConfigurations = new FaceSensorConfigurations(false);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
index 20961a9..9a8cd48 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
@@ -223,6 +223,18 @@
}
@Test
+ public void registerAuthenticators_virtualFingerprintOnly() throws Exception {
+ initServiceWith(NAME_DEFAULT, NAME_VIRTUAL);
+ Settings.Secure.putInt(mSettingsRule.mockContentResolver(mContext),
+ Settings.Secure.BIOMETRIC_FINGERPRINT_VIRTUAL_ENABLED, 1);
+
+ mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
+ waitForRegistration();
+
+ verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
+ }
+
+ @Test
@RequiresFlagsEnabled(Flags.FLAG_DE_HIDL)
public void registerAuthenticatorsLegacy_virtualOnly() throws Exception {
initServiceWith(NAME_DEFAULT, NAME_VIRTUAL);
diff --git a/services/tests/servicestests/src/com/android/server/grammaticalinflection/GrammaticalInflectionBackupTest.java b/services/tests/servicestests/src/com/android/server/grammaticalinflection/GrammaticalInflectionBackupTest.java
index 6c5a569..af6f6f2 100644
--- a/services/tests/servicestests/src/com/android/server/grammaticalinflection/GrammaticalInflectionBackupTest.java
+++ b/services/tests/servicestests/src/com/android/server/grammaticalinflection/GrammaticalInflectionBackupTest.java
@@ -18,6 +18,7 @@
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -46,6 +47,7 @@
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.List;
@@ -67,7 +69,7 @@
@Before
public void setUp() throws Exception {
mBackupHelper = new GrammaticalInflectionBackupHelper(
- mGrammaticalInflectionService, mMockPackageManager);
+ null, mGrammaticalInflectionService, mMockPackageManager);
}
@Test
@@ -106,6 +108,28 @@
eq(Configuration.GRAMMATICAL_GENDER_NEUTRAL));
}
+ @Test
+ public void testSystemBackupPayload_returnsGender()
+ throws IOException, ClassNotFoundException {
+ doReturn(Configuration.GRAMMATICAL_GENDER_MASCULINE).when(mGrammaticalInflectionService)
+ .getSystemGrammaticalGender(any(), eq(DEFAULT_USER_ID));
+
+ int gender = convertByteArrayToInt(mBackupHelper.getSystemBackupPayload(DEFAULT_USER_ID));
+
+ assertEquals(gender, Configuration.GRAMMATICAL_GENDER_MASCULINE);
+ }
+
+ @Test
+ public void testApplySystemPayload_setSystemWideGrammaticalGender()
+ throws IOException {
+ mBackupHelper.applyRestoredSystemPayload(
+ intToByteArray(Configuration.GRAMMATICAL_GENDER_NEUTRAL), DEFAULT_USER_ID);
+
+ verify(mGrammaticalInflectionService).setSystemWideGrammaticalGender(
+ eq(Configuration.GRAMMATICAL_GENDER_NEUTRAL),
+ eq(DEFAULT_USER_ID));
+ }
+
private void mockAppInstalled() {
ApplicationInfo dummyApp = new ApplicationInfo();
dummyApp.packageName = DEFAULT_PACKAGE_NAME;
@@ -141,4 +165,15 @@
}
return data;
}
+
+ private byte[] intToByteArray(final int gender) {
+ ByteBuffer bb = ByteBuffer.allocate(4);
+ bb.putInt(gender);
+ return bb.array();
+ }
+
+ private int convertByteArrayToInt(byte[] intBytes) {
+ ByteBuffer byteBuffer = ByteBuffer.wrap(intBytes);
+ return byteBuffer.getInt();
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
index 52df010..eac9929 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -85,7 +85,6 @@
import android.os.test.TestLooper;
import android.service.dreams.DreamManagerInternal;
import android.telecom.TelecomManager;
-import android.util.FeatureFlagUtils;
import android.view.Display;
import android.view.InputDevice;
import android.view.KeyEvent;
@@ -743,15 +742,8 @@
void assertSwitchKeyboardLayout(int direction, int displayId) {
mTestLooper.dispatchAll();
- if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_NEW_KEYBOARD_UI)) {
- verify(mInputMethodManagerInternal).onSwitchKeyboardLayoutShortcut(eq(direction),
- eq(displayId), eq(mImeTargetWindowToken));
- verify(mWindowManagerFuncsImpl, never()).switchKeyboardLayout(anyInt(), anyInt());
- } else {
- verify(mWindowManagerFuncsImpl).switchKeyboardLayout(anyInt(), eq(direction));
- verify(mInputMethodManagerInternal, never())
- .onSwitchKeyboardLayoutShortcut(anyInt(), anyInt(), any());
- }
+ verify(mInputMethodManagerInternal).onSwitchKeyboardLayoutShortcut(eq(direction),
+ eq(displayId), eq(mImeTargetWindowToken));
}
void assertTakeBugreport() {
diff --git a/tests/CompanionDeviceMultiDeviceTests/client/Android.bp b/tests/CompanionDeviceMultiDeviceTests/client/Android.bp
index 1e68c9d..9994826 100644
--- a/tests/CompanionDeviceMultiDeviceTests/client/Android.bp
+++ b/tests/CompanionDeviceMultiDeviceTests/client/Android.bp
@@ -19,10 +19,11 @@
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["frameworks_base_license"],
+ default_team: "trendy_team_framework_cdm",
}
android_test {
- name: "cdm_snippet",
+ name: "cdm_snippet_legacy",
srcs: ["src/**/*.kt"],
manifest: "AndroidManifest.xml",
diff --git a/tests/CompanionDeviceMultiDeviceTests/host/Android.bp b/tests/CompanionDeviceMultiDeviceTests/host/Android.bp
index 03335c7..37cb850 100644
--- a/tests/CompanionDeviceMultiDeviceTests/host/Android.bp
+++ b/tests/CompanionDeviceMultiDeviceTests/host/Android.bp
@@ -19,6 +19,7 @@
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
default_applicable_licenses: ["frameworks_base_license"],
+ default_team: "trendy_team_framework_cdm",
}
python_test_host {
@@ -36,7 +37,7 @@
tags: ["mobly"],
},
data: [
- ":cdm_snippet",
+ ":cdm_snippet_legacy",
],
version: {
py2: {
diff --git a/tests/CompanionDeviceMultiDeviceTests/host/AndroidTest.xml b/tests/CompanionDeviceMultiDeviceTests/host/AndroidTest.xml
index 9d1813f..7c7ef63 100644
--- a/tests/CompanionDeviceMultiDeviceTests/host/AndroidTest.xml
+++ b/tests/CompanionDeviceMultiDeviceTests/host/AndroidTest.xml
@@ -24,12 +24,12 @@
<device name="device1">
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
- <option name="test-file-name" value="cdm_snippet.apk" />
+ <option name="test-file-name" value="cdm_snippet_legacy.apk" />
</target_preparer>
</device>
<device name="device2">
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
- <option name="test-file-name" value="cdm_snippet.apk" />
+ <option name="test-file-name" value="cdm_snippet_legacy.apk" />
</target_preparer>
</device>
diff --git a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/RotationTransition.kt b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/RotationTransition.kt
index 511c948..1390218 100644
--- a/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/RotationTransition.kt
+++ b/tests/FlickerTests/ActivityEmbedding/src/com/android/server/wm/flicker/activityembedding/rotation/RotationTransition.kt
@@ -17,8 +17,12 @@
package com.android.server.wm.flicker.activityembedding.rotation
import android.platform.test.annotations.Presubmit
+import android.tools.Position
+import android.tools.datatypes.Rect
import android.tools.flicker.legacy.FlickerBuilder
import android.tools.flicker.legacy.LegacyFlickerTest
+import android.tools.traces.Condition
+import android.tools.traces.DeviceStateDump
import android.tools.traces.component.ComponentNameMatcher
import com.android.server.wm.flicker.activityembedding.ActivityEmbeddingTestBase
import com.android.server.wm.flicker.helpers.setRotation
@@ -30,7 +34,14 @@
override val transition: FlickerBuilder.() -> Unit = {
setup { this.setRotation(flicker.scenario.startRotation) }
teardown { testApp.exit(wmHelper) }
- transitions { this.setRotation(flicker.scenario.endRotation) }
+ transitions {
+ this.setRotation(flicker.scenario.endRotation)
+ if (!flicker.scenario.isTablet) {
+ wmHelper.StateSyncBuilder()
+ .add(navBarInPosition(flicker.scenario.isGesturalNavigation))
+ .waitForAndVerify()
+ }
+ }
}
/** {@inheritDoc} */
@@ -76,4 +87,37 @@
appLayerRotates_StartingPos()
appLayerRotates_EndingPos()
}
+
+ private fun navBarInPosition(isGesturalNavigation: Boolean): Condition<DeviceStateDump> {
+ return Condition("navBarPosition") { dump ->
+ val display =
+ dump.layerState.displays.filterNot { it.isOff }.minByOrNull { it.id }
+ ?: error("There is no display!")
+ val displayArea = display.layerStackSpace
+ val navBarPosition = display.navBarPosition(isGesturalNavigation)
+ val navBarRegion = dump.layerState
+ .getLayerWithBuffer(ComponentNameMatcher.NAV_BAR)
+ ?.visibleRegion?.bounds ?: Rect.EMPTY
+
+ when (navBarPosition) {
+ Position.TOP ->
+ navBarRegion.top == displayArea.top &&
+ navBarRegion.left == displayArea.left &&
+ navBarRegion.right == displayArea.right
+ Position.BOTTOM ->
+ navBarRegion.bottom == displayArea.bottom &&
+ navBarRegion.left == displayArea.left &&
+ navBarRegion.right == displayArea.right
+ Position.LEFT ->
+ navBarRegion.left == displayArea.left &&
+ navBarRegion.top == displayArea.top &&
+ navBarRegion.bottom == displayArea.bottom
+ Position.RIGHT ->
+ navBarRegion.right == displayArea.right &&
+ navBarRegion.top == displayArea.top &&
+ navBarRegion.bottom == displayArea.bottom
+ else -> error("Unknown position $navBarPosition")
+ }
+ }
+ }
}
diff --git a/tests/FlickerTests/README.md b/tests/FlickerTests/README.md
index 6b28fdf..7429250 100644
--- a/tests/FlickerTests/README.md
+++ b/tests/FlickerTests/README.md
@@ -7,82 +7,17 @@
## Adding a Test
-By default tests should inherit from `RotationTestBase` or `NonRotationTestBase` and must override the variable `transitionToRun` (Kotlin) or the function `getTransitionToRun()` (Java).
-Only tests that are not supported by these classes should inherit directly from the `FlickerTestBase` class.
+By default, tests should inherit from `TestBase` and override the variable `transition` (Kotlin) or the function `getTransition()` (Java).
-### Rotation animations and transitions
+Inheriting from this class ensures the common assertions will be executed, namely:
-Tests that rotate the device should inherit from `RotationTestBase`.
-Tests that inherit from the class automatically receive start and end rotation values.
-Moreover, these tests inherit the following checks:
* all regions on the screen are covered
* status bar is always visible
-* status bar rotates
+* status bar is at the correct position at the start and end of the transition
* nav bar is always visible
-* nav bar is rotates
+* nav bar is at the correct position at the start and end of the transition
The default tests can be disabled by overriding the respective methods and including an `@Ignore` annotation.
-### Non-Rotation animations and transitions
+For more examples of how a test looks like check `ChangeAppRotationTest` within the `Rotation` subdirectory.
-`NonRotationTestBase` was created to make it easier to write tests that do not involve rotation (e.g., `Pip`, `split screen` or `IME`).
-Tests that inherit from the class are automatically executed twice: once in portrait and once in landscape mode and the assertions are checked independently.
-Moreover, these tests inherit the following checks:
-* all regions on the screen are covered
-* status bar is always visible
-* nav bar is always visible
-
-The default tests can be disabled by overriding the respective methods and including an `@Ignore` annotation.
-
-### Exceptional cases
-
-Tests that rotate the device should inherit from `RotationTestBase`.
-This class allows the test to be freely configured and does not provide any assertions.
-
-
-### Example
-
-Start by defining common or error prone transitions using `TransitionRunner`.
-```kotlin
-@LargeTest
-@RunWith(Parameterized::class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class MyTest(
- beginRotationName: String,
- beginRotation: Int
-) : NonRotationTestBase(beginRotationName, beginRotation) {
- init {
- mTestApp = MyAppHelper(InstrumentationRegistry.getInstrumentation())
- }
-
- override val transitionToRun: TransitionRunner
- get() = TransitionRunner.newBuilder()
- .withTag("myTest")
- .recordAllRuns()
- .runBefore { device.pressHome() }
- .runBefore { device.waitForIdle() }
- .run { testApp.open() }
- .runAfter{ testApp.exit() }
- .repeat(2)
- .includeJankyRuns()
- .build()
-
- @Test
- fun myWMTest() {
- checkResults {
- WmTraceSubject.assertThat(it)
- .showsAppWindow(MyTestApp)
- .forAllEntries()
- }
- }
-
- @Test
- fun mySFTest() {
- checkResults {
- LayersTraceSubject.assertThat(it)
- .showsLayer(MyTestApp)
- .forAllEntries()
- }
- }
-}
-```
diff --git a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
index e60764f..80282c3 100644
--- a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
@@ -33,7 +33,6 @@
import android.os.Bundle
import android.os.test.TestLooper
import android.platform.test.annotations.Presubmit
-import android.provider.Settings
import android.util.proto.ProtoOutputStream
import android.view.InputDevice
import android.view.inputmethod.InputMethodInfo
@@ -47,9 +46,7 @@
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
-import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
-import org.junit.Assert.assertThrows
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -234,631 +231,326 @@
}
@Test
- fun testDefaultUi_getKeyboardLayouts() {
- NewSettingsApiFlag(false).use {
- val keyboardLayouts = keyboardLayoutManager.keyboardLayouts
- assertNotEquals(
- "Default UI: Keyboard layout API should not return empty array",
- 0,
- keyboardLayouts.size
- )
- assertTrue(
- "Default UI: Keyboard layout API should provide English(US) layout",
- hasLayout(keyboardLayouts, ENGLISH_US_LAYOUT_DESCRIPTOR)
- )
- }
+ fun testGetKeyboardLayouts() {
+ val keyboardLayouts = keyboardLayoutManager.keyboardLayouts
+ assertNotEquals(
+ "Keyboard layout API should not return empty array",
+ 0,
+ keyboardLayouts.size
+ )
+ assertTrue(
+ "Keyboard layout API should provide English(US) layout",
+ hasLayout(keyboardLayouts, ENGLISH_US_LAYOUT_DESCRIPTOR)
+ )
}
@Test
- fun testNewUi_getKeyboardLayouts() {
- NewSettingsApiFlag(true).use {
- val keyboardLayouts = keyboardLayoutManager.keyboardLayouts
- assertNotEquals(
- "New UI: Keyboard layout API should not return empty array",
- 0,
- keyboardLayouts.size
- )
- assertTrue(
- "New UI: Keyboard layout API should provide English(US) layout",
- hasLayout(keyboardLayouts, ENGLISH_US_LAYOUT_DESCRIPTOR)
- )
- }
+ fun testGetKeyboardLayout() {
+ val keyboardLayout =
+ keyboardLayoutManager.getKeyboardLayout(ENGLISH_US_LAYOUT_DESCRIPTOR)
+ assertEquals("getKeyboardLayout API should return correct Layout from " +
+ "available layouts",
+ ENGLISH_US_LAYOUT_DESCRIPTOR,
+ keyboardLayout!!.descriptor
+ )
}
@Test
- fun testDefaultUi_getKeyboardLayoutsForInputDevice() {
- NewSettingsApiFlag(false).use {
- val keyboardLayouts =
- keyboardLayoutManager.getKeyboardLayoutsForInputDevice(keyboardDevice.identifier)
- assertNotEquals(
- "Default UI: getKeyboardLayoutsForInputDevice API should not return empty array",
- 0,
- keyboardLayouts.size
- )
- assertTrue(
- "Default UI: getKeyboardLayoutsForInputDevice API should provide English(US) " +
- "layout",
- hasLayout(keyboardLayouts, ENGLISH_US_LAYOUT_DESCRIPTOR)
- )
+ fun testGetSetKeyboardLayoutForInputDevice_withImeInfo() {
+ val imeSubtype = createImeSubtype()
- val vendorSpecificKeyboardLayouts =
- keyboardLayoutManager.getKeyboardLayoutsForInputDevice(
- vendorSpecificKeyboardDevice.identifier
- )
- assertEquals(
- "Default UI: getKeyboardLayoutsForInputDevice API should return only vendor " +
- "specific layout",
+ keyboardLayoutManager.setKeyboardLayoutForInputDevice(
+ keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype,
+ ENGLISH_UK_LAYOUT_DESCRIPTOR
+ )
+ var result =
+ keyboardLayoutManager.getKeyboardLayoutForInputDevice(
+ keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype
+ )
+ assertEquals(
+ "getKeyboardLayoutForInputDevice API should return the set layout",
+ ENGLISH_UK_LAYOUT_DESCRIPTOR,
+ result.layoutDescriptor
+ )
+
+ // This should replace previously set layout
+ keyboardLayoutManager.setKeyboardLayoutForInputDevice(
+ keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype,
+ ENGLISH_US_LAYOUT_DESCRIPTOR
+ )
+ result =
+ keyboardLayoutManager.getKeyboardLayoutForInputDevice(
+ keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype
+ )
+ assertEquals(
+ "getKeyboardLayoutForInputDevice API should return the last set layout",
+ ENGLISH_US_LAYOUT_DESCRIPTOR,
+ result.layoutDescriptor
+ )
+ }
+
+ @Test
+ fun testGetKeyboardLayoutListForInputDevice() {
+ // Check Layouts for "hi-Latn". It should return all 'Latn' keyboard layouts
+ var keyboardLayouts =
+ keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
+ keyboardDevice.identifier, USER_ID, imeInfo,
+ createImeSubtypeForLanguageTag("hi-Latn")
+ )
+ assertNotEquals(
+ "getKeyboardLayoutListForInputDevice API should return the list of " +
+ "supported layouts with matching script code",
+ 0,
+ keyboardLayouts.size
+ )
+ assertTrue("getKeyboardLayoutListForInputDevice API should return a list " +
+ "containing English(US) layout for hi-Latn",
+ containsLayout(keyboardLayouts, ENGLISH_US_LAYOUT_DESCRIPTOR)
+ )
+ assertTrue("getKeyboardLayoutListForInputDevice API should return a list " +
+ "containing English(No script code) layout for hi-Latn",
+ containsLayout(
+ keyboardLayouts,
+ createLayoutDescriptor("keyboard_layout_english_without_script_code")
+ )
+ )
+
+ // Check Layouts for "hi" which by default uses 'Deva' script.
+ keyboardLayouts =
+ keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
+ keyboardDevice.identifier, USER_ID, imeInfo,
+ createImeSubtypeForLanguageTag("hi")
+ )
+ assertEquals("getKeyboardLayoutListForInputDevice API should return empty " +
+ "list if no supported layouts available",
+ 0,
+ keyboardLayouts.size
+ )
+
+ // If user manually selected some layout, always provide it in the layout list
+ val imeSubtype = createImeSubtypeForLanguageTag("hi")
+ keyboardLayoutManager.setKeyboardLayoutForInputDevice(
+ keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype,
+ ENGLISH_US_LAYOUT_DESCRIPTOR
+ )
+ keyboardLayouts =
+ keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
+ keyboardDevice.identifier, USER_ID, imeInfo,
+ imeSubtype
+ )
+ assertEquals("getKeyboardLayoutListForInputDevice API should return user " +
+ "selected layout even if the script is incompatible with IME",
1,
- vendorSpecificKeyboardLayouts.size
- )
- assertEquals(
- "Default UI: getKeyboardLayoutsForInputDevice API should return vendor specific " +
- "layout",
- VENDOR_SPECIFIC_LAYOUT_DESCRIPTOR,
- vendorSpecificKeyboardLayouts[0].descriptor
- )
- }
- }
+ keyboardLayouts.size
+ )
- @Test
- fun testNewUi_getKeyboardLayoutsForInputDevice() {
- NewSettingsApiFlag(true).use {
- val keyboardLayouts = keyboardLayoutManager.keyboardLayouts
- assertNotEquals(
- "New UI: getKeyboardLayoutsForInputDevice API should not return empty array",
- 0,
- keyboardLayouts.size
- )
- assertTrue(
- "New UI: getKeyboardLayoutsForInputDevice API should provide English(US) " +
- "layout",
- hasLayout(keyboardLayouts, ENGLISH_US_LAYOUT_DESCRIPTOR)
- )
- }
- }
-
- @Test
- fun testDefaultUi_getSetCurrentKeyboardLayoutForInputDevice() {
- NewSettingsApiFlag(false).use {
- assertNull(
- "Default UI: getCurrentKeyboardLayoutForInputDevice API should return null if " +
- "nothing was set",
- keyboardLayoutManager.getCurrentKeyboardLayoutForInputDevice(
- keyboardDevice.identifier
- )
- )
-
- keyboardLayoutManager.setCurrentKeyboardLayoutForInputDevice(
- keyboardDevice.identifier,
- ENGLISH_US_LAYOUT_DESCRIPTOR
- )
- val keyboardLayout =
- keyboardLayoutManager.getCurrentKeyboardLayoutForInputDevice(
- keyboardDevice.identifier
- )
- assertEquals(
- "Default UI: getCurrentKeyboardLayoutForInputDevice API should return the set " +
- "layout",
- ENGLISH_US_LAYOUT_DESCRIPTOR,
- keyboardLayout
- )
- }
- }
-
- @Test
- fun testNewUi_getSetCurrentKeyboardLayoutForInputDevice() {
- NewSettingsApiFlag(true).use {
- keyboardLayoutManager.setCurrentKeyboardLayoutForInputDevice(
- keyboardDevice.identifier,
- ENGLISH_US_LAYOUT_DESCRIPTOR
- )
- assertNull(
- "New UI: getCurrentKeyboardLayoutForInputDevice API should always return null " +
- "even after setCurrentKeyboardLayoutForInputDevice",
- keyboardLayoutManager.getCurrentKeyboardLayoutForInputDevice(
- keyboardDevice.identifier
- )
- )
- }
- }
-
- @Test
- fun testDefaultUi_getEnabledKeyboardLayoutsForInputDevice() {
- NewSettingsApiFlag(false).use {
- keyboardLayoutManager.addKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, ENGLISH_US_LAYOUT_DESCRIPTOR
- )
-
- val keyboardLayouts =
- keyboardLayoutManager.getEnabledKeyboardLayoutsForInputDevice(
- keyboardDevice.identifier
- )
- assertEquals(
- "Default UI: getEnabledKeyboardLayoutsForInputDevice API should return added " +
- "layout",
- 1,
- keyboardLayouts.size
- )
- assertEquals(
- "Default UI: getEnabledKeyboardLayoutsForInputDevice API should return " +
- "English(US) layout",
- ENGLISH_US_LAYOUT_DESCRIPTOR,
- keyboardLayouts[0]
- )
- assertEquals(
- "Default UI: getCurrentKeyboardLayoutForInputDevice API should return " +
- "English(US) layout (Auto select the first enabled layout)",
- ENGLISH_US_LAYOUT_DESCRIPTOR,
- keyboardLayoutManager.getCurrentKeyboardLayoutForInputDevice(
- keyboardDevice.identifier
- )
- )
-
- keyboardLayoutManager.removeKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, ENGLISH_US_LAYOUT_DESCRIPTOR
- )
- assertEquals(
- "Default UI: getKeyboardLayoutsForInputDevice API should return 0 layouts",
- 0,
- keyboardLayoutManager.getEnabledKeyboardLayoutsForInputDevice(
- keyboardDevice.identifier
- ).size
- )
- assertNull(
- "Default UI: getCurrentKeyboardLayoutForInputDevice API should return null after " +
- "the enabled layout is removed",
- keyboardLayoutManager.getCurrentKeyboardLayoutForInputDevice(
- keyboardDevice.identifier
- )
- )
- }
- }
-
- @Test
- fun testNewUi_getEnabledKeyboardLayoutsForInputDevice() {
- NewSettingsApiFlag(true).use {
- keyboardLayoutManager.addKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, ENGLISH_US_LAYOUT_DESCRIPTOR
- )
-
- assertEquals(
- "New UI: getEnabledKeyboardLayoutsForInputDevice API should return always return " +
- "an empty array",
- 0,
- keyboardLayoutManager.getEnabledKeyboardLayoutsForInputDevice(
- keyboardDevice.identifier
- ).size
- )
- assertNull(
- "New UI: getCurrentKeyboardLayoutForInputDevice API should always return null",
- keyboardLayoutManager.getCurrentKeyboardLayoutForInputDevice(
- keyboardDevice.identifier
- )
- )
- }
- }
-
- @Test
- fun testDefaultUi_switchKeyboardLayout() {
- NewSettingsApiFlag(false).use {
- keyboardLayoutManager.addKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, ENGLISH_US_LAYOUT_DESCRIPTOR
- )
- keyboardLayoutManager.addKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, ENGLISH_UK_LAYOUT_DESCRIPTOR
- )
- assertEquals(
- "Default UI: getCurrentKeyboardLayoutForInputDevice API should return " +
- "English(US) layout",
- ENGLISH_US_LAYOUT_DESCRIPTOR,
- keyboardLayoutManager.getCurrentKeyboardLayoutForInputDevice(
- keyboardDevice.identifier
- )
- )
-
- keyboardLayoutManager.switchKeyboardLayout(DEVICE_ID, 1)
-
- // Throws null pointer because trying to show toast using TestLooper
- assertThrows(NullPointerException::class.java) { testLooper.dispatchAll() }
- assertEquals("Default UI: getCurrentKeyboardLayoutForInputDevice API should return " +
- "English(UK) layout",
- ENGLISH_UK_LAYOUT_DESCRIPTOR,
- keyboardLayoutManager.getCurrentKeyboardLayoutForInputDevice(
- keyboardDevice.identifier
- )
- )
- }
- }
-
- @Test
- fun testNewUi_switchKeyboardLayout() {
- NewSettingsApiFlag(true).use {
- keyboardLayoutManager.addKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, ENGLISH_US_LAYOUT_DESCRIPTOR
- )
- keyboardLayoutManager.addKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, ENGLISH_UK_LAYOUT_DESCRIPTOR
- )
-
- keyboardLayoutManager.switchKeyboardLayout(DEVICE_ID, 1)
- testLooper.dispatchAll()
-
- assertNull("New UI: getCurrentKeyboardLayoutForInputDevice API should always return " +
- "null",
- keyboardLayoutManager.getCurrentKeyboardLayoutForInputDevice(
- keyboardDevice.identifier
- )
- )
- }
- }
-
- @Test
- fun testDefaultUi_getKeyboardLayout() {
- NewSettingsApiFlag(false).use {
- val keyboardLayout =
- keyboardLayoutManager.getKeyboardLayout(ENGLISH_US_LAYOUT_DESCRIPTOR)
- assertEquals("Default UI: getKeyboardLayout API should return correct Layout from " +
- "available layouts",
- ENGLISH_US_LAYOUT_DESCRIPTOR,
- keyboardLayout!!.descriptor
- )
- }
- }
-
- @Test
- fun testNewUi_getKeyboardLayout() {
- NewSettingsApiFlag(true).use {
- val keyboardLayout =
- keyboardLayoutManager.getKeyboardLayout(ENGLISH_US_LAYOUT_DESCRIPTOR)
- assertEquals("New UI: getKeyboardLayout API should return correct Layout from " +
- "available layouts",
- ENGLISH_US_LAYOUT_DESCRIPTOR,
- keyboardLayout!!.descriptor
- )
- }
- }
-
- @Test
- fun testDefaultUi_getSetKeyboardLayoutForInputDevice_WithImeInfo() {
- NewSettingsApiFlag(false).use {
- val imeSubtype = createImeSubtype()
- keyboardLayoutManager.setKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype,
- ENGLISH_UK_LAYOUT_DESCRIPTOR
- )
- assertEquals(
- "Default UI: getKeyboardLayoutForInputDevice API should always return " +
- "KeyboardLayoutSelectionResult.FAILED",
- KeyboardLayoutSelectionResult.FAILED,
- keyboardLayoutManager.getKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype
- )
- )
- }
- }
-
- @Test
- fun testNewUi_getSetKeyboardLayoutForInputDevice_withImeInfo() {
- NewSettingsApiFlag(true).use {
- val imeSubtype = createImeSubtype()
-
- keyboardLayoutManager.setKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype,
- ENGLISH_UK_LAYOUT_DESCRIPTOR
- )
- var result =
- keyboardLayoutManager.getKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype
- )
- assertEquals(
- "New UI: getKeyboardLayoutForInputDevice API should return the set layout",
- ENGLISH_UK_LAYOUT_DESCRIPTOR,
- result.layoutDescriptor
- )
-
- // This should replace previously set layout
- keyboardLayoutManager.setKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype,
- ENGLISH_US_LAYOUT_DESCRIPTOR
- )
- result =
- keyboardLayoutManager.getKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype
- )
- assertEquals(
- "New UI: getKeyboardLayoutForInputDevice API should return the last set layout",
- ENGLISH_US_LAYOUT_DESCRIPTOR,
- result.layoutDescriptor
- )
- }
- }
-
- @Test
- fun testDefaultUi_getKeyboardLayoutListForInputDevice() {
- NewSettingsApiFlag(false).use {
- val keyboardLayouts =
- keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
+ // Special case Japanese: UScript ignores provided script code for certain language tags
+ // Should manually match provided script codes and then rely on Uscript to derive
+ // script from language tags and match those.
+ keyboardLayouts =
+ keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
keyboardDevice.identifier, USER_ID, imeInfo,
- createImeSubtype()
- )
- assertEquals("Default UI: getKeyboardLayoutListForInputDevice API should always " +
- "return empty array",
- 0,
- keyboardLayouts.size
+ createImeSubtypeForLanguageTag("ja-Latn-JP")
)
- }
- }
+ assertNotEquals(
+ "getKeyboardLayoutListForInputDevice API should return the list of " +
+ "supported layouts with matching script code for ja-Latn-JP",
+ 0,
+ keyboardLayouts.size
+ )
+ assertTrue("getKeyboardLayoutListForInputDevice API should return a list " +
+ "containing English(US) layout for ja-Latn-JP",
+ containsLayout(keyboardLayouts, ENGLISH_US_LAYOUT_DESCRIPTOR)
+ )
+ assertTrue("getKeyboardLayoutListForInputDevice API should return a list " +
+ "containing English(No script code) layout for ja-Latn-JP",
+ containsLayout(
+ keyboardLayouts,
+ createLayoutDescriptor("keyboard_layout_english_without_script_code")
+ )
+ )
- @Test
- fun testNewUi_getKeyboardLayoutListForInputDevice() {
- NewSettingsApiFlag(true).use {
- // Check Layouts for "hi-Latn". It should return all 'Latn' keyboard layouts
- var keyboardLayouts =
- keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
+ // If script code not explicitly provided for Japanese should rely on Uscript to find
+ // derived script code and hence no suitable layout will be found.
+ keyboardLayouts =
+ keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
keyboardDevice.identifier, USER_ID, imeInfo,
- createImeSubtypeForLanguageTag("hi-Latn")
- )
- assertNotEquals(
- "New UI: getKeyboardLayoutListForInputDevice API should return the list of " +
- "supported layouts with matching script code",
- 0,
- keyboardLayouts.size
+ createImeSubtypeForLanguageTag("ja-JP")
)
- assertTrue("New UI: getKeyboardLayoutListForInputDevice API should return a list " +
- "containing English(US) layout for hi-Latn",
- containsLayout(keyboardLayouts, ENGLISH_US_LAYOUT_DESCRIPTOR)
- )
- assertTrue("New UI: getKeyboardLayoutListForInputDevice API should return a list " +
- "containing English(No script code) layout for hi-Latn",
- containsLayout(
- keyboardLayouts,
- createLayoutDescriptor("keyboard_layout_english_without_script_code")
- )
- )
+ assertEquals(
+ "getKeyboardLayoutListForInputDevice API should return empty list of " +
+ "supported layouts with matching script code for ja-JP",
+ 0,
+ keyboardLayouts.size
+ )
- // Check Layouts for "hi" which by default uses 'Deva' script.
- keyboardLayouts =
- keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
- keyboardDevice.identifier, USER_ID, imeInfo,
- createImeSubtypeForLanguageTag("hi")
- )
- assertEquals("New UI: getKeyboardLayoutListForInputDevice API should return empty " +
- "list if no supported layouts available",
- 0,
- keyboardLayouts.size
+ // If IME doesn't have a corresponding language tag, then should show all available
+ // layouts no matter the script code.
+ keyboardLayouts =
+ keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
+ keyboardDevice.identifier, USER_ID, imeInfo, null
)
-
- // If user manually selected some layout, always provide it in the layout list
- val imeSubtype = createImeSubtypeForLanguageTag("hi")
- keyboardLayoutManager.setKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, USER_ID, imeInfo, imeSubtype,
- ENGLISH_US_LAYOUT_DESCRIPTOR
- )
- keyboardLayouts =
- keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
- keyboardDevice.identifier, USER_ID, imeInfo,
- imeSubtype
- )
- assertEquals("New UI: getKeyboardLayoutListForInputDevice API should return user " +
- "selected layout even if the script is incompatible with IME",
- 1,
- keyboardLayouts.size
- )
-
- // Special case Japanese: UScript ignores provided script code for certain language tags
- // Should manually match provided script codes and then rely on Uscript to derive
- // script from language tags and match those.
- keyboardLayouts =
- keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
- keyboardDevice.identifier, USER_ID, imeInfo,
- createImeSubtypeForLanguageTag("ja-Latn-JP")
- )
- assertNotEquals(
- "New UI: getKeyboardLayoutListForInputDevice API should return the list of " +
- "supported layouts with matching script code for ja-Latn-JP",
- 0,
- keyboardLayouts.size
- )
- assertTrue("New UI: getKeyboardLayoutListForInputDevice API should return a list " +
- "containing English(US) layout for ja-Latn-JP",
- containsLayout(keyboardLayouts, ENGLISH_US_LAYOUT_DESCRIPTOR)
- )
- assertTrue("New UI: getKeyboardLayoutListForInputDevice API should return a list " +
- "containing English(No script code) layout for ja-Latn-JP",
- containsLayout(
- keyboardLayouts,
- createLayoutDescriptor("keyboard_layout_english_without_script_code")
- )
- )
-
- // If script code not explicitly provided for Japanese should rely on Uscript to find
- // derived script code and hence no suitable layout will be found.
- keyboardLayouts =
- keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
- keyboardDevice.identifier, USER_ID, imeInfo,
- createImeSubtypeForLanguageTag("ja-JP")
- )
- assertEquals(
- "New UI: getKeyboardLayoutListForInputDevice API should return empty list of " +
- "supported layouts with matching script code for ja-JP",
- 0,
- keyboardLayouts.size
- )
-
- // If IME doesn't have a corresponding language tag, then should show all available
- // layouts no matter the script code.
- keyboardLayouts =
- keyboardLayoutManager.getKeyboardLayoutListForInputDevice(
- keyboardDevice.identifier, USER_ID, imeInfo, null
- )
- assertNotEquals(
- "New UI: getKeyboardLayoutListForInputDevice API should return all layouts if" +
- "language tag or subtype not provided",
- 0,
- keyboardLayouts.size
- )
- assertTrue("New UI: getKeyboardLayoutListForInputDevice API should contain Latin " +
- "layouts if language tag or subtype not provided",
- containsLayout(keyboardLayouts, ENGLISH_US_LAYOUT_DESCRIPTOR)
- )
- assertTrue("New UI: getKeyboardLayoutListForInputDevice API should contain Cyrillic " +
- "layouts if language tag or subtype not provided",
- containsLayout(
- keyboardLayouts,
- createLayoutDescriptor("keyboard_layout_russian")
- )
- )
- }
- }
-
- @Test
- fun testNewUi_getDefaultKeyboardLayoutForInputDevice_withImeLanguageTag() {
- NewSettingsApiFlag(true).use {
- assertCorrectLayout(
- keyboardDevice,
- createImeSubtypeForLanguageTag("en-US"),
- ENGLISH_US_LAYOUT_DESCRIPTOR
- )
- assertCorrectLayout(
- keyboardDevice,
- createImeSubtypeForLanguageTag("en-GB"),
- ENGLISH_UK_LAYOUT_DESCRIPTOR
- )
- assertCorrectLayout(
- keyboardDevice,
- createImeSubtypeForLanguageTag("de"),
- GERMAN_LAYOUT_DESCRIPTOR
- )
- assertCorrectLayout(
- keyboardDevice,
- createImeSubtypeForLanguageTag("fr-FR"),
- createLayoutDescriptor("keyboard_layout_french")
- )
- assertCorrectLayout(
- keyboardDevice,
- createImeSubtypeForLanguageTag("ru"),
+ assertNotEquals(
+ "getKeyboardLayoutListForInputDevice API should return all layouts if" +
+ "language tag or subtype not provided",
+ 0,
+ keyboardLayouts.size
+ )
+ assertTrue("getKeyboardLayoutListForInputDevice API should contain Latin " +
+ "layouts if language tag or subtype not provided",
+ containsLayout(keyboardLayouts, ENGLISH_US_LAYOUT_DESCRIPTOR)
+ )
+ assertTrue("getKeyboardLayoutListForInputDevice API should contain Cyrillic " +
+ "layouts if language tag or subtype not provided",
+ containsLayout(
+ keyboardLayouts,
createLayoutDescriptor("keyboard_layout_russian")
)
- assertEquals(
- "New UI: getDefaultKeyboardLayoutForInputDevice should return " +
- "KeyboardLayoutSelectionResult.FAILED when no layout available",
- KeyboardLayoutSelectionResult.FAILED,
- keyboardLayoutManager.getKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, USER_ID, imeInfo,
- createImeSubtypeForLanguageTag("it")
- )
- )
- assertEquals(
- "New UI: getDefaultKeyboardLayoutForInputDevice should return " +
- "KeyboardLayoutSelectionResult.FAILED when no layout for script code is" +
- "available",
- KeyboardLayoutSelectionResult.FAILED,
- keyboardLayoutManager.getKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, USER_ID, imeInfo,
- createImeSubtypeForLanguageTag("en-Deva")
- )
- )
- }
+ )
}
@Test
- fun testNewUi_getDefaultKeyboardLayoutForInputDevice_withImeLanguageTagAndLayoutType() {
- NewSettingsApiFlag(true).use {
- assertCorrectLayout(
- keyboardDevice,
- createImeSubtypeForLanguageTagAndLayoutType("en-US", "qwerty"),
- ENGLISH_US_LAYOUT_DESCRIPTOR
+ fun testGetDefaultKeyboardLayoutForInputDevice_withImeLanguageTag() {
+ assertCorrectLayout(
+ keyboardDevice,
+ createImeSubtypeForLanguageTag("en-US"),
+ ENGLISH_US_LAYOUT_DESCRIPTOR
+ )
+ assertCorrectLayout(
+ keyboardDevice,
+ createImeSubtypeForLanguageTag("en-GB"),
+ ENGLISH_UK_LAYOUT_DESCRIPTOR
+ )
+ assertCorrectLayout(
+ keyboardDevice,
+ createImeSubtypeForLanguageTag("de"),
+ GERMAN_LAYOUT_DESCRIPTOR
+ )
+ assertCorrectLayout(
+ keyboardDevice,
+ createImeSubtypeForLanguageTag("fr-FR"),
+ createLayoutDescriptor("keyboard_layout_french")
+ )
+ assertCorrectLayout(
+ keyboardDevice,
+ createImeSubtypeForLanguageTag("ru"),
+ createLayoutDescriptor("keyboard_layout_russian")
+ )
+ assertEquals(
+ "getDefaultKeyboardLayoutForInputDevice should return " +
+ "KeyboardLayoutSelectionResult.FAILED when no layout available",
+ KeyboardLayoutSelectionResult.FAILED,
+ keyboardLayoutManager.getKeyboardLayoutForInputDevice(
+ keyboardDevice.identifier, USER_ID, imeInfo,
+ createImeSubtypeForLanguageTag("it")
)
- assertCorrectLayout(
- keyboardDevice,
- createImeSubtypeForLanguageTagAndLayoutType("en-US", "dvorak"),
- createLayoutDescriptor("keyboard_layout_english_us_dvorak")
- )
- // Try to match layout type even if country doesn't match
- assertCorrectLayout(
- keyboardDevice,
- createImeSubtypeForLanguageTagAndLayoutType("en-GB", "dvorak"),
- createLayoutDescriptor("keyboard_layout_english_us_dvorak")
- )
- // Choose layout based on layout type priority, if layout type is not provided by IME
- // (Qwerty > Dvorak > Extended)
- assertCorrectLayout(
- keyboardDevice,
- createImeSubtypeForLanguageTagAndLayoutType("en-US", ""),
- ENGLISH_US_LAYOUT_DESCRIPTOR
- )
- assertCorrectLayout(
- keyboardDevice,
- createImeSubtypeForLanguageTagAndLayoutType("en-GB", "qwerty"),
- ENGLISH_UK_LAYOUT_DESCRIPTOR
- )
- assertCorrectLayout(
- keyboardDevice,
- createImeSubtypeForLanguageTagAndLayoutType("de", "qwertz"),
- GERMAN_LAYOUT_DESCRIPTOR
- )
- // Wrong layout type should match with language if provided layout type not available
- assertCorrectLayout(
- keyboardDevice,
- createImeSubtypeForLanguageTagAndLayoutType("de", "qwerty"),
- GERMAN_LAYOUT_DESCRIPTOR
- )
- assertCorrectLayout(
- keyboardDevice,
- createImeSubtypeForLanguageTagAndLayoutType("fr-FR", "azerty"),
- createLayoutDescriptor("keyboard_layout_french")
- )
- assertCorrectLayout(
- keyboardDevice,
- createImeSubtypeForLanguageTagAndLayoutType("ru", "qwerty"),
- createLayoutDescriptor("keyboard_layout_russian_qwerty")
- )
- // If layout type is empty then prioritize KCM with empty layout type
- assertCorrectLayout(
- keyboardDevice,
- createImeSubtypeForLanguageTagAndLayoutType("ru", ""),
- createLayoutDescriptor("keyboard_layout_russian")
- )
- assertEquals("New UI: getDefaultKeyboardLayoutForInputDevice should return " +
+ )
+ assertEquals(
+ "getDefaultKeyboardLayoutForInputDevice should return " +
"KeyboardLayoutSelectionResult.FAILED when no layout for script code is" +
"available",
- KeyboardLayoutSelectionResult.FAILED,
- keyboardLayoutManager.getKeyboardLayoutForInputDevice(
- keyboardDevice.identifier, USER_ID, imeInfo,
- createImeSubtypeForLanguageTagAndLayoutType("en-Deva-US", "")
- )
+ KeyboardLayoutSelectionResult.FAILED,
+ keyboardLayoutManager.getKeyboardLayoutForInputDevice(
+ keyboardDevice.identifier, USER_ID, imeInfo,
+ createImeSubtypeForLanguageTag("en-Deva")
)
- }
+ )
}
@Test
- fun testNewUi_getDefaultKeyboardLayoutForInputDevice_withHwLanguageTagAndLayoutType() {
- NewSettingsApiFlag(true).use {
- val frenchSubtype = createImeSubtypeForLanguageTagAndLayoutType("fr", "azerty")
- // Should return English dvorak even if IME current layout is French, since HW says the
- // keyboard is a Dvorak keyboard
- assertCorrectLayout(
- englishDvorakKeyboardDevice,
- frenchSubtype,
- createLayoutDescriptor("keyboard_layout_english_us_dvorak")
+ fun testGetDefaultKeyboardLayoutForInputDevice_withImeLanguageTagAndLayoutType() {
+ assertCorrectLayout(
+ keyboardDevice,
+ createImeSubtypeForLanguageTagAndLayoutType("en-US", "qwerty"),
+ ENGLISH_US_LAYOUT_DESCRIPTOR
+ )
+ assertCorrectLayout(
+ keyboardDevice,
+ createImeSubtypeForLanguageTagAndLayoutType("en-US", "dvorak"),
+ createLayoutDescriptor("keyboard_layout_english_us_dvorak")
+ )
+ // Try to match layout type even if country doesn't match
+ assertCorrectLayout(
+ keyboardDevice,
+ createImeSubtypeForLanguageTagAndLayoutType("en-GB", "dvorak"),
+ createLayoutDescriptor("keyboard_layout_english_us_dvorak")
+ )
+ // Choose layout based on layout type priority, if layout type is not provided by IME
+ // (Qwerty > Dvorak > Extended)
+ assertCorrectLayout(
+ keyboardDevice,
+ createImeSubtypeForLanguageTagAndLayoutType("en-US", ""),
+ ENGLISH_US_LAYOUT_DESCRIPTOR
+ )
+ assertCorrectLayout(
+ keyboardDevice,
+ createImeSubtypeForLanguageTagAndLayoutType("en-GB", "qwerty"),
+ ENGLISH_UK_LAYOUT_DESCRIPTOR
+ )
+ assertCorrectLayout(
+ keyboardDevice,
+ createImeSubtypeForLanguageTagAndLayoutType("de", "qwertz"),
+ GERMAN_LAYOUT_DESCRIPTOR
+ )
+ // Wrong layout type should match with language if provided layout type not available
+ assertCorrectLayout(
+ keyboardDevice,
+ createImeSubtypeForLanguageTagAndLayoutType("de", "qwerty"),
+ GERMAN_LAYOUT_DESCRIPTOR
+ )
+ assertCorrectLayout(
+ keyboardDevice,
+ createImeSubtypeForLanguageTagAndLayoutType("fr-FR", "azerty"),
+ createLayoutDescriptor("keyboard_layout_french")
+ )
+ assertCorrectLayout(
+ keyboardDevice,
+ createImeSubtypeForLanguageTagAndLayoutType("ru", "qwerty"),
+ createLayoutDescriptor("keyboard_layout_russian_qwerty")
+ )
+ // If layout type is empty then prioritize KCM with empty layout type
+ assertCorrectLayout(
+ keyboardDevice,
+ createImeSubtypeForLanguageTagAndLayoutType("ru", ""),
+ createLayoutDescriptor("keyboard_layout_russian")
+ )
+ assertEquals("getDefaultKeyboardLayoutForInputDevice should return " +
+ "KeyboardLayoutSelectionResult.FAILED when no layout for script code is" +
+ "available",
+ KeyboardLayoutSelectionResult.FAILED,
+ keyboardLayoutManager.getKeyboardLayoutForInputDevice(
+ keyboardDevice.identifier, USER_ID, imeInfo,
+ createImeSubtypeForLanguageTagAndLayoutType("en-Deva-US", "")
)
+ )
+ }
- // Back to back changing HW keyboards with same product and vendor ID but different
- // language and layout type should configure the layouts correctly.
- assertCorrectLayout(
- englishQwertyKeyboardDevice,
- frenchSubtype,
- createLayoutDescriptor("keyboard_layout_english_us")
- )
+ @Test
+ fun testGetDefaultKeyboardLayoutForInputDevice_withHwLanguageTagAndLayoutType() {
+ val frenchSubtype = createImeSubtypeForLanguageTagAndLayoutType("fr", "azerty")
+ // Should return English dvorak even if IME current layout is French, since HW says the
+ // keyboard is a Dvorak keyboard
+ assertCorrectLayout(
+ englishDvorakKeyboardDevice,
+ frenchSubtype,
+ createLayoutDescriptor("keyboard_layout_english_us_dvorak")
+ )
- // Fallback to IME information if the HW provided layout script is incompatible with the
- // provided IME subtype
- assertCorrectLayout(
- englishDvorakKeyboardDevice,
- createImeSubtypeForLanguageTagAndLayoutType("ru", ""),
- createLayoutDescriptor("keyboard_layout_russian")
- )
- }
+ // Back to back changing HW keyboards with same product and vendor ID but different
+ // language and layout type should configure the layouts correctly.
+ assertCorrectLayout(
+ englishQwertyKeyboardDevice,
+ frenchSubtype,
+ createLayoutDescriptor("keyboard_layout_english_us")
+ )
+
+ // Fallback to IME information if the HW provided layout script is incompatible with the
+ // provided IME subtype
+ assertCorrectLayout(
+ englishDvorakKeyboardDevice,
+ createImeSubtypeForLanguageTagAndLayoutType("ru", ""),
+ createLayoutDescriptor("keyboard_layout_russian")
+ )
}
@Test
@@ -867,27 +559,25 @@
KeyboardLayoutManager.ImeInfo(0, imeInfo,
createImeSubtypeForLanguageTagAndLayoutType("de-Latn", "qwertz")))
Mockito.doReturn(imeInfos).`when`(keyboardLayoutManager).imeInfoListForLayoutMapping
- NewSettingsApiFlag(true).use {
- keyboardLayoutManager.onInputDeviceAdded(keyboardDevice.id)
- ExtendedMockito.verify {
- FrameworkStatsLog.write(
- ArgumentMatchers.eq(FrameworkStatsLog.KEYBOARD_CONFIGURED),
- ArgumentMatchers.anyBoolean(),
- ArgumentMatchers.eq(keyboardDevice.vendorId),
- ArgumentMatchers.eq(keyboardDevice.productId),
- ArgumentMatchers.eq(
- createByteArray(
- KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
- LAYOUT_TYPE_DEFAULT,
- GERMAN_LAYOUT_NAME,
- KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD,
- "de-Latn",
- LAYOUT_TYPE_QWERTZ
- ),
+ keyboardLayoutManager.onInputDeviceAdded(keyboardDevice.id)
+ ExtendedMockito.verify {
+ FrameworkStatsLog.write(
+ ArgumentMatchers.eq(FrameworkStatsLog.KEYBOARD_CONFIGURED),
+ ArgumentMatchers.anyBoolean(),
+ ArgumentMatchers.eq(keyboardDevice.vendorId),
+ ArgumentMatchers.eq(keyboardDevice.productId),
+ ArgumentMatchers.eq(
+ createByteArray(
+ KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
+ LAYOUT_TYPE_DEFAULT,
+ GERMAN_LAYOUT_NAME,
+ KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD,
+ "de-Latn",
+ LAYOUT_TYPE_QWERTZ
),
- ArgumentMatchers.eq(keyboardDevice.deviceBus),
- )
- }
+ ),
+ ArgumentMatchers.eq(keyboardDevice.deviceBus),
+ )
}
}
@@ -897,27 +587,25 @@
KeyboardLayoutManager.ImeInfo(0, imeInfo,
createImeSubtypeForLanguageTagAndLayoutType("de-Latn", "qwertz")))
Mockito.doReturn(imeInfos).`when`(keyboardLayoutManager).imeInfoListForLayoutMapping
- NewSettingsApiFlag(true).use {
- keyboardLayoutManager.onInputDeviceAdded(englishQwertyKeyboardDevice.id)
- ExtendedMockito.verify {
- FrameworkStatsLog.write(
- ArgumentMatchers.eq(FrameworkStatsLog.KEYBOARD_CONFIGURED),
- ArgumentMatchers.anyBoolean(),
- ArgumentMatchers.eq(englishQwertyKeyboardDevice.vendorId),
- ArgumentMatchers.eq(englishQwertyKeyboardDevice.productId),
- ArgumentMatchers.eq(
- createByteArray(
- "en",
- LAYOUT_TYPE_QWERTY,
- ENGLISH_US_LAYOUT_NAME,
- KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_DEVICE,
- "de-Latn",
- LAYOUT_TYPE_QWERTZ
- )
- ),
- ArgumentMatchers.eq(keyboardDevice.deviceBus),
- )
- }
+ keyboardLayoutManager.onInputDeviceAdded(englishQwertyKeyboardDevice.id)
+ ExtendedMockito.verify {
+ FrameworkStatsLog.write(
+ ArgumentMatchers.eq(FrameworkStatsLog.KEYBOARD_CONFIGURED),
+ ArgumentMatchers.anyBoolean(),
+ ArgumentMatchers.eq(englishQwertyKeyboardDevice.vendorId),
+ ArgumentMatchers.eq(englishQwertyKeyboardDevice.productId),
+ ArgumentMatchers.eq(
+ createByteArray(
+ "en",
+ LAYOUT_TYPE_QWERTY,
+ ENGLISH_US_LAYOUT_NAME,
+ KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_DEVICE,
+ "de-Latn",
+ LAYOUT_TYPE_QWERTZ
+ )
+ ),
+ ArgumentMatchers.eq(keyboardDevice.deviceBus),
+ )
}
}
@@ -925,27 +613,25 @@
fun testConfigurationLogged_onInputDeviceAdded_DefaultSelection() {
val imeInfos = listOf(KeyboardLayoutManager.ImeInfo(0, imeInfo, createImeSubtype()))
Mockito.doReturn(imeInfos).`when`(keyboardLayoutManager).imeInfoListForLayoutMapping
- NewSettingsApiFlag(true).use {
- keyboardLayoutManager.onInputDeviceAdded(keyboardDevice.id)
- ExtendedMockito.verify {
- FrameworkStatsLog.write(
- ArgumentMatchers.eq(FrameworkStatsLog.KEYBOARD_CONFIGURED),
- ArgumentMatchers.anyBoolean(),
- ArgumentMatchers.eq(keyboardDevice.vendorId),
- ArgumentMatchers.eq(keyboardDevice.productId),
- ArgumentMatchers.eq(
- createByteArray(
- KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
- LAYOUT_TYPE_DEFAULT,
- "Default",
- KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_DEFAULT,
- KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
- LAYOUT_TYPE_DEFAULT
- ),
+ keyboardLayoutManager.onInputDeviceAdded(keyboardDevice.id)
+ ExtendedMockito.verify {
+ FrameworkStatsLog.write(
+ ArgumentMatchers.eq(FrameworkStatsLog.KEYBOARD_CONFIGURED),
+ ArgumentMatchers.anyBoolean(),
+ ArgumentMatchers.eq(keyboardDevice.vendorId),
+ ArgumentMatchers.eq(keyboardDevice.productId),
+ ArgumentMatchers.eq(
+ createByteArray(
+ KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
+ LAYOUT_TYPE_DEFAULT,
+ "Default",
+ KeyboardLayoutSelectionResult.LAYOUT_SELECTION_CRITERIA_DEFAULT,
+ KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
+ LAYOUT_TYPE_DEFAULT
),
- ArgumentMatchers.eq(keyboardDevice.deviceBus),
- )
- }
+ ),
+ ArgumentMatchers.eq(keyboardDevice.deviceBus),
+ )
}
}
@@ -953,19 +639,17 @@
fun testConfigurationNotLogged_onInputDeviceChanged() {
val imeInfos = listOf(KeyboardLayoutManager.ImeInfo(0, imeInfo, createImeSubtype()))
Mockito.doReturn(imeInfos).`when`(keyboardLayoutManager).imeInfoListForLayoutMapping
- NewSettingsApiFlag(true).use {
- keyboardLayoutManager.onInputDeviceChanged(keyboardDevice.id)
- ExtendedMockito.verify({
- FrameworkStatsLog.write(
- ArgumentMatchers.eq(FrameworkStatsLog.KEYBOARD_CONFIGURED),
- ArgumentMatchers.anyBoolean(),
- ArgumentMatchers.anyInt(),
- ArgumentMatchers.anyInt(),
- ArgumentMatchers.any(ByteArray::class.java),
- ArgumentMatchers.anyInt(),
- )
- }, Mockito.times(0))
- }
+ keyboardLayoutManager.onInputDeviceChanged(keyboardDevice.id)
+ ExtendedMockito.verify({
+ FrameworkStatsLog.write(
+ ArgumentMatchers.eq(FrameworkStatsLog.KEYBOARD_CONFIGURED),
+ ArgumentMatchers.anyBoolean(),
+ ArgumentMatchers.anyInt(),
+ ArgumentMatchers.anyInt(),
+ ArgumentMatchers.any(ByteArray::class.java),
+ ArgumentMatchers.anyInt(),
+ )
+ }, Mockito.times(0))
}
@Test
@@ -975,18 +659,16 @@
Mockito.doReturn(false).`when`(keyboardLayoutManager).isVirtualDevice(
ArgumentMatchers.eq(keyboardDevice.id)
)
- NewSettingsApiFlag(true).use {
- keyboardLayoutManager.onInputDeviceChanged(keyboardDevice.id)
- ExtendedMockito.verify(
- notificationManager,
- Mockito.times(1)
- ).notifyAsUser(
- ArgumentMatchers.isNull(),
- ArgumentMatchers.anyInt(),
- ArgumentMatchers.any(),
- ArgumentMatchers.any()
- )
- }
+ keyboardLayoutManager.onInputDeviceChanged(keyboardDevice.id)
+ ExtendedMockito.verify(
+ notificationManager,
+ Mockito.times(1)
+ ).notifyAsUser(
+ ArgumentMatchers.isNull(),
+ ArgumentMatchers.anyInt(),
+ ArgumentMatchers.any(),
+ ArgumentMatchers.any()
+ )
}
@Test
@@ -996,18 +678,16 @@
Mockito.doReturn(true).`when`(keyboardLayoutManager).isVirtualDevice(
ArgumentMatchers.eq(keyboardDevice.id)
)
- NewSettingsApiFlag(true).use {
- keyboardLayoutManager.onInputDeviceChanged(keyboardDevice.id)
- ExtendedMockito.verify(
- notificationManager,
- Mockito.never()
- ).notifyAsUser(
- ArgumentMatchers.isNull(),
- ArgumentMatchers.anyInt(),
- ArgumentMatchers.any(),
- ArgumentMatchers.any()
- )
- }
+ keyboardLayoutManager.onInputDeviceChanged(keyboardDevice.id)
+ ExtendedMockito.verify(
+ notificationManager,
+ Mockito.never()
+ ).notifyAsUser(
+ ArgumentMatchers.isNull(),
+ ArgumentMatchers.anyInt(),
+ ArgumentMatchers.any(),
+ ArgumentMatchers.any()
+ )
}
private fun assertCorrectLayout(
@@ -1019,7 +699,7 @@
device.identifier, USER_ID, imeInfo, imeSubtype
)
assertEquals(
- "New UI: getDefaultKeyboardLayoutForInputDevice should return $expectedLayout",
+ "getDefaultKeyboardLayoutForInputDevice should return $expectedLayout",
expectedLayout,
result.layoutDescriptor
)
@@ -1123,21 +803,4 @@
info.serviceInfo.name = RECEIVER_NAME
return info
}
-
- private inner class NewSettingsApiFlag constructor(enabled: Boolean) : AutoCloseable {
- init {
- Settings.Global.putString(
- context.contentResolver,
- "settings_new_keyboard_ui", enabled.toString()
- )
- }
-
- override fun close() {
- Settings.Global.putString(
- context.contentResolver,
- "settings_new_keyboard_ui",
- ""
- )
- }
- }
}
diff --git a/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java b/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java
index b506d74..56845ae 100644
--- a/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java
+++ b/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java
@@ -21,10 +21,9 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
@@ -34,9 +33,7 @@
import android.hardware.usb.flags.Flags;
import android.os.RemoteException;
import android.os.UserManager;
-import android.platform.test.annotations.RequiresFlagsEnabled;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.platform.test.flag.junit.SetFlagsRule;
import androidx.test.runner.AndroidJUnit4;
@@ -64,7 +61,7 @@
@Mock
private UsbSettingsManager mUsbSettingsManager;
@Mock
- private IUsbOperationInternal mIUsbOperationInternal;
+ private IUsbOperationInternal mCallback;
private static final String TEST_PORT_ID = "123";
@@ -77,98 +74,105 @@
private UsbService mUsbService;
@Rule
- public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Before
public void setUp() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_USB_DATA_SIGNAL_STAKING);
MockitoAnnotations.initMocks(this);
- mUsbService = new UsbService(mContext, mUsbPortManager, mUsbAlsaManager, mUserManager,
- mUsbSettingsManager);
+
+ when(mUsbPortManager.enableUsbData(eq(TEST_PORT_ID), anyBoolean(), eq(TEST_TRANSACTION_ID),
+ eq(mCallback), any())).thenReturn(true);
+
+ mUsbService = new UsbService(mContext, mUsbPortManager, mUsbAlsaManager,
+ mUserManager, mUsbSettingsManager);
+ }
+
+ private void assertToggleUsbSuccessfully(int uid, boolean enable) {
+ assertTrue(mUsbService.enableUsbDataInternal(TEST_PORT_ID, enable,
+ TEST_TRANSACTION_ID, mCallback, uid));
+
+ verify(mUsbPortManager).enableUsbData(TEST_PORT_ID,
+ enable, TEST_TRANSACTION_ID, mCallback, null);
+ verifyZeroInteractions(mCallback);
+
+ clearInvocations(mUsbPortManager);
+ clearInvocations(mCallback);
+ }
+
+ private void assertToggleUsbFailed(int uid, boolean enable) throws Exception {
+ assertFalse(mUsbService.enableUsbDataInternal(TEST_PORT_ID, enable,
+ TEST_TRANSACTION_ID, mCallback, uid));
+
+ verifyZeroInteractions(mUsbPortManager);
+ verify(mCallback).onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+
+ clearInvocations(mUsbPortManager);
+ clearInvocations(mCallback);
}
/**
* Verify enableUsbData successfully disables USB port without error
*/
@Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_USB_DATA_SIGNAL_STAKING)
- public void usbPort_SuccessfullyDisabled() {
- boolean enableState = false;
- when(mUsbPortManager.enableUsbData(TEST_PORT_ID, enableState, TEST_TRANSACTION_ID,
- mIUsbOperationInternal, null)).thenReturn(true);
-
- assertTrue(mUsbService.enableUsbDataInternal(TEST_PORT_ID, enableState,
- TEST_TRANSACTION_ID, mIUsbOperationInternal, TEST_FIRST_CALLER_ID));
-
- verify(mUsbPortManager, times(1)).enableUsbData(TEST_PORT_ID,
- enableState, TEST_TRANSACTION_ID, mIUsbOperationInternal, null);
- verifyZeroInteractions(mIUsbOperationInternal);
+ public void disableUsb_successfullyDisable() {
+ assertToggleUsbSuccessfully(TEST_FIRST_CALLER_ID, false);
}
/**
* Verify enableUsbData successfully enables USB port without error given no other stakers
*/
@Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_USB_DATA_SIGNAL_STAKING)
- public void usbPortWhenNoOtherStakers_SuccessfullyEnabledUsb() {
- boolean enableState = true;
- when(mUsbPortManager.enableUsbData(TEST_PORT_ID, enableState, TEST_TRANSACTION_ID,
- mIUsbOperationInternal, null))
- .thenReturn(true);
-
- assertTrue(mUsbService.enableUsbDataInternal(TEST_PORT_ID, enableState,
- TEST_TRANSACTION_ID, mIUsbOperationInternal, TEST_FIRST_CALLER_ID));
- verifyZeroInteractions(mIUsbOperationInternal);
+ public void enableUsbWhenNoOtherStakers_successfullyEnable() {
+ assertToggleUsbSuccessfully(TEST_FIRST_CALLER_ID, true);
}
/**
* Verify enableUsbData does not enable USB port if other stakers are present
*/
@Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_USB_DATA_SIGNAL_STAKING)
- public void usbPortWithOtherStakers_DoesNotToEnableUsb() throws RemoteException {
- mUsbService.enableUsbDataInternal(TEST_PORT_ID, false, TEST_TRANSACTION_ID,
- mIUsbOperationInternal, TEST_FIRST_CALLER_ID);
- clearInvocations(mUsbPortManager);
+ public void enableUsbPortWithOtherStakers_failsToEnable() throws Exception {
+ assertToggleUsbSuccessfully(TEST_FIRST_CALLER_ID, false);
- assertFalse(mUsbService.enableUsbDataInternal(TEST_PORT_ID, true,
- TEST_TRANSACTION_ID, mIUsbOperationInternal, TEST_SECOND_CALLER_ID));
+ assertToggleUsbFailed(TEST_SECOND_CALLER_ID, true);
+ }
- verifyZeroInteractions(mUsbPortManager);
- verify(mIUsbOperationInternal).onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+ /**
+ * Verify enableUsbData successfully enables USB port when the last staker is removed
+ */
+ @Test
+ public void enableUsbByTheOnlyStaker_successfullyEnable() {
+ assertToggleUsbSuccessfully(TEST_FIRST_CALLER_ID, false);
+
+ assertToggleUsbSuccessfully(TEST_FIRST_CALLER_ID, true);
}
/**
* Verify enableUsbDataWhileDockedInternal does not enable USB port if other stakers are present
*/
@Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_USB_DATA_SIGNAL_STAKING)
- public void enableUsbWhileDockedWhenThereAreOtherStakers_DoesNotEnableUsb()
+ public void enableUsbWhileDockedWhenThereAreOtherStakers_failsToEnable()
throws RemoteException {
- mUsbService.enableUsbDataInternal(TEST_PORT_ID, false, TEST_TRANSACTION_ID,
- mIUsbOperationInternal, TEST_FIRST_CALLER_ID);
+ assertToggleUsbSuccessfully(TEST_FIRST_CALLER_ID, false);
- mUsbService.enableUsbDataWhileDockedInternal(TEST_PORT_ID, 0,
- mIUsbOperationInternal, TEST_SECOND_CALLER_ID);
+ mUsbService.enableUsbDataWhileDockedInternal(TEST_PORT_ID, TEST_TRANSACTION_ID,
+ mCallback, TEST_SECOND_CALLER_ID);
- verify(mUsbPortManager, never()).enableUsbDataWhileDocked(any(),
- anyLong(), any(), any());
- verify(mIUsbOperationInternal).onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
+ verifyZeroInteractions(mUsbPortManager);
+ verify(mCallback).onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
}
/**
- * Verify enableUsbDataWhileDockedInternal does enable USB port if other stakers are
+ * Verify enableUsbDataWhileDockedInternal does enable USB port if other stakers are
* not present
*/
@Test
- @RequiresFlagsEnabled(Flags.FLAG_ENABLE_USB_DATA_SIGNAL_STAKING)
- public void enableUsbWhileDockedWhenThereAreNoStakers_SuccessfullyEnableUsb()
- throws RemoteException {
+ public void enableUsbWhileDockedWhenThereAreNoStakers_SuccessfullyEnable() {
mUsbService.enableUsbDataWhileDockedInternal(TEST_PORT_ID, TEST_TRANSACTION_ID,
- mIUsbOperationInternal, TEST_SECOND_CALLER_ID);
+ mCallback, TEST_SECOND_CALLER_ID);
- verify(mUsbPortManager, times(1))
- .enableUsbDataWhileDocked(TEST_PORT_ID, TEST_TRANSACTION_ID,
- mIUsbOperationInternal, null);
- verifyZeroInteractions(mIUsbOperationInternal);
+ verify(mUsbPortManager).enableUsbDataWhileDocked(TEST_PORT_ID, TEST_TRANSACTION_ID,
+ mCallback, null);
+ verifyZeroInteractions(mCallback);
}
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java
index 22c3fd8..8c2186a 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabels.java
@@ -28,10 +28,18 @@
private final Long mVersion;
private final DataLabels mDataLabels;
+ private final SecurityLabels mSecurityLabels;
+ private final ThirdPartyVerification mThirdPartyVerification;
- public SafetyLabels(Long version, DataLabels dataLabels) {
+ public SafetyLabels(
+ Long version,
+ DataLabels dataLabels,
+ SecurityLabels securityLabels,
+ ThirdPartyVerification thirdPartyVerification) {
this.mVersion = version;
this.mDataLabels = dataLabels;
+ this.mSecurityLabels = securityLabels;
+ this.mThirdPartyVerification = thirdPartyVerification;
}
/** Returns the data label for the safety label */
@@ -54,6 +62,12 @@
if (mDataLabels != null) {
XmlUtils.appendChildren(safetyLabelsEle, mDataLabels.toOdDomElements(doc));
}
+ if (mSecurityLabels != null) {
+ XmlUtils.appendChildren(safetyLabelsEle, mSecurityLabels.toOdDomElements(doc));
+ }
+ if (mThirdPartyVerification != null) {
+ XmlUtils.appendChildren(safetyLabelsEle, mThirdPartyVerification.toOdDomElements(doc));
+ }
return XmlUtils.listOf(safetyLabelsEle);
}
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java
index 6bf8ef3..0f7aa81 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SafetyLabelsFactory.java
@@ -44,6 +44,22 @@
safetyLabelsEle,
XmlUtils.HR_TAG_DATA_LABELS,
false)));
- return new SafetyLabels(version, dataLabels);
+ SecurityLabels securityLabels =
+ new SecurityLabelsFactory()
+ .createFromHrElements(
+ XmlUtils.listOf(
+ XmlUtils.getSingleChildElement(
+ safetyLabelsEle,
+ XmlUtils.HR_TAG_SECURITY_LABELS,
+ false)));
+ ThirdPartyVerification thirdPartyVerification =
+ new ThirdPartyVerificationFactory()
+ .createFromHrElements(
+ XmlUtils.listOf(
+ XmlUtils.getSingleChildElement(
+ safetyLabelsEle,
+ XmlUtils.HR_TAG_THIRD_PARTY_VERIFICATION,
+ false)));
+ return new SafetyLabels(version, dataLabels, securityLabels, thirdPartyVerification);
}
}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabels.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabels.java
new file mode 100644
index 0000000..529b5036
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabels.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2024 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.asllib.marshallable;
+
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.util.List;
+
+/** Security Labels representation */
+public class SecurityLabels implements AslMarshallable {
+
+ private final Boolean mIsDataDeletable;
+ private final Boolean mIsDataEncrypted;
+
+ public SecurityLabels(Boolean isDataDeletable, Boolean isDataEncrypted) {
+ this.mIsDataDeletable = isDataDeletable;
+ this.mIsDataEncrypted = isDataEncrypted;
+ }
+
+ /** Creates an on-device DOM element from the {@link SecurityLabels}. */
+ @Override
+ public List<Element> toOdDomElements(Document doc) {
+ Element ele = XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_SECURITY_LABELS);
+ if (mIsDataDeletable != null) {
+ ele.appendChild(
+ XmlUtils.createOdBooleanEle(
+ doc, XmlUtils.OD_NAME_IS_DATA_DELETABLE, mIsDataDeletable));
+ }
+ if (mIsDataEncrypted != null) {
+ ele.appendChild(
+ XmlUtils.createOdBooleanEle(
+ doc, XmlUtils.OD_NAME_IS_DATA_ENCRYPTED, mIsDataEncrypted));
+ }
+ return XmlUtils.listOf(ele);
+ }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabelsFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabelsFactory.java
new file mode 100644
index 0000000..8402452
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/SecurityLabelsFactory.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 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.asllib.marshallable;
+
+import com.android.asllib.util.AslgenUtil;
+import com.android.asllib.util.MalformedXmlException;
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Element;
+
+import java.util.List;
+
+public class SecurityLabelsFactory implements AslMarshallableFactory<SecurityLabels> {
+
+ /** Creates a {@link SecurityLabels} from the human-readable DOM element. */
+ @Override
+ public SecurityLabels createFromHrElements(List<Element> elements)
+ throws MalformedXmlException {
+ Element ele = XmlUtils.getSingleElement(elements);
+ if (ele == null) {
+ AslgenUtil.logI("No SecurityLabels found in hr format.");
+ return null;
+ }
+ Boolean isDataDeletable =
+ XmlUtils.getBoolAttr(ele, XmlUtils.HR_ATTR_IS_DATA_DELETABLE, false);
+ Boolean isDataEncrypted =
+ XmlUtils.getBoolAttr(ele, XmlUtils.HR_ATTR_IS_DATA_ENCRYPTED, false);
+ return new SecurityLabels(isDataDeletable, isDataEncrypted);
+ }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerification.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerification.java
new file mode 100644
index 0000000..a1b22f8
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerification.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 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.asllib.marshallable;
+
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.util.List;
+
+/** ThirdPartyVerification representation. */
+public class ThirdPartyVerification implements AslMarshallable {
+
+ private final String mUrl;
+
+ public ThirdPartyVerification(String url) {
+ this.mUrl = url;
+ }
+
+ /** Creates an on-device DOM element from the {@link ThirdPartyVerification}. */
+ @Override
+ public List<Element> toOdDomElements(Document doc) {
+ Element ele =
+ XmlUtils.createPbundleEleWithName(doc, XmlUtils.OD_NAME_THIRD_PARTY_VERIFICATION);
+ ele.appendChild(XmlUtils.createOdStringEle(doc, XmlUtils.OD_NAME_URL, mUrl));
+ return XmlUtils.listOf(ele);
+ }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerificationFactory.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerificationFactory.java
new file mode 100644
index 0000000..c3e4964
--- /dev/null
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/marshallable/ThirdPartyVerificationFactory.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2024 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.asllib.marshallable;
+
+import com.android.asllib.util.AslgenUtil;
+import com.android.asllib.util.MalformedXmlException;
+import com.android.asllib.util.XmlUtils;
+
+import org.w3c.dom.Element;
+
+import java.util.List;
+
+public class ThirdPartyVerificationFactory
+ implements AslMarshallableFactory<ThirdPartyVerification> {
+
+ /** Creates a {@link ThirdPartyVerification} from the human-readable DOM element. */
+ @Override
+ public ThirdPartyVerification createFromHrElements(List<Element> elements)
+ throws MalformedXmlException {
+ Element ele = XmlUtils.getSingleElement(elements);
+ if (ele == null) {
+ AslgenUtil.logI("No ThirdPartyVerification found in hr format.");
+ return null;
+ }
+
+ String url = XmlUtils.getStringAttr(ele, XmlUtils.HR_ATTR_URL);
+ return new ThirdPartyVerification(url);
+ }
+}
diff --git a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java
index 691f92f..ed3d7f8 100644
--- a/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java
+++ b/tools/app_metadata_bundles/src/lib/java/com/android/asllib/util/XmlUtils.java
@@ -32,6 +32,8 @@
public static final String HR_TAG_DEVELOPER_INFO = "developer-info";
public static final String HR_TAG_APP_INFO = "app-info";
public static final String HR_TAG_DATA_LABELS = "data-labels";
+ public static final String HR_TAG_SECURITY_LABELS = "security-labels";
+ public static final String HR_TAG_THIRD_PARTY_VERIFICATION = "third-party-verification";
public static final String HR_TAG_DATA_ACCESSED = "data-accessed";
public static final String HR_TAG_DATA_COLLECTED = "data-collected";
public static final String HR_TAG_DATA_SHARED = "data-shared";
@@ -46,6 +48,8 @@
public static final String HR_ATTR_DATA_TYPE = "dataType";
public static final String HR_ATTR_IS_COLLECTION_OPTIONAL = "isCollectionOptional";
public static final String HR_ATTR_IS_SHARING_OPTIONAL = "isSharingOptional";
+ public static final String HR_ATTR_IS_DATA_DELETABLE = "isDataDeletable";
+ public static final String HR_ATTR_IS_DATA_ENCRYPTED = "isDataEncrypted";
public static final String HR_ATTR_EPHEMERAL = "ephemeral";
public static final String HR_ATTR_PURPOSES = "purposes";
public static final String HR_ATTR_VERSION = "version";
@@ -98,6 +102,8 @@
public static final String OD_NAME_VERSION = "version";
public static final String OD_NAME_URL = "url";
public static final String OD_NAME_SYSTEM_APP_SAFETY_LABEL = "system_app_safety_label";
+ public static final String OD_NAME_SECURITY_LABELS = "security_labels";
+ public static final String OD_NAME_THIRD_PARTY_VERIFICATION = "third_party_verification";
public static final String OD_NAME_DATA_LABELS = "data_labels";
public static final String OD_NAME_DATA_ACCESSED = "data_accessed";
public static final String OD_NAME_DATA_COLLECTED = "data_collected";
@@ -105,6 +111,8 @@
public static final String OD_NAME_PURPOSES = "purposes";
public static final String OD_NAME_IS_COLLECTION_OPTIONAL = "is_collection_optional";
public static final String OD_NAME_IS_SHARING_OPTIONAL = "is_sharing_optional";
+ public static final String OD_NAME_IS_DATA_DELETABLE = "is_data_deletable";
+ public static final String OD_NAME_IS_DATA_ENCRYPTED = "is_data_encrypted";
public static final String OD_NAME_EPHEMERAL = "ephemeral";
public static final String TRUE_STR = "true";
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/AllTests.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AllTests.java
index 03e8ac6..54c80f6 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/AllTests.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AllTests.java
@@ -17,9 +17,15 @@
package com.android.asllib;
import com.android.asllib.marshallable.AndroidSafetyLabelTest;
+import com.android.asllib.marshallable.AppInfoTest;
import com.android.asllib.marshallable.DataCategoryTest;
import com.android.asllib.marshallable.DataLabelsTest;
import com.android.asllib.marshallable.DeveloperInfoTest;
+import com.android.asllib.marshallable.SafetyLabelsTest;
+import com.android.asllib.marshallable.SecurityLabelsTest;
+import com.android.asllib.marshallable.SystemAppSafetyLabelTest;
+import com.android.asllib.marshallable.ThirdPartyVerificationTest;
+import com.android.asllib.marshallable.TransparencyInfoTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@@ -28,8 +34,14 @@
@Suite.SuiteClasses({
AslgenTests.class,
AndroidSafetyLabelTest.class,
- DeveloperInfoTest.class,
+ AppInfoTest.class,
DataCategoryTest.class,
DataLabelsTest.class,
+ DeveloperInfoTest.class,
+ SafetyLabelsTest.class,
+ SecurityLabelsTest.class,
+ SystemAppSafetyLabelTest.class,
+ ThirdPartyVerificationTest.class,
+ TransparencyInfoTest.class
})
public class AllTests {}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java
index 5f43008..e2588d7 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/AslgenTests.java
@@ -34,7 +34,8 @@
@RunWith(JUnit4.class)
public class AslgenTests {
private static final String VALID_MAPPINGS_PATH = "com/android/asllib/validmappings";
- private static final List<String> VALID_MAPPINGS_SUBDIRS = List.of("location", "contacts");
+ private static final List<String> VALID_MAPPINGS_SUBDIRS =
+ List.of("location", "contacts", "general");
private static final String HR_XML_FILENAME = "hr.xml";
private static final String OD_XML_FILENAME = "od.xml";
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java
index b62620e..c52d6c8 100644
--- a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SafetyLabelsTest.java
@@ -32,6 +32,9 @@
private static final String MISSING_VERSION_FILE_NAME = "missing-version.xml";
private static final String VALID_EMPTY_FILE_NAME = "valid-empty.xml";
private static final String WITH_DATA_LABELS_FILE_NAME = "with-data-labels.xml";
+ private static final String WITH_SECURITY_LABELS_FILE_NAME = "with-security-labels.xml";
+ private static final String WITH_THIRD_PARTY_VERIFICATION_FILE_NAME =
+ "with-third-party-verification.xml";
private Document mDoc = null;
@@ -62,6 +65,20 @@
testHrToOdSafetyLabels(WITH_DATA_LABELS_FILE_NAME);
}
+ /** Test for safety labels with security labels. */
+ @Test
+ public void testSafetyLabelsWithSecurityLabels() throws Exception {
+ System.out.println("starting testSafetyLabelsWithSecurityLabels.");
+ testHrToOdSafetyLabels(WITH_SECURITY_LABELS_FILE_NAME);
+ }
+
+ /** Test for safety labels with third party verification. */
+ @Test
+ public void testSafetyLabelsWithThirdPartyVerification() throws Exception {
+ System.out.println("starting testSafetyLabelsWithThirdPartyVerification.");
+ testHrToOdSafetyLabels(WITH_THIRD_PARTY_VERIFICATION_FILE_NAME);
+ }
+
private void hrToOdExpectException(String fileName) {
TestUtils.hrToOdExpectException(new SafetyLabelsFactory(), SAFETY_LABELS_HR_PATH, fileName);
}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SecurityLabelsTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SecurityLabelsTest.java
new file mode 100644
index 0000000..c0d0d72
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/SecurityLabelsTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2017 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.asllib.marshallable;
+
+
+import com.android.asllib.testutils.TestUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.w3c.dom.Document;
+
+import java.nio.file.Paths;
+import java.util.List;
+
+@RunWith(JUnit4.class)
+public class SecurityLabelsTest {
+ private static final String SECURITY_LABELS_HR_PATH = "com/android/asllib/securitylabels/hr";
+ private static final String SECURITY_LABELS_OD_PATH = "com/android/asllib/securitylabels/od";
+
+ public static final List<String> OPTIONAL_FIELD_NAMES =
+ List.of("isDataDeletable", "isDataEncrypted");
+
+ private static final String ALL_FIELDS_VALID_FILE_NAME = "all-fields-valid.xml";
+
+ private Document mDoc = null;
+
+ /** Logic for setting up tests (empty if not yet needed). */
+ public static void main(String[] params) throws Exception {}
+
+ @Before
+ public void setUp() throws Exception {
+ System.out.println("set up.");
+ mDoc = TestUtils.document();
+ }
+
+ /** Test for all fields valid. */
+ @Test
+ public void testAllFieldsValid() throws Exception {
+ System.out.println("starting testAllFieldsValid.");
+ testHrToOdSecurityLabels(ALL_FIELDS_VALID_FILE_NAME);
+ }
+
+ /** Tests missing optional fields passes. */
+ @Test
+ public void testMissingOptionalFields() throws Exception {
+ for (String optField : OPTIONAL_FIELD_NAMES) {
+ var ele =
+ TestUtils.getElementsFromResource(
+ Paths.get(SECURITY_LABELS_HR_PATH, ALL_FIELDS_VALID_FILE_NAME));
+ ele.get(0).removeAttribute(optField);
+ SecurityLabels securityLabels = new SecurityLabelsFactory().createFromHrElements(ele);
+ securityLabels.toOdDomElements(mDoc);
+ }
+ }
+
+ private void testHrToOdSecurityLabels(String fileName) throws Exception {
+ TestUtils.testHrToOd(
+ mDoc,
+ new SecurityLabelsFactory(),
+ SECURITY_LABELS_HR_PATH,
+ SECURITY_LABELS_OD_PATH,
+ fileName);
+ }
+}
diff --git a/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/ThirdPartyVerificationTest.java b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/ThirdPartyVerificationTest.java
new file mode 100644
index 0000000..ab8e85c
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/java/com/android/asllib/marshallable/ThirdPartyVerificationTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017 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.asllib.marshallable;
+
+import com.android.asllib.testutils.TestUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.w3c.dom.Document;
+
+@RunWith(JUnit4.class)
+public class ThirdPartyVerificationTest {
+ private static final String THIRD_PARTY_VERIFICATION_HR_PATH =
+ "com/android/asllib/thirdpartyverification/hr";
+ private static final String THIRD_PARTY_VERIFICATION_OD_PATH =
+ "com/android/asllib/thirdpartyverification/od";
+
+ private static final String VALID_FILE_NAME = "valid.xml";
+ private static final String MISSING_URL_FILE_NAME = "missing-url.xml";
+
+ private Document mDoc = null;
+
+ /** Logic for setting up tests (empty if not yet needed). */
+ public static void main(String[] params) throws Exception {}
+
+ @Before
+ public void setUp() throws Exception {
+ System.out.println("set up.");
+ mDoc = TestUtils.document();
+ }
+
+ /** Test for valid. */
+ @Test
+ public void testValid() throws Exception {
+ System.out.println("starting testValid.");
+ testHrToOdThirdPartyVerification(VALID_FILE_NAME);
+ }
+
+ /** Tests missing url. */
+ @Test
+ public void testMissingUrl() throws Exception {
+ System.out.println("starting testMissingUrl.");
+ hrToOdExpectException(MISSING_URL_FILE_NAME);
+ }
+
+ private void hrToOdExpectException(String fileName) {
+ TestUtils.hrToOdExpectException(
+ new ThirdPartyVerificationFactory(), THIRD_PARTY_VERIFICATION_HR_PATH, fileName);
+ }
+
+ private void testHrToOdThirdPartyVerification(String fileName) throws Exception {
+ TestUtils.testHrToOd(
+ mDoc,
+ new ThirdPartyVerificationFactory(),
+ THIRD_PARTY_VERIFICATION_HR_PATH,
+ THIRD_PARTY_VERIFICATION_OD_PATH,
+ fileName);
+ }
+}
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-security-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-security-labels.xml
new file mode 100644
index 0000000..940e48a
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-security-labels.xml
@@ -0,0 +1,6 @@
+<safety-labels version="12345">
+ <security-labels
+ isDataDeletable="true"
+ isDataEncrypted="false"
+ />
+</safety-labels>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-third-party-verification.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-third-party-verification.xml
new file mode 100644
index 0000000..bfbc5ae
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/hr/with-third-party-verification.xml
@@ -0,0 +1,4 @@
+<safety-labels version="12345">
+<third-party-verification url="www.example.com">
+ </third-party-verification>
+</safety-labels>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-security-labels.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-security-labels.xml
new file mode 100644
index 0000000..b39c562b
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-security-labels.xml
@@ -0,0 +1,7 @@
+<pbundle_as_map name="safety_labels">
+ <long name="version" value="12345"/>
+ <pbundle_as_map name="security_labels">
+ <boolean name="is_data_deletable" value="true" />
+ <boolean name="is_data_encrypted" value="false" />
+ </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-third-party-verification.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-third-party-verification.xml
new file mode 100644
index 0000000..10653ff
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/safetylabels/od/with-third-party-verification.xml
@@ -0,0 +1,6 @@
+<pbundle_as_map name="safety_labels">
+ <long name="version" value="12345"/>
+ <pbundle_as_map name="third_party_verification">
+ <string name="url" value="www.example.com"/>
+ </pbundle_as_map>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/securitylabels/hr/all-fields-valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/securitylabels/hr/all-fields-valid.xml
new file mode 100644
index 0000000..e2fb592
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/securitylabels/hr/all-fields-valid.xml
@@ -0,0 +1,4 @@
+<security-labels
+ isDataDeletable="true"
+ isDataEncrypted="false">
+</security-labels>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/securitylabels/od/all-fields-valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/securitylabels/od/all-fields-valid.xml
new file mode 100644
index 0000000..7b2f656
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/securitylabels/od/all-fields-valid.xml
@@ -0,0 +1,4 @@
+<pbundle_as_map name="security_labels">
+ <boolean name="is_data_deletable" value="true" />
+ <boolean name="is_data_encrypted" value="false" />
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/thirdpartyverification/hr/missing-url.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/thirdpartyverification/hr/missing-url.xml
new file mode 100644
index 0000000..6738ac2
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/thirdpartyverification/hr/missing-url.xml
@@ -0,0 +1 @@
+<third-party-verification></third-party-verification>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/thirdpartyverification/hr/valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/thirdpartyverification/hr/valid.xml
new file mode 100644
index 0000000..2a664f2
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/thirdpartyverification/hr/valid.xml
@@ -0,0 +1 @@
+<third-party-verification url="www.example.com"></third-party-verification>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/thirdpartyverification/od/valid.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/thirdpartyverification/od/valid.xml
new file mode 100644
index 0000000..dbeb592
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/thirdpartyverification/od/valid.xml
@@ -0,0 +1,3 @@
+<pbundle_as_map name="third_party_verification">
+ <string name="url" value="www.example.com"/>
+</pbundle_as_map>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml
new file mode 100644
index 0000000..36beb93
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/hr.xml
@@ -0,0 +1,35 @@
+<app-metadata-bundles version="123">
+ <system-app-safety-label url="www.example.com">
+ </system-app-safety-label>
+ <safety-labels version="12345">
+ <data-labels>
+ <data-shared dataCategory="location"
+ dataType="approx_location"
+ isSharingOptional="false"
+ ephemeral="false"
+ purposes="app_functionality" />
+ <data-shared dataCategory="location"
+ dataType="precise_location"
+ isSharingOptional="true"
+ ephemeral="true"
+ purposes="app_functionality|analytics" />
+ </data-labels>
+ <security-labels
+ isDataDeletable="true"
+ isDataEncrypted="false"
+ />
+ <third-party-verification url="www.example.com">
+ </third-party-verification>
+ </safety-labels>
+ <transparency-info>
+ <developer-info
+ name="max"
+ email="max@example.com"
+ address="111 blah lane"
+ countryRegion="US"
+ relationship="aosp"
+ website="example.com"
+ appDeveloperRegistryId="registry_id" />
+ <app-info title="beervision" description="a beer app" containsAds="true" obeyAps="false" adsFingerprinting="false" securityFingerprinting="false" privacyPolicy="www.example.com" securityEndpoints="url1|url2|url3" firstPartyEndpoints="url1" serviceProviderEndpoints="url55|url56" category="Food and drink" email="max@maxloh.com" />
+ </transparency-info>
+</app-metadata-bundles>
\ No newline at end of file
diff --git a/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml
new file mode 100644
index 0000000..db21280
--- /dev/null
+++ b/tools/app_metadata_bundles/src/test/resources/com/android/asllib/validmappings/general/od.xml
@@ -0,0 +1,70 @@
+<bundle>
+ <long name="version" value="123"/>
+ <pbundle_as_map name="safety_labels">
+ <long name="version" value="12345"/>
+ <pbundle_as_map name="data_labels">
+ <pbundle_as_map name="data_shared">
+ <pbundle_as_map name="location">
+ <pbundle_as_map name="approx_location">
+ <int-array name="purposes" num="1">
+ <item value="1"/>
+ </int-array>
+ <boolean name="is_sharing_optional" value="false"/>
+ <boolean name="ephemeral" value="false"/>
+ </pbundle_as_map>
+ <pbundle_as_map name="precise_location">
+ <int-array name="purposes" num="2">
+ <item value="1"/>
+ <item value="2"/>
+ </int-array>
+ <boolean name="is_sharing_optional" value="true"/>
+ <boolean name="ephemeral" value="true"/>
+ </pbundle_as_map>
+ </pbundle_as_map>
+ </pbundle_as_map>
+ </pbundle_as_map>
+ <pbundle_as_map name="security_labels">
+ <boolean name="is_data_deletable" value="true"/>
+ <boolean name="is_data_encrypted" value="false"/>
+ </pbundle_as_map>
+ <pbundle_as_map name="third_party_verification">
+ <string name="url" value="www.example.com"/>
+ </pbundle_as_map>
+ </pbundle_as_map>
+ <pbundle_as_map name="system_app_safety_label">
+ <string name="url" value="www.example.com"/>
+ </pbundle_as_map>
+ <pbundle_as_map name="transparency_info">
+ <pbundle_as_map name="developer_info">
+ <string name="name" value="max"/>
+ <string name="email" value="max@example.com"/>
+ <string name="address" value="111 blah lane"/>
+ <string name="country_region" value="US"/>
+ <long name="relationship" value="5"/>
+ <string name="website" value="example.com"/>
+ </pbundle_as_map>
+ <pbundle_as_map name="app_info">
+ <string name="title" value="beervision"/>
+ <string name="description" value="a beer app"/>
+ <boolean name="contains_ads" value="true"/>
+ <boolean name="obey_aps" value="false"/>
+ <boolean name="ads_fingerprinting" value="false"/>
+ <boolean name="security_fingerprinting" value="false"/>
+ <string name="privacy_policy" value="www.example.com"/>
+ <string-array name="security_endpoint" num="3">
+ <item value="url1"/>
+ <item value="url2"/>
+ <item value="url3"/>
+ </string-array>
+ <string-array name="first_party_endpoint" num="1">
+ <item value="url1"/>
+ </string-array>
+ <string-array name="service_provider_endpoint" num="2">
+ <item value="url55"/>
+ <item value="url56"/>
+ </string-array>
+ <string name="category" value="Food and drink"/>
+ <string name="email" value="max@maxloh.com"/>
+ </pbundle_as_map>
+ </pbundle_as_map>
+</bundle>
\ No newline at end of file
diff --git a/wifi/wifi.aconfig b/wifi/wifi.aconfig
index 3c734bc..6c4e4c3 100644
--- a/wifi/wifi.aconfig
+++ b/wifi/wifi.aconfig
@@ -1,5 +1,4 @@
package: "android.net.wifi.flags"
-container: "system"
flag {
name: "get_device_cross_akm_roaming_support"