Merge "Introduce NICViewModel#isDozing and #isVisible" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index c30164c..003b7f8 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -42,6 +42,7 @@
":android.credentials.flags-aconfig-java{.generated_srcjars}",
":android.view.contentprotection.flags-aconfig-java{.generated_srcjars}",
":android.service.voice.flags-aconfig-java{.generated_srcjars}",
+ ":android.service.autofill.flags-aconfig-java{.generated_srcjars}",
]
filegroup {
@@ -416,3 +417,19 @@
aconfig_declarations: "android.service.voice.flags-aconfig",
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+
+// Autofill
+aconfig_declarations {
+ name: "android.service.autofill.flags-aconfig",
+ package: "android.service.autofill",
+ srcs: [
+ "services/autofill/bugfixes.aconfig",
+ "services/autofill/features.aconfig"
+ ],
+}
+
+java_aconfig_library {
+ name: "android.service.autofill.flags-aconfig-java",
+ aconfig_declarations: "android.service.autofill.flags-aconfig",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
diff --git a/apex/jobscheduler/service/Android.bp b/apex/jobscheduler/service/Android.bp
index a4a0b4b..887f7fe 100644
--- a/apex/jobscheduler/service/Android.bp
+++ b/apex/jobscheduler/service/Android.bp
@@ -13,6 +13,10 @@
name: "service-jobscheduler",
installable: true,
+ defaults: [
+ "service-jobscheduler-aconfig-libraries",
+ ],
+
srcs: [
"java/**/*.java",
":framework-jobscheduler-shared-srcs",
diff --git a/apex/jobscheduler/service/aconfig/Android.bp b/apex/jobscheduler/service/aconfig/Android.bp
new file mode 100644
index 0000000..24ecd3d
--- /dev/null
+++ b/apex/jobscheduler/service/aconfig/Android.bp
@@ -0,0 +1,29 @@
+// JobScheduler
+aconfig_declarations {
+ name: "service-job.flags-aconfig",
+ package: "com.android.server.job",
+ srcs: [
+ "job.aconfig",
+ ],
+}
+
+java_aconfig_library {
+ name: "service-jobscheduler-job.flags-aconfig-java",
+ aconfig_declarations: "service-job.flags-aconfig",
+ defaults: ["framework-minus-apex-aconfig-java-defaults"],
+ visibility: ["//frameworks/base:__subpackages__"],
+}
+
+service_jobscheduler_aconfig_srcjars = [
+ ":service-jobscheduler-job.flags-aconfig-java{.generated_srcjars}",
+]
+
+// Aconfig declarations and libraries for the core framework
+java_defaults {
+ name: "service-jobscheduler-aconfig-libraries",
+ // Add java_aconfig_libraries to here to add them to the core framework
+ srcs: service_jobscheduler_aconfig_srcjars,
+ // Add aconfig-annotations-lib as a dependency for the optimization
+ libs: ["aconfig-annotations-lib"],
+ visibility: ["//frameworks/base:__subpackages__"],
+}
diff --git a/apex/jobscheduler/service/aconfig/job.aconfig b/apex/jobscheduler/service/aconfig/job.aconfig
new file mode 100644
index 0000000..4e3cb7d
--- /dev/null
+++ b/apex/jobscheduler/service/aconfig/job.aconfig
@@ -0,0 +1,8 @@
+package: "com.android.server.job"
+
+flag {
+ name: "relax_prefetch_connectivity_constraint_only_on_charger"
+ namespace: "backstagepower"
+ description: "Only relax a prefetch job's connectivity constraint when the device is charging"
+ bug: "299329948"
+}
\ No newline at end of file
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index f252a0b..158d914 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -1030,6 +1030,12 @@
"light_idle_to_initial_flex";
private static final String KEY_LIGHT_IDLE_TIMEOUT_MAX_FLEX = "light_max_idle_to_flex";
private static final String KEY_LIGHT_IDLE_FACTOR = "light_idle_factor";
+ private static final String KEY_LIGHT_IDLE_INCREASE_LINEARLY =
+ "light_idle_increase_linearly";
+ private static final String KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS =
+ "light_idle_linear_increase_factor_ms";
+ private static final String KEY_LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS =
+ "light_idle_flex_linear_increase_factor_ms";
private static final String KEY_LIGHT_MAX_IDLE_TIMEOUT = "light_max_idle_to";
private static final String KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET =
"light_idle_maintenance_min_budget";
@@ -1079,6 +1085,10 @@
private long mDefaultLightIdleTimeoutMaxFlex =
!COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L;
private float mDefaultLightIdleFactor = 2f;
+ private boolean mDefaultLightIdleIncreaseLinearly;
+ private long mDefaultLightIdleLinearIncreaseFactorMs = mDefaultLightIdleTimeout;
+ private long mDefaultLightIdleFlexLinearIncreaseFactorMs =
+ mDefaultLightIdleTimeoutInitialFlex;
private long mDefaultLightMaxIdleTimeout =
!COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L;
private long mDefaultLightIdleMaintenanceMinBudget =
@@ -1174,6 +1184,37 @@
public float LIGHT_IDLE_FACTOR = mDefaultLightIdleFactor;
/**
+ * Whether to increase the light idle mode time linearly or exponentially.
+ * If true, will increase linearly
+ * (i.e. {@link #LIGHT_IDLE_TIMEOUT} + x * {@link #LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS}).
+ * If false, will increase by exponentially
+ * (i.e. {@link #LIGHT_IDLE_TIMEOUT} * ({@link #LIGHT_IDLE_FACTOR} ^ x)).
+ * This will also impact how the light idle flex value
+ * ({@link #LIGHT_IDLE_TIMEOUT_INITIAL_FLEX}) is increased (using
+ * {@link #LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS} for the linear increase)..
+ *
+ * @see #KEY_LIGHT_IDLE_INCREASE_LINEARLY
+ */
+ public boolean LIGHT_IDLE_INCREASE_LINEARLY = mDefaultLightIdleIncreaseLinearly;
+
+ /**
+ * Amount of time to increase the light idle time by, if increasing it linearly.
+ *
+ * @see #KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS
+ * @see #LIGHT_IDLE_INCREASE_LINEARLY
+ */
+ public long LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS = mDefaultLightIdleLinearIncreaseFactorMs;
+
+ /**
+ * Amount of time to increase the light idle flex time by, if increasing it linearly.
+ *
+ * @see #KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS
+ * @see #LIGHT_IDLE_INCREASE_LINEARLY
+ */
+ public long LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS =
+ mDefaultLightIdleFlexLinearIncreaseFactorMs;
+
+ /**
* This is the maximum time we will stay in light idle mode.
*
* @see #KEY_LIGHT_MAX_IDLE_TIMEOUT
@@ -1409,6 +1450,16 @@
mDefaultLightIdleTimeoutMaxFlex);
mDefaultLightIdleFactor = res.getFloat(
com.android.internal.R.integer.device_idle_light_idle_factor);
+ mDefaultLightIdleIncreaseLinearly = res.getBoolean(
+ com.android.internal.R.bool.device_idle_light_idle_increase_linearly);
+ mDefaultLightIdleLinearIncreaseFactorMs = getTimeout(res.getInteger(
+ com.android.internal.R.integer
+ .device_idle_light_idle_linear_increase_factor_ms),
+ mDefaultLightIdleLinearIncreaseFactorMs);
+ mDefaultLightIdleFlexLinearIncreaseFactorMs = getTimeout(res.getInteger(
+ com.android.internal.R.integer
+ .device_idle_light_idle_flex_linear_increase_factor_ms),
+ mDefaultLightIdleFlexLinearIncreaseFactorMs);
mDefaultLightMaxIdleTimeout = getTimeout(
res.getInteger(com.android.internal.R.integer.device_idle_light_max_idle_to_ms),
mDefaultLightMaxIdleTimeout);
@@ -1487,6 +1538,9 @@
LIGHT_IDLE_TIMEOUT_INITIAL_FLEX = mDefaultLightIdleTimeoutInitialFlex;
LIGHT_IDLE_TIMEOUT_MAX_FLEX = mDefaultLightIdleTimeoutMaxFlex;
LIGHT_IDLE_FACTOR = mDefaultLightIdleFactor;
+ LIGHT_IDLE_INCREASE_LINEARLY = mDefaultLightIdleIncreaseLinearly;
+ LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS = mDefaultLightIdleLinearIncreaseFactorMs;
+ LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS = mDefaultLightIdleFlexLinearIncreaseFactorMs;
LIGHT_MAX_IDLE_TIMEOUT = mDefaultLightMaxIdleTimeout;
LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mDefaultLightIdleMaintenanceMinBudget;
LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mDefaultLightIdleMaintenanceMaxBudget;
@@ -1556,6 +1610,21 @@
LIGHT_IDLE_FACTOR = Math.max(1, properties.getFloat(
KEY_LIGHT_IDLE_FACTOR, mDefaultLightIdleFactor));
break;
+ case KEY_LIGHT_IDLE_INCREASE_LINEARLY:
+ LIGHT_IDLE_INCREASE_LINEARLY = properties.getBoolean(
+ KEY_LIGHT_IDLE_INCREASE_LINEARLY,
+ mDefaultLightIdleIncreaseLinearly);
+ break;
+ case KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS:
+ LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS = properties.getLong(
+ KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS,
+ mDefaultLightIdleLinearIncreaseFactorMs);
+ break;
+ case KEY_LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS:
+ LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS = properties.getLong(
+ KEY_LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS,
+ mDefaultLightIdleFlexLinearIncreaseFactorMs);
+ break;
case KEY_LIGHT_MAX_IDLE_TIMEOUT:
LIGHT_MAX_IDLE_TIMEOUT = properties.getLong(
KEY_LIGHT_MAX_IDLE_TIMEOUT, mDefaultLightMaxIdleTimeout);
@@ -1716,6 +1785,20 @@
pw.print(LIGHT_IDLE_FACTOR);
pw.println();
+ pw.print(" "); pw.print(KEY_LIGHT_IDLE_INCREASE_LINEARLY); pw.print("=");
+ pw.print(LIGHT_IDLE_INCREASE_LINEARLY);
+ pw.println();
+
+ pw.print(" "); pw.print(KEY_LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS);
+ pw.print("=");
+ pw.print(LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS);
+ pw.println();
+
+ pw.print(" "); pw.print(KEY_LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS);
+ pw.print("=");
+ pw.print(LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS);
+ pw.println();
+
pw.print(" "); pw.print(KEY_LIGHT_MAX_IDLE_TIMEOUT); pw.print("=");
TimeUtils.formatDuration(LIGHT_MAX_IDLE_TIMEOUT, pw);
pw.println();
@@ -3694,10 +3777,18 @@
}
mMaintenanceStartTime = 0;
scheduleLightAlarmLocked(mNextLightIdleDelay, mNextLightIdleDelayFlex, true);
- mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT,
- (long) (mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR));
- mNextLightIdleDelayFlex = Math.min(mConstants.LIGHT_IDLE_TIMEOUT_MAX_FLEX,
- (long) (mNextLightIdleDelayFlex * mConstants.LIGHT_IDLE_FACTOR));
+ if (!mConstants.LIGHT_IDLE_INCREASE_LINEARLY) {
+ mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT,
+ (long) (mNextLightIdleDelay * mConstants.LIGHT_IDLE_FACTOR));
+ mNextLightIdleDelayFlex = Math.min(mConstants.LIGHT_IDLE_TIMEOUT_MAX_FLEX,
+ (long) (mNextLightIdleDelayFlex * mConstants.LIGHT_IDLE_FACTOR));
+ } else {
+ mNextLightIdleDelay = Math.min(mConstants.LIGHT_MAX_IDLE_TIMEOUT,
+ mNextLightIdleDelay + mConstants.LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS);
+ mNextLightIdleDelayFlex = Math.min(mConstants.LIGHT_IDLE_TIMEOUT_MAX_FLEX,
+ mNextLightIdleDelayFlex
+ + mConstants.LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS);
+ }
moveToLightStateLocked(LIGHT_STATE_IDLE, reason);
addEvent(EVENT_LIGHT_IDLE, null);
mGoingIdleWakeLock.acquire();
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
index 6d938de..45f15db 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
@@ -22,6 +22,8 @@
import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
+import static com.android.server.job.Flags.FLAG_RELAX_PREFETCH_CONNECTIVITY_CONSTRAINT_ONLY_ON_CHARGER;
+import static com.android.server.job.Flags.relaxPrefetchConnectivityConstraintOnlyOnCharger;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -929,6 +931,11 @@
// Need to at least know the estimated download bytes for a prefetch job.
return false;
}
+ if (relaxPrefetchConnectivityConstraintOnlyOnCharger()) {
+ if (!mService.isBatteryCharging()) {
+ return false;
+ }
+ }
// See if we match after relaxing any unmetered request
final NetworkCapabilities.Builder builder =
@@ -1735,6 +1742,14 @@
Predicate<JobStatus> predicate) {
final long nowElapsed = sElapsedRealtimeClock.millis();
+ pw.println("Aconfig flags:");
+ pw.increaseIndent();
+ pw.print(FLAG_RELAX_PREFETCH_CONNECTIVITY_CONSTRAINT_ONLY_ON_CHARGER,
+ relaxPrefetchConnectivityConstraintOnlyOnCharger());
+ pw.println();
+ pw.decreaseIndent();
+ pw.println();
+
if (mRequestedWhitelistJobs.size() > 0) {
pw.print("Requested standby exceptions:");
for (int i = 0; i < mRequestedWhitelistJobs.size(); i++) {
diff --git a/api/Android.bp b/api/Android.bp
index 45e70719..222275f 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -82,7 +82,6 @@
"framework-media",
"framework-mediaprovider",
"framework-ondevicepersonalization",
- "framework-pdf",
"framework-permission",
"framework-permission-s",
"framework-scheduling",
diff --git a/api/javadoc-lint-baseline b/api/javadoc-lint-baseline
index 8713126..762d9d1 100644
--- a/api/javadoc-lint-baseline
+++ b/api/javadoc-lint-baseline
@@ -291,76 +291,6 @@
android/view/inspector/PropertyReader.java:141: lint: Unresolved link/see tag "android.annotation.ColorInt ColorInt" in android.view.inspector.PropertyReader [101]
android/window/BackEvent.java:24: lint: Unresolved link/see tag "android.window.BackMotionEvent BackMotionEvent" in android.window.BackEvent [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_30" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_35" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_40" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_45" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_50" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_55" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_60" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_65" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_70" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_75" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_80" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_85" in android [101]
-com/android/server/wm/CompatModePackages.java:92: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_90" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_30" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_35" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_40" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_45" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_50" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_55" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_60" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_65" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_70" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_75" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_80" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_85" in android [101]
-com/android/server/wm/CompatModePackages.java:122: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_90" in android [101]
-com/android/server/wm/CompatModePackages.java:135: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:135: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:135: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_90" in android [101]
-com/android/server/wm/CompatModePackages.java:148: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:148: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:148: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_85" in android [101]
-com/android/server/wm/CompatModePackages.java:161: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:161: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:161: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_80" in android [101]
-com/android/server/wm/CompatModePackages.java:174: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:174: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:174: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_75" in android [101]
-com/android/server/wm/CompatModePackages.java:187: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:187: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:187: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_70" in android [101]
-com/android/server/wm/CompatModePackages.java:200: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:200: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:200: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_65" in android [101]
-com/android/server/wm/CompatModePackages.java:213: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:213: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:213: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_60" in android [101]
-com/android/server/wm/CompatModePackages.java:226: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:226: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:226: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_55" in android [101]
-com/android/server/wm/CompatModePackages.java:239: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:239: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:239: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_50" in android [101]
-com/android/server/wm/CompatModePackages.java:252: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:252: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:252: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_45" in android [101]
-com/android/server/wm/CompatModePackages.java:265: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:265: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:265: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_40" in android [101]
-com/android/server/wm/CompatModePackages.java:278: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:278: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:278: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_35" in android [101]
-com/android/server/wm/CompatModePackages.java:291: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED" in android [101]
-com/android/server/wm/CompatModePackages.java:291: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALED_INVERSE" in android [101]
-com/android/server/wm/CompatModePackages.java:291: lint: Unresolved link/see tag "CompatModePackages#DOWNSCALE_30" in android [101]
-
android/net/wifi/SoftApConfiguration.java:173: lint: Unresolved link/see tag "android.net.wifi.SoftApConfiguration.Builder#setShutdownTimeoutMillis(long)" in android.net.wifi.SoftApConfiguration [101]
android/content/pm/ActivityInfo.java:1197: lint: Unresolved link/see tag "android.view.ViewRootImpl" in android.content.pm.ActivityInfo [101]
android/os/UserManager.java:2384: lint: Unresolved link/see tag "android.annotation.UserHandleAware @UserHandleAware" in android.os.UserManager [101]
diff --git a/core/api/current.txt b/core/api/current.txt
index 96a9595..d037c31 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -18539,8 +18539,10 @@
ctor public BiometricPrompt.CryptoObject(@NonNull javax.crypto.Mac);
ctor @Deprecated public BiometricPrompt.CryptoObject(@NonNull android.security.identity.IdentityCredential);
ctor public BiometricPrompt.CryptoObject(@NonNull android.security.identity.PresentationSession);
+ ctor @FlaggedApi("android.hardware.biometrics.add_key_agreement_crypto_object") public BiometricPrompt.CryptoObject(@NonNull javax.crypto.KeyAgreement);
method public javax.crypto.Cipher getCipher();
method @Deprecated @Nullable public android.security.identity.IdentityCredential getIdentityCredential();
+ method @FlaggedApi("android.hardware.biometrics.add_key_agreement_crypto_object") @Nullable public javax.crypto.KeyAgreement getKeyAgreement();
method public javax.crypto.Mac getMac();
method @Nullable public android.security.identity.PresentationSession getPresentationSession();
method public java.security.Signature getSignature();
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 358c8e7..a99eeb0 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3946,7 +3946,7 @@
field public static final int DELETE_FAILED_OWNER_BLOCKED = -4; // 0xfffffffc
field public static final int DELETE_KEEP_DATA = 1; // 0x1
field public static final int DELETE_SUCCEEDED = 1; // 0x1
- field public static final String EXTRA_REQUEST_PERMISSIONS_DEVICE_ID = "android.content.pm.extra.REQUEST_PERMISSIONS_DEVICE_ID";
+ field @FlaggedApi("android.permission.flags.device_aware_permission_apis") public static final String EXTRA_REQUEST_PERMISSIONS_DEVICE_ID = "android.content.pm.extra.REQUEST_PERMISSIONS_DEVICE_ID";
field public static final String EXTRA_REQUEST_PERMISSIONS_LEGACY_ACCESS_PERMISSION_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_LEGACY_ACCESS_PERMISSION_NAMES";
field public static final String EXTRA_REQUEST_PERMISSIONS_NAMES = "android.content.pm.extra.REQUEST_PERMISSIONS_NAMES";
field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS";
diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java
index 7b3d017..d15c79f 100644
--- a/core/java/android/app/ApplicationExitInfo.java
+++ b/core/java/android/app/ApplicationExitInfo.java
@@ -468,6 +468,15 @@
*/
public static final int SUBREASON_EXCESSIVE_BINDER_OBJECTS = 29;
+ /**
+ * The process was killed by the [kernel] Out-of-memory (OOM) killer; this
+ * would be set only when the reason is {@link #REASON_LOW_MEMORY}.
+ *
+ * For internal use only.
+ * @hide
+ */
+ public static final int SUBREASON_OOM_KILL = 30;
+
// If there is any OEM code which involves additional app kill reasons, it should
// be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000.
@@ -644,6 +653,7 @@
SUBREASON_PACKAGE_UPDATE,
SUBREASON_UNDELIVERED_BROADCAST,
SUBREASON_EXCESSIVE_BINDER_OBJECTS,
+ SUBREASON_OOM_KILL,
})
@Retention(RetentionPolicy.SOURCE)
public @interface SubReason {}
@@ -1371,6 +1381,8 @@
return "UNDELIVERED BROADCAST";
case SUBREASON_EXCESSIVE_BINDER_OBJECTS:
return "EXCESSIVE BINDER OBJECTS";
+ case SUBREASON_OOM_KILL:
+ return "OOM KILL";
default:
return "UNKNOWN";
}
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 2fb428b..a84845a 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -240,6 +240,12 @@
public static final int MESSAGE_REQUEST_PERMISSION_RESTORE = 0x63826983; // ?RES
/**
+ * The length limit of Association tag.
+ * @hide
+ */
+ private static final int ASSOCIATION_TAG_LENGTH_LIMIT = 100;
+
+ /**
* Callback for applications to receive updates about and the outcome of
* {@link AssociationRequest} issued via {@code associate()} call.
*
@@ -1409,7 +1415,7 @@
/**
* Sets the {@link AssociationInfo#getTag() tag} for this association.
*
- * <p>The length of the tag must be at most 20 characters.
+ * <p>The length of the tag must be at most 100 characters to save disk space.
*
* <p>This allows to store useful information about the associated devices.
*
@@ -1421,8 +1427,8 @@
public void setAssociationTag(int associationId, @NonNull String tag) {
Objects.requireNonNull(tag, "tag cannot be null");
- if (tag.length() > 20) {
- throw new IllegalArgumentException("Length of the tag must be at most 20 characters");
+ if (tag.length() > ASSOCIATION_TAG_LENGTH_LIMIT) {
+ throw new IllegalArgumentException("Length of the tag must be at most 100 characters");
}
try {
diff --git a/core/java/android/companion/virtualnative/OWNERS b/core/java/android/companion/virtualnative/OWNERS
new file mode 100644
index 0000000..2968104
--- /dev/null
+++ b/core/java/android/companion/virtualnative/OWNERS
@@ -0,0 +1 @@
+include /services/companion/java/com/android/server/companion/virtual/OWNERS
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 3fc515d..8fbe50c3 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -4802,6 +4802,7 @@
* @hide
*/
@SystemApi
+ @FlaggedApi(android.permission.flags.Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS)
public static final String EXTRA_REQUEST_PERMISSIONS_DEVICE_ID =
"android.content.pm.extra.REQUEST_PERMISSIONS_DEVICE_ID";
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index ea0f049..3e12a1a 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -13,3 +13,10 @@
description: "Bind wallpaper service on its own thread instead of system_server's main handler during a user switch."
bug: "302100344"
}
+
+flag {
+ name: "support_communal_profile"
+ namespace: "multiuser"
+ description: "Framework support for communal profile."
+ bug: "285426179"
+}
diff --git a/core/java/android/credentials/GetCandidateCredentialsResponse.java b/core/java/android/credentials/GetCandidateCredentialsResponse.java
index 231e4bc..1b130a9 100644
--- a/core/java/android/credentials/GetCandidateCredentialsResponse.java
+++ b/core/java/android/credentials/GetCandidateCredentialsResponse.java
@@ -53,6 +53,15 @@
mCandidateProviderDataList = new ArrayList<>(candidateProviderDataList);
}
+ /**
+ * Returns candidate provider data list.
+ *
+ * @hide
+ */
+ public List<GetCredentialProviderData> getCandidateProviderDataList() {
+ return mCandidateProviderDataList;
+ }
+
protected GetCandidateCredentialsResponse(Parcel in) {
List<GetCredentialProviderData> candidateProviderDataList = new ArrayList<>();
in.readTypedList(candidateProviderDataList, GetCredentialProviderData.CREATOR);
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index af448f0..490ff64 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -20,8 +20,10 @@
import static android.Manifest.permission.USE_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.hardware.biometrics.BiometricManager.Authenticators;
+import static android.hardware.biometrics.Flags.FLAG_ADD_KEY_AGREEMENT_CRYPTO_OBJECT;
import android.annotation.CallbackExecutor;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -53,6 +55,7 @@
import java.util.concurrent.Executor;
import javax.crypto.Cipher;
+import javax.crypto.KeyAgreement;
import javax.crypto.Mac;
/**
@@ -748,7 +751,7 @@
* A wrapper class for the cryptographic operations supported by BiometricPrompt.
*
* <p>Currently the framework supports {@link Signature}, {@link Cipher}, {@link Mac},
- * {@link IdentityCredential}, and {@link PresentationSession}.
+ * {@link IdentityCredential}, {@link PresentationSession} and {@link KeyAgreement}.
*
* <p>Cryptographic operations in Android can be split into two categories: auth-per-use and
* time-based. This is specified during key creation via the timeout parameter of the
@@ -793,6 +796,11 @@
super(session);
}
+ @FlaggedApi(FLAG_ADD_KEY_AGREEMENT_CRYPTO_OBJECT)
+ public CryptoObject(@NonNull KeyAgreement keyAgreement) {
+ super(keyAgreement);
+ }
+
/**
* Get {@link Signature} object.
* @return {@link Signature} object or null if this doesn't contain one.
@@ -834,6 +842,15 @@
public @Nullable PresentationSession getPresentationSession() {
return super.getPresentationSession();
}
+
+ /**
+ * Get {@link KeyAgreement} object.
+ * @return {@link KeyAgreement} object or null if this doesn't contain one.
+ */
+ @FlaggedApi(FLAG_ADD_KEY_AGREEMENT_CRYPTO_OBJECT)
+ public @Nullable KeyAgreement getKeyAgreement() {
+ return super.getKeyAgreement();
+ }
}
/**
diff --git a/core/java/android/hardware/biometrics/CryptoObject.java b/core/java/android/hardware/biometrics/CryptoObject.java
index 267ef36..151f819 100644
--- a/core/java/android/hardware/biometrics/CryptoObject.java
+++ b/core/java/android/hardware/biometrics/CryptoObject.java
@@ -16,6 +16,9 @@
package android.hardware.biometrics;
+import static android.hardware.biometrics.Flags.FLAG_ADD_KEY_AGREEMENT_CRYPTO_OBJECT;
+
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.security.identity.IdentityCredential;
import android.security.identity.PresentationSession;
@@ -24,6 +27,7 @@
import java.security.Signature;
import javax.crypto.Cipher;
+import javax.crypto.KeyAgreement;
import javax.crypto.Mac;
/**
@@ -62,6 +66,11 @@
mCrypto = session;
}
+ @FlaggedApi(FLAG_ADD_KEY_AGREEMENT_CRYPTO_OBJECT)
+ public CryptoObject(@NonNull KeyAgreement keyAgreement) {
+ mCrypto = keyAgreement;
+ }
+
/**
* Get {@link Signature} object.
* @return {@link Signature} object or null if this doesn't contain one.
@@ -105,6 +114,15 @@
}
/**
+ * Get {@link PresentationSession} object.
+ * @return {@link PresentationSession} object or null if this doesn't contain one.
+ */
+ @FlaggedApi(FLAG_ADD_KEY_AGREEMENT_CRYPTO_OBJECT)
+ public KeyAgreement getKeyAgreement() {
+ return mCrypto instanceof KeyAgreement ? (KeyAgreement) mCrypto : null;
+ }
+
+ /**
* @hide
* @return the opId associated with this object or 0 if none
*/
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index f594377..5bfda70 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -24,12 +24,14 @@
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.Manifest.permission.USE_FINGERPRINT;
import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_LOCKOUT_NONE;
+import static android.hardware.biometrics.Flags.FLAG_ADD_KEY_AGREEMENT_CRYPTO_OBJECT;
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_POWER_BUTTON;
import static com.android.internal.util.FrameworkStatsLog.AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_FINGERPRINT_MANAGER_AUTHENTICATE;
import static com.android.internal.util.FrameworkStatsLog.AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_FINGERPRINT_MANAGER_HAS_ENROLLED_FINGERPRINTS;
import static com.android.internal.util.FrameworkStatsLog.AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_FINGERPRINT_MANAGER_IS_HARDWARE_DETECTED;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -76,6 +78,7 @@
import java.util.concurrent.Executor;
import javax.crypto.Cipher;
+import javax.crypto.KeyAgreement;
import javax.crypto.Mac;
/**
@@ -312,6 +315,16 @@
public PresentationSession getPresentationSession() {
return super.getPresentationSession();
}
+
+ /**
+ * Get {@link KeyAgreement} object.
+ * @return {@link KeyAgreement} object or null if this doesn't contain one.
+ * @hide
+ */
+ @FlaggedApi(FLAG_ADD_KEY_AGREEMENT_CRYPTO_OBJECT)
+ public KeyAgreement getKeyAgreement() {
+ return super.getKeyAgreement();
+ }
}
/**
diff --git a/core/java/android/hardware/input/KeyboardLayout.java b/core/java/android/hardware/input/KeyboardLayout.java
index bbfed24..883f157 100644
--- a/core/java/android/hardware/input/KeyboardLayout.java
+++ b/core/java/android/hardware/input/KeyboardLayout.java
@@ -82,8 +82,8 @@
DVORAK(4, LAYOUT_TYPE_DVORAK),
COLEMAK(5, LAYOUT_TYPE_COLEMAK),
WORKMAN(6, LAYOUT_TYPE_WORKMAN),
- TURKISH_F(7, LAYOUT_TYPE_TURKISH_F),
- TURKISH_Q(8, LAYOUT_TYPE_TURKISH_Q),
+ TURKISH_Q(7, LAYOUT_TYPE_TURKISH_Q),
+ TURKISH_F(8, LAYOUT_TYPE_TURKISH_F),
EXTENDED(9, LAYOUT_TYPE_EXTENDED);
private final int mValue;
diff --git a/core/java/android/os/OomKillRecord.java b/core/java/android/os/OomKillRecord.java
new file mode 100644
index 0000000..151a65f
--- /dev/null
+++ b/core/java/android/os/OomKillRecord.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2023 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;
+
+
+/**
+ * Expected data to get back from the OOM event's file.
+ * Note that this should be equivalent to the struct <b>OomKill</b> inside
+ * <pre>
+ * system/memory/libmeminfo/libmemevents/include/memevents.h
+ * </pre>
+ *
+ * @hide
+ */
+public final class OomKillRecord {
+ private long mTimeStampInMillis;
+ private int mPid;
+ private int mUid;
+ private String mProcessName;
+ private short mOomScoreAdj;
+
+ public OomKillRecord(long timeStampInMillis, int pid, int uid,
+ String processName, short oomScoreAdj) {
+ this.mTimeStampInMillis = timeStampInMillis;
+ this.mPid = pid;
+ this.mUid = uid;
+ this.mProcessName = processName;
+ this.mOomScoreAdj = oomScoreAdj;
+ }
+
+ public long getTimestampMilli() {
+ return mTimeStampInMillis;
+ }
+
+ public int getPid() {
+ return mPid;
+ }
+
+ public int getUid() {
+ return mUid;
+ }
+
+ public String getProcessName() {
+ return mProcessName;
+ }
+
+ public short getOomScoreAdj() {
+ return mOomScoreAdj;
+ }
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b414ed4..36d3180 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -11607,6 +11607,45 @@
"accessibility_magnification_joystick_enabled";
/**
+ * Controls magnification enable gesture. Accessibility magnification can have one or more
+ * enable gestures.
+ *
+ * @see #ACCESSIBILITY_MAGNIFICATION_GESTURE_NONE
+ * @see #ACCESSIBILITY_MAGNIFICATION_GESTURE_SINGLE_FINGER_TRIPLE_TAP
+ * @see #ACCESSIBILITY_MAGNIFICATION_GESTURE_TWO_FINGER_TRIPLE_TAP
+ * @hide
+ */
+ public static final String ACCESSIBILITY_MAGNIFICATION_GESTURE =
+ "accessibility_magnification_gesture";
+
+ /**
+ * Magnification enable gesture value that is a default value.
+ * @hide
+ */
+ public static final int ACCESSIBILITY_MAGNIFICATION_GESTURE_NONE = 0x0;
+
+ /**
+ * Magnification enable gesture value is single finger triple tap.
+ * @hide
+ */
+ public static final int ACCESSIBILITY_MAGNIFICATION_GESTURE_SINGLE_FINGER_TRIPLE_TAP = 0x1;
+
+ /**
+ * Magnification enable gesture value is two finger triple tap.
+ * @hide
+ */
+ public static final int ACCESSIBILITY_MAGNIFICATION_GESTURE_TWO_FINGER_TRIPLE_TAP = 0x2;
+
+ /**
+ * Magnification enable gesture values include single finger triple tap and two finger
+ * triple tap.
+ * @hide
+ */
+ public static final int ACCESSIBILITY_MAGNIFICATION_GESTURE_ALL =
+ ACCESSIBILITY_MAGNIFICATION_GESTURE_SINGLE_FINGER_TRIPLE_TAP
+ | ACCESSIBILITY_MAGNIFICATION_GESTURE_TWO_FINGER_TRIPLE_TAP;
+
+ /**
* Controls magnification capability. Accessibility magnification is capable of at least one
* of the magnification modes.
*
diff --git a/core/java/android/service/credentials/CredentialProviderService.java b/core/java/android/service/credentials/CredentialProviderService.java
index be7b722..a2b0a66 100644
--- a/core/java/android/service/credentials/CredentialProviderService.java
+++ b/core/java/android/service/credentials/CredentialProviderService.java
@@ -153,6 +153,18 @@
public static final String EXTRA_BEGIN_GET_CREDENTIAL_REQUEST =
"android.service.credentials.extra.BEGIN_GET_CREDENTIAL_REQUEST";
+ /**
+ * The key to autofillId associated with the requested credential option and the corresponding
+ * credential entry. The associated autofillId will be contained inside the candidate query
+ * bundle of {@link android.credentials.CredentialOption} if requested through the
+ * {@link com.android.credentialmanager.autofill.CredentialAutofillService}. The resulting
+ * credential entry will contain the autofillId inside its framework extras intent.
+ *
+ * @hide
+ */
+ public static final String EXTRA_AUTOFILL_ID =
+ "android.service.credentials.extra.AUTOFILL_ID";
+
private static final String TAG = "CredProviderService";
/**
diff --git a/core/java/android/view/IRecentsAnimationController.aidl b/core/java/android/view/IRecentsAnimationController.aidl
index c4d3070..a150187 100644
--- a/core/java/android/view/IRecentsAnimationController.aidl
+++ b/core/java/android/view/IRecentsAnimationController.aidl
@@ -23,6 +23,8 @@
import android.window.PictureInPictureSurfaceTransaction;
import android.window.TaskSnapshot;
+import com.android.internal.os.IResultReceiver;
+
/**
* Passed to the {@link IRecentsAnimationRunner} in order for the runner to control to let the
* runner control certain aspects of the recents animation, and to notify window manager when the
@@ -58,7 +60,7 @@
* top resumed app, false otherwise.
*/
@UnsupportedAppUsage
- void finish(boolean moveHomeToTop, boolean sendUserLeaveHint);
+ void finish(boolean moveHomeToTop, boolean sendUserLeaveHint, in IResultReceiver finishCb);
/**
* Called by the handler to indicate that the recents animation input consumer should be
diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java
index 2761aae..45b3fdd 100644
--- a/core/java/android/view/InputWindowHandle.java
+++ b/core/java/android/view/InputWindowHandle.java
@@ -16,6 +16,8 @@
package android.view;
+import static com.android.window.flags.Flags.surfaceTrustedOverlay;
+
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.graphics.Matrix;
@@ -35,7 +37,6 @@
* @hide
*/
public final class InputWindowHandle {
-
/**
* An internal annotation for all the {@link android.os.InputConfig} flags that can be
* specified to {@link #inputConfig} to control the behavior of an input window. Only the
@@ -59,7 +60,6 @@
InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER,
InputConfig.IS_WALLPAPER,
InputConfig.PAUSE_DISPATCHING,
- InputConfig.TRUSTED_OVERLAY,
InputConfig.WATCH_OUTSIDE_TOUCH,
InputConfig.SLIPPERY,
InputConfig.DISABLE_USER_ACTIVITY,
@@ -272,4 +272,13 @@
}
this.inputConfig &= ~inputConfig;
}
+
+ public void setTrustedOverlay(SurfaceControl.Transaction t, SurfaceControl sc,
+ boolean isTrusted) {
+ if (surfaceTrustedOverlay()) {
+ t.setTrustedOverlay(sc, isTrusted);
+ } else if (isTrusted) {
+ inputConfig |= InputConfig.TRUSTED_OVERLAY;
+ }
+ }
}
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index effc127..57b19a8 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -407,7 +407,7 @@
public @Nullable SurfacePackage getSurfacePackage() {
if (mSurfaceControl != null && mAccessibilityEmbeddedConnection != null) {
return new SurfacePackage(new SurfaceControl(mSurfaceControl, "getSurfacePackage"),
- mAccessibilityEmbeddedConnection, getFocusGrantToken(), mRemoteInterface);
+ mAccessibilityEmbeddedConnection, getInputTransferToken(), mRemoteInterface);
} else {
return null;
}
@@ -526,10 +526,12 @@
}
/**
+ * Returns an input token used which can be used to request focus on the embedded surface.
+ *
* @hide
*/
- public IBinder getFocusGrantToken() {
- return mWm.getFocusGrantToken(getWindowToken().asBinder());
+ public IBinder getInputTransferToken() {
+ return mWm.getInputTransferToken(getWindowToken().asBinder());
}
private void addWindowToken(WindowManager.LayoutParams attrs) {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index e64274e..2f4bea0 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1850,6 +1850,8 @@
to = "PHONE"),
@ViewDebug.IntToString(from = TYPE_SYSTEM_ALERT,
to = "SYSTEM_ALERT"),
+ @ViewDebug.IntToString(from = TYPE_KEYGUARD,
+ to = "KEYGUARD"),
@ViewDebug.IntToString(from = TYPE_TOAST,
to = "TOAST"),
@ViewDebug.IntToString(from = TYPE_SYSTEM_OVERLAY,
@@ -1898,6 +1900,8 @@
to = "PRIVATE_PRESENTATION"),
@ViewDebug.IntToString(from = TYPE_VOICE_INTERACTION,
to = "VOICE_INTERACTION"),
+ @ViewDebug.IntToString(from = TYPE_ACCESSIBILITY_OVERLAY,
+ to = "ACCESSIBILITY_OVERLAY"),
@ViewDebug.IntToString(from = TYPE_VOICE_INTERACTION_STARTING,
to = "VOICE_INTERACTION_STARTING"),
@ViewDebug.IntToString(from = TYPE_DOCK_DIVIDER,
@@ -1907,7 +1911,13 @@
@ViewDebug.IntToString(from = TYPE_SCREENSHOT,
to = "SCREENSHOT"),
@ViewDebug.IntToString(from = TYPE_APPLICATION_OVERLAY,
- to = "APPLICATION_OVERLAY")
+ to = "APPLICATION_OVERLAY"),
+ @ViewDebug.IntToString(from = TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY,
+ to = "ACCESSIBILITY_MAGNIFICATION_OVERLAY"),
+ @ViewDebug.IntToString(from = TYPE_NOTIFICATION_SHADE,
+ to = "NOTIFICATION_SHADE"),
+ @ViewDebug.IntToString(from = TYPE_STATUS_BAR_ADDITIONAL,
+ to = "STATUS_BAR_ADDITIONAL")
})
@WindowType
public int type;
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 7d3d283..8fe9b7b 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -58,7 +58,7 @@
SurfaceControl mLeash;
Rect mFrame;
Rect mAttachedFrame;
- IBinder mFocusGrantToken;
+ IBinder mInputTransferToken;
State(SurfaceControl sc, WindowManager.LayoutParams p, int displayId, IWindow client,
SurfaceControl leash, Rect frame) {
@@ -89,7 +89,7 @@
private final Configuration mConfiguration;
private final IWindowSession mRealWm;
private final IBinder mHostInputToken;
- private final IBinder mFocusGrantToken = new Binder();
+ private final IBinder mInputTransferToken = new Binder();
private InsetsState mInsetsState;
private final ClientWindowFrames mTmpFrames = new ClientWindowFrames();
private final MergedConfiguration mTmpConfig = new MergedConfiguration();
@@ -109,17 +109,17 @@
mConfiguration.setTo(configuration);
}
- IBinder getFocusGrantToken(IBinder window) {
+ IBinder getInputTransferToken(IBinder window) {
synchronized (this) {
// This can only happen if someone requested the focusGrantToken before setView was
// called for the SCVH. In that case, use the root focusGrantToken since this will be
// the same token sent to WMS for the root window once setView is called.
if (mStateForWindow.isEmpty()) {
- return mFocusGrantToken;
+ return mInputTransferToken;
}
State state = mStateForWindow.get(window);
if (state != null) {
- return state.mFocusGrantToken;
+ return state.mInputTransferToken;
}
}
@@ -207,9 +207,9 @@
// Give the first window the mFocusGrantToken since that's the token the host can use
// to give focus to the embedded.
if (mStateForWindow.isEmpty()) {
- state.mFocusGrantToken = mFocusGrantToken;
+ state.mInputTransferToken = mInputTransferToken;
} else {
- state.mFocusGrantToken = new Binder();
+ state.mInputTransferToken = new Binder();
}
mStateForWindow.put(window.asBinder(), state);
@@ -230,12 +230,13 @@
new SurfaceControl(sc, "WindowlessWindowManager.addToDisplay"),
window, mHostInputToken, attrs.flags, attrs.privateFlags,
attrs.inputFeatures, attrs.type,
- attrs.token, state.mFocusGrantToken, attrs.getTitle().toString(),
+ attrs.token, state.mInputTransferToken, attrs.getTitle().toString(),
outInputChannel);
} else {
mRealWm.grantInputChannel(displayId, sc, window, mHostInputToken, attrs.flags,
attrs.privateFlags, attrs.inputFeatures, attrs.type, attrs.token,
- state.mFocusGrantToken, attrs.getTitle().toString(), outInputChannel);
+ state.mInputTransferToken, attrs.getTitle().toString(),
+ outInputChannel);
}
state.mInputChannelToken =
outInputChannel != null ? outInputChannel.getToken() : null;
diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
index a0d5800..e31ad82 100644
--- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
+++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
@@ -4,5 +4,5 @@
namespace: "accessibility"
name: "force_invert_color"
description: "Enable force force-dark for smart inversion and dark theme everywhere"
- bug: "239594271"
+ bug: "282821643"
}
\ 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
new file mode 100644
index 0000000..1b98806
--- /dev/null
+++ b/core/java/android/window/flags/window_surfaces.aconfig
@@ -0,0 +1,11 @@
+package: "com.android.window.flags"
+
+# Project link: https://gantry.corp.google.com/projects/android_platform_window_surfaces/changes
+
+flag {
+ namespace: "window_surfaces"
+ name: "surface_trusted_overlay"
+ description: "Whether to add trusted overlay flag on the SurfaceControl or the InputWindow"
+ is_fixed_read_only: true
+ bug: "292032926"
+}
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index 1bfb51c..6e836e0 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -837,25 +837,41 @@
@WorkerThread
private void updateProperties(DeviceConfig.Properties properties) {
- mSamplingInterval = properties.getInt(SETTINGS_SAMPLING_INTERVAL_KEY,
- DEFAULT_SAMPLING_INTERVAL);
- mTraceThresholdMissedFrames = properties.getInt(SETTINGS_THRESHOLD_MISSED_FRAMES_KEY,
- DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES);
- mTraceThresholdFrameTimeMillis = properties.getInt(
- SETTINGS_THRESHOLD_FRAME_TIME_MILLIS_KEY,
- DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS);
- // Never allow the debug overlay to be used on user builds
- boolean debugOverlayEnabled = Build.IS_DEBUGGABLE && properties.getBoolean(
- SETTINGS_DEBUG_OVERLAY_ENABLED_KEY,
- DEFAULT_DEBUG_OVERLAY_ENABLED);
- if (debugOverlayEnabled && mDebugOverlay == null) {
- mDebugOverlay = new InteractionMonitorDebugOverlay(mLock, mDebugBgColor, mDebugYOffset);
- } else if (!debugOverlayEnabled && mDebugOverlay != null) {
- mDebugOverlay.dispose();
- mDebugOverlay = null;
+ for (String property : properties.getKeyset()) {
+ switch (property) {
+ case SETTINGS_SAMPLING_INTERVAL_KEY:
+ mSamplingInterval = properties.getInt(property, DEFAULT_SAMPLING_INTERVAL);
+ break;
+ case SETTINGS_THRESHOLD_MISSED_FRAMES_KEY:
+ mTraceThresholdMissedFrames =
+ properties.getInt(property, DEFAULT_TRACE_THRESHOLD_MISSED_FRAMES);
+ break;
+ case SETTINGS_THRESHOLD_FRAME_TIME_MILLIS_KEY:
+ mTraceThresholdFrameTimeMillis =
+ properties.getInt(property, DEFAULT_TRACE_THRESHOLD_FRAME_TIME_MILLIS);
+ break;
+ case SETTINGS_ENABLED_KEY:
+ mEnabled = properties.getBoolean(property, DEFAULT_ENABLED);
+ break;
+ case SETTINGS_DEBUG_OVERLAY_ENABLED_KEY:
+ // Never allow the debug overlay to be used on user builds
+ boolean debugOverlayEnabled = Build.IS_DEBUGGABLE
+ && properties.getBoolean(property, DEFAULT_DEBUG_OVERLAY_ENABLED);
+ if (debugOverlayEnabled && mDebugOverlay == null) {
+ mDebugOverlay = new InteractionMonitorDebugOverlay(
+ mLock, mDebugBgColor, mDebugYOffset);
+ } else if (!debugOverlayEnabled && mDebugOverlay != null) {
+ mDebugOverlay.dispose();
+ mDebugOverlay = null;
+ }
+ break;
+ default:
+ if (DEBUG) {
+ Log.d(TAG, "Got a change event for an unknown property: "
+ + property + " => " + properties.getString(property, ""));
+ }
+ }
}
- // The memory visibility is powered by the volatile field, mEnabled.
- mEnabled = properties.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED);
}
@VisibleForTesting
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index 06e69f2..fd435d0 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -222,6 +222,7 @@
private boolean isContentRectWithinBounds() {
mContext.getDisplayNoVerify().getRealSize(mDisplaySize);
mScreenRect.set(0, 0, mDisplaySize.x, mDisplaySize.y);
+ mScreenRect.offset(mRootViewPositionOnScreen[0], mRootViewPositionOnScreen[1]);
return intersectsClosed(mContentRectOnScreen, mScreenRect)
&& intersectsClosed(mContentRectOnScreen, mViewRectOnScreen);
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 6c93680..4732702 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -98,6 +98,7 @@
// Settings for font scaling
optional SettingProto accessibility_font_scaling_has_been_changed = 51 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto accessibility_force_invert_color_enabled = 52 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto accessibility_magnification_gesture = 53 [ (android.privacy).dest = DEST_AUTOMATIC ];
}
optional Accessibility accessibility = 2;
diff --git a/core/res/res/layout/autofill_save.xml b/core/res/res/layout/autofill_save.xml
index 8b6c901..27f8138 100644
--- a/core/res/res/layout/autofill_save.xml
+++ b/core/res/res/layout/autofill_save.xml
@@ -60,10 +60,11 @@
android:gravity="center"
android:textAppearance="@style/AutofillSaveUiTitle">
</TextView>
- <LinearLayout
+ <FrameLayout
android:id="@+id/autofill_save_custom_subtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:minHeight="0dp"
android:visibility="gone"/>
</LinearLayout>
diff --git a/core/res/res/values-watch/dimens_material.xml b/core/res/res/values-watch/dimens_material.xml
index 2ab2d91..8becb08 100644
--- a/core/res/res/values-watch/dimens_material.xml
+++ b/core/res/res/values-watch/dimens_material.xml
@@ -47,11 +47,12 @@
<dimen name="progress_bar_height">24dp</dimen>
<!-- Progress bar message dimens -->
- <dimen name="message_progress_dialog_text_size">18sp</dimen>
+ <dimen name="message_progress_dialog_text_size">14sp</dimen>
<dimen name="message_progress_dialog_bottom_padding">80px</dimen>
<dimen name="message_progress_dialog_top_padding">0dp</dimen>
<dimen name="message_progress_dialog_start_padding">0dp</dimen>
<dimen name="message_progress_dialog_end_padding">0dp</dimen>
+ <item name="message_progress_dialog_letter_spacing" format="float" type="dimen">0.021</item>
<!-- fallback for screen percentage widths -->
<dimen name="screen_percentage_05">0dp</dimen>
diff --git a/core/res/res/values-watch/styles_material.xml b/core/res/res/values-watch/styles_material.xml
index 8698e86..f3e412d 100644
--- a/core/res/res/values-watch/styles_material.xml
+++ b/core/res/res/values-watch/styles_material.xml
@@ -100,7 +100,9 @@
<style name="ProgressDialogMessage">
<item name="android:textAlignment">center</item>
- <item name="textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item>
+ <item name="android:fontFamily">google-sans-text</item>
+ <item name="android:letterSpacing">@dimen/message_progress_dialog_letter_spacing</item>
+ <item name="textColor">?attr/textColorPrimary</item>
<item name="textSize">@dimen/message_progress_dialog_text_size</item>
<item name="paddingBottom">@dimen/message_progress_dialog_bottom_padding</item>
<item name="paddingEnd">@dimen/message_progress_dialog_end_padding</item>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3c296de..7ef81ab 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1151,6 +1151,14 @@
<!-- Allows activities to be launched on a long press on power during device setup. -->
<bool name="config_allowStartActivityForLongPressOnPowerInSetup">false</bool>
+ <!-- Control the behavior when the user short presses the settings button.
+ 0 - Nothing
+ 1 - Launch notification panel
+ This needs to match the constants in
+ com/android/server/policy/PhoneWindowManager.java
+ -->
+ <integer name="config_shortPressOnSettingsBehavior">0</integer>
+
<!-- Control the behavior when the user short presses the power button.
0 - Nothing
1 - Go to sleep (doze)
@@ -5394,6 +5402,7 @@
<item>1,1,1.0,.4,1</item>
<item>1,1,1.0,.15,15</item>
<item>0,0,0.7,0,1</item>
+ <item>0,0,0.83333,0,1</item>
</string-array>
<!-- The integer index of the selected option in config_udfps_touch_detection_options -->
diff --git a/core/res/res/values/config_device_idle.xml b/core/res/res/values/config_device_idle.xml
index 98a5ff9..bc9ca3d 100644
--- a/core/res/res/values/config_device_idle.xml
+++ b/core/res/res/values/config_device_idle.xml
@@ -42,6 +42,15 @@
<!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_FACTOR -->
<item name="device_idle_light_idle_factor" format="float" type="integer">2.0</item>
+ <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_INCREASE_LINEARLY -->
+ <bool name="device_idle_light_idle_increase_linearly">false</bool>
+
+ <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS -->
+ <integer name="device_idle_light_idle_linear_increase_factor_ms">300000</integer>
+
+ <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_FLEX_LINEAR_INCREASE_FACTOR_MS -->
+ <integer name="device_idle_light_idle_flex_linear_increase_factor_ms">60000</integer>
+
<!-- Default for DeviceIdleController.Constants.LIGHT_MAX_IDLE_TIMEOUT -->
<integer name="device_idle_light_max_idle_to_ms">900000</integer>
diff --git a/core/res/res/values/config_telephony.xml b/core/res/res/values/config_telephony.xml
index 71d696e..3ba150b 100644
--- a/core/res/res/values/config_telephony.xml
+++ b/core/res/res/values/config_telephony.xml
@@ -73,7 +73,7 @@
CarrierConfigManager#KEY_AUTO_DATA_SWITCH_RAT_SIGNAL_SCORE_STRING_ARRAY.
If 0, the device always switch to the higher score SIM.
If < 0, the network type and signal strength based auto switch is disabled. -->
- <integer name="auto_data_switch_score_tolerance">-1</integer>
+ <integer name="auto_data_switch_score_tolerance">4000</integer>
<java-symbol type="integer" name="auto_data_switch_score_tolerance" />
<!-- Boolean indicating whether the Iwlan data service supports persistence of iwlan ipsec
@@ -219,4 +219,8 @@
<bool name="telephony_analytics_switch">true</bool>
<java-symbol type="bool" name="telephony_analytics_switch" />
+ <!-- Whether to enable modem on boot if behavior is not defined -->
+ <bool name="config_enable_cellular_on_boot_default">true</bool>
+ <java-symbol type="bool" name="config_enable_cellular_on_boot_default" />
+
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 193f3ad..643f4b1 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1816,6 +1816,7 @@
<java-symbol type="integer" name="config_lidNavigationAccessibility" />
<java-symbol type="integer" name="config_lidOpenRotation" />
<java-symbol type="integer" name="config_longPressOnHomeBehavior" />
+ <java-symbol type="integer" name="config_shortPressOnSettingsBehavior" />
<java-symbol type="layout" name="global_actions" />
<java-symbol type="layout" name="global_actions_item" />
<java-symbol type="layout" name="global_actions_silent_mode" />
@@ -4537,7 +4538,10 @@
<java-symbol type="integer" name="device_idle_light_idle_to_init_flex_ms" />
<java-symbol type="integer" name="device_idle_light_idle_to_max_flex_ms" />
<java-symbol type="integer" name="device_idle_light_idle_factor" />
+ <java-symbol type="bool" name="device_idle_light_idle_increase_linearly" />
<java-symbol type="integer" name="device_idle_light_max_idle_to_ms" />
+ <java-symbol type="integer" name="device_idle_light_idle_linear_increase_factor_ms" />
+ <java-symbol type="integer" name="device_idle_light_idle_flex_linear_increase_factor_ms" />
<java-symbol type="integer" name="device_idle_light_idle_maintenance_min_budget_ms" />
<java-symbol type="integer" name="device_idle_light_idle_maintenance_max_budget_ms" />
<java-symbol type="integer" name="device_idle_min_light_maintenance_time_ms" />
diff --git a/core/tests/BroadcastRadioTests/Android.bp b/core/tests/BroadcastRadioTests/Android.bp
index 85d54e0..054d10c 100644
--- a/core/tests/BroadcastRadioTests/Android.bp
+++ b/core/tests/BroadcastRadioTests/Android.bp
@@ -38,7 +38,7 @@
static_libs: [
"services.core",
"androidx.test.rules",
- "truth-prebuilt",
+ "truth",
"testng",
"mockito-target-extended",
],
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
index a195228..824f591 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
@@ -16,20 +16,20 @@
package com.android.server.broadcastradio.aidl;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.after;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.timeout;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static org.junit.Assert.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.app.compat.CompatChanges;
import android.graphics.Bitmap;
@@ -81,8 +81,8 @@
private static final int USER_ID_1 = 11;
private static final int USER_ID_2 = 12;
- private static final VerificationWithTimeout CALLBACK_TIMEOUT =
- timeout(/* millis= */ 200);
+ private static final int CALLBACK_TIMEOUT_MS = 200;
+ private static final VerificationWithTimeout CALLBACK_TIMEOUT = timeout(CALLBACK_TIMEOUT_MS);
private static final int SIGNAL_QUALITY = 90;
private static final long AM_FM_FREQUENCY_SPACING = 500;
private static final long[] AM_FM_FREQUENCY_LIST = {97_500, 98_100, 99_100};
@@ -166,12 +166,12 @@
@Before
public void setup() throws Exception {
- when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
doReturn(true).when(() -> CompatChanges.isChangeEnabled(
eq(ConversionUtils.RADIO_U_VERSION_REQUIRED), anyInt()));
+ doReturn(USER_ID_1).when(mUserHandleMock).getIdentifier();
+ doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser());
- doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
mRadioModule = new RadioModule(mBroadcastRadioMock,
AidlTestUtils.makeDefaultModuleProperties());
@@ -222,7 +222,7 @@
return Result.OK;
}).when(mBroadcastRadioMock).seek(anyBoolean(), anyBoolean());
- when(mBroadcastRadioMock.getImage(anyInt())).thenReturn(null);
+ doReturn(null).when(mBroadcastRadioMock).getImage(anyInt());
doAnswer(invocation -> {
int configFlag = (int) invocation.getArguments()[0];
@@ -275,7 +275,7 @@
mTunerSessions[0].setConfiguration(FM_BAND_CONFIG);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onConfigurationChanged(FM_BAND_CONFIG);
}
@@ -446,26 +446,11 @@
mTunerSessions[0].tune(initialSel);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(tuneInfo);
}
@Test
- public void tune_forSystemUser() throws Exception {
- when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM);
- doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
- doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
- ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
- RadioManager.ProgramInfo tuneInfo =
- AidlTestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY);
- openAidlClients(/* numClients= */ 1);
-
- mTunerSessions[0].tune(initialSel);
-
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(tuneInfo);
- }
-
- @Test
public void tune_withUnknownErrorFromHal_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
ProgramSelector sel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
@@ -525,7 +510,7 @@
mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(any());
}
@@ -604,7 +589,7 @@
mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(seekUpInfo);
}
@@ -638,6 +623,7 @@
openAidlClients(/* numClients= */ 1);
ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
mTunerSessions[0].tune(initialSel);
+ verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(any());
doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mTunerSessions[0].cancel();
@@ -686,8 +672,8 @@
public void getImage_whenHalThrowsException_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
String exceptionMessage = "HAL service died.";
- when(mBroadcastRadioMock.getImage(anyInt()))
- .thenThrow(new RemoteException(exceptionMessage));
+ doThrow(new RemoteException(exceptionMessage)).when(mBroadcastRadioMock)
+ .getImage(anyInt());
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].getImage(/* id= */ 1);
@@ -713,7 +699,8 @@
mTunerSessions[0].startBackgroundScan();
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onBackgroundScanComplete();
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
+ .onBackgroundScanComplete();
}
@Test
@@ -905,7 +892,8 @@
mHalTunerCallback.onProgramListUpdated(AidlTestUtils.makeHalChunk(/* purge= */ false,
/* complete= */ true, List.of(TEST_FM_INFO), new ArrayList<>()));
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onProgramListUpdated(any());
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
+ .onProgramListUpdated(any());
}
@Test
@@ -1160,8 +1148,8 @@
Map<String, String> parametersSet = Map.of("mockParam1", "mockValue1",
"mockParam2", "mockValue2");
String exceptionMessage = "HAL service died.";
- when(mBroadcastRadioMock.setParameters(any()))
- .thenThrow(new RemoteException(exceptionMessage));
+ doThrow(new RemoteException(exceptionMessage)).when(mBroadcastRadioMock)
+ .setParameters(any());
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].setParameters(parametersSet);
@@ -1186,8 +1174,8 @@
openAidlClients(/* numClients= */ 1);
List<String> parameterKeys = List.of("mockKey1", "mockKey2");
String exceptionMessage = "HAL service died.";
- when(mBroadcastRadioMock.getParameters(any()))
- .thenThrow(new RemoteException(exceptionMessage));
+ doThrow(new RemoteException(exceptionMessage)).when(mBroadcastRadioMock)
+ .getParameters(any());
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].getParameters(parameterKeys);
@@ -1198,7 +1186,7 @@
}
@Test
- public void onCurrentProgramInfoChanged_withNoncurrentUser_doesNotInvokeCallback()
+ public void onCurrentProgramInfoChanged_withNonCurrentUser_doesNotInvokeCallback()
throws Exception {
openAidlClients(1);
doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser());
@@ -1206,7 +1194,7 @@
mHalTunerCallback.onCurrentProgramInfoChanged(AidlTestUtils.makeHalProgramInfo(
AidlTestUtils.makeHalFmSelector(AM_FM_FREQUENCY_LIST[1]), SIGNAL_QUALITY));
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(any());
}
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
index fac9eaa..3b9d7ba 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java
@@ -16,22 +16,22 @@
package com.android.server.broadcastradio.hal2;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.after;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.timeout;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.graphics.Bitmap;
import android.hardware.broadcastradio.V2_0.Constants;
@@ -78,8 +78,8 @@
private static final int USER_ID_1 = 11;
private static final int USER_ID_2 = 12;
- private static final VerificationWithTimeout CALLBACK_TIMEOUT =
- timeout(/* millis= */ 200);
+ private static final int CALLBACK_TIMEOUT_MS = 200;
+ private static final VerificationWithTimeout CALLBACK_TIMEOUT = timeout(CALLBACK_TIMEOUT_MS);
private static final int SIGNAL_QUALITY = 1;
private static final long AM_FM_FREQUENCY_SPACING = 500;
private static final long[] AM_FM_FREQUENCY_LIST = {97_500, 98_100, 99_100};
@@ -113,7 +113,7 @@
@Before
public void setup() throws Exception {
- when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1);
+ doReturn(USER_ID_1).when(mUserHandleMock).getIdentifier();
doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser());
@@ -170,7 +170,7 @@
return Result.OK;
}).when(mHalTunerSessionMock).scan(anyBoolean(), anyBoolean());
- when(mBroadcastRadioMock.getImage(anyInt())).thenReturn(new ArrayList<Byte>(0));
+ doReturn(new ArrayList<Byte>(0)).when(mBroadcastRadioMock).getImage(anyInt());
doAnswer(invocation -> {
int configFlag = (int) invocation.getArguments()[0];
@@ -227,7 +227,7 @@
mTunerSessions[0].setConfiguration(FM_BAND_CONFIG);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onConfigurationChanged(FM_BAND_CONFIG);
}
@@ -379,7 +379,7 @@
mTunerSessions[0].tune(initialSel);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(tuneInfo);
}
@@ -398,20 +398,6 @@
}
@Test
- public void tune_forSystemUser() throws Exception {
- when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM);
- doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle());
- doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
- ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
- RadioManager.ProgramInfo tuneInfo = TestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY);
- openAidlClients(/* numClients= */ 1);
-
- mTunerSessions[0].tune(initialSel);
-
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT).onCurrentProgramInfoChanged(tuneInfo);
- }
-
- @Test
public void step_withDirectionUp() throws Exception {
long initFreq = AM_FM_FREQUENCY_LIST[1];
ProgramSelector initialSel = TestUtils.makeFmSelector(initFreq);
@@ -455,7 +441,7 @@
mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(any());
}
@@ -533,7 +519,7 @@
mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false);
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(seekUpInfo);
}
@@ -563,18 +549,6 @@
}
@Test
- public void cancel_forNonCurrentUser() throws Exception {
- openAidlClients(/* numClients= */ 1);
- ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
- mTunerSessions[0].tune(initialSel);
- doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
-
- mTunerSessions[0].cancel();
-
- verify(mHalTunerSessionMock, never()).cancel();
- }
-
- @Test
public void cancel_forNonCurrentUser_doesNotCancel() throws Exception {
openAidlClients(/* numClients= */ 1);
ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
@@ -627,8 +601,7 @@
public void getImage_whenHalThrowsException_fails() throws Exception {
openAidlClients(/* numClients= */ 1);
String exceptionMessage = "HAL service died.";
- when(mBroadcastRadioMock.getImage(anyInt()))
- .thenThrow(new RemoteException(exceptionMessage));
+ doThrow(new RemoteException(exceptionMessage)).when(mBroadcastRadioMock).getImage(anyInt());
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].getImage(/* id= */ 1);
@@ -654,7 +627,8 @@
mTunerSessions[0].startBackgroundScan();
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0)).onBackgroundScanComplete();
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
+ .onBackgroundScanComplete();
}
@Test
@@ -845,8 +819,8 @@
Map<String, String> parametersSet = Map.of("mockParam1", "mockValue1",
"mockParam2", "mockValue2");
String exceptionMessage = "HAL service died.";
- when(mHalTunerSessionMock.setParameters(any()))
- .thenThrow(new RemoteException(exceptionMessage));
+ doThrow(new RemoteException(exceptionMessage)).when(mHalTunerSessionMock)
+ .setParameters(any());
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].setParameters(parametersSet);
@@ -871,8 +845,8 @@
openAidlClients(/* numClients= */ 1);
List<String> parameterKeys = List.of("mockKey1", "mockKey2");
String exceptionMessage = "HAL service died.";
- when(mHalTunerSessionMock.getParameters(any()))
- .thenThrow(new RemoteException(exceptionMessage));
+ doThrow(new RemoteException(exceptionMessage)).when(mHalTunerSessionMock)
+ .getParameters(any());
RuntimeException thrown = assertThrows(RuntimeException.class, () -> {
mTunerSessions[0].getParameters(parameterKeys);
@@ -883,7 +857,7 @@
}
@Test
- public void onCurrentProgramInfoChanged_withNoncurrentUser_doesNotInvokeCallback()
+ public void onCurrentProgramInfoChanged_withNonCurrentUser_doesNotInvokeCallback()
throws Exception {
openAidlClients(1);
doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser());
@@ -891,7 +865,7 @@
mHalTunerCallback.onCurrentProgramInfoChanged(TestUtils.makeHalProgramInfo(
TestUtils.makeHalFmSelector(/* freq= */ 97300), SIGNAL_QUALITY));
- verify(mAidlTunerCallbackMocks[0], CALLBACK_TIMEOUT.times(0))
+ verify(mAidlTunerCallbackMocks[0], after(CALLBACK_TIMEOUT_MS).times(0))
.onCurrentProgramInfoChanged(any());
}
diff --git a/core/tests/GameManagerTests/Android.bp b/core/tests/GameManagerTests/Android.bp
index 8c5d6d5..0e3bc65 100644
--- a/core/tests/GameManagerTests/Android.bp
+++ b/core/tests/GameManagerTests/Android.bp
@@ -30,7 +30,7 @@
"frameworks-base-testutils",
"junit",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
],
libs: ["android.test.runner"],
platform_apis: true,
diff --git a/core/tests/PackageInstallerSessions/Android.bp b/core/tests/PackageInstallerSessions/Android.bp
index 6f2366e..b631df1 100644
--- a/core/tests/PackageInstallerSessions/Android.bp
+++ b/core/tests/PackageInstallerSessions/Android.bp
@@ -35,7 +35,7 @@
"frameworks-base-testutils",
"platform-test-annotations",
"testng",
- "truth-prebuilt",
+ "truth",
],
libs: [
diff --git a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp
index 5260835..1fb5f2c 100644
--- a/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp
+++ b/core/tests/batterystatstests/BatteryUsageStatsProtoTests/Android.bp
@@ -18,7 +18,7 @@
"platform-test-annotations",
"platformprotosnano",
"statsdprotolite",
- "truth-prebuilt",
+ "truth",
],
libs: ["android.test.runner"],
diff --git a/core/tests/bugreports/Android.bp b/core/tests/bugreports/Android.bp
index 2b34ee2..7c1ac48 100644
--- a/core/tests/bugreports/Android.bp
+++ b/core/tests/bugreports/Android.bp
@@ -32,7 +32,7 @@
static_libs: [
"androidx.test.rules",
"androidx.test.uiautomator_uiautomator",
- "truth-prebuilt",
+ "truth",
],
test_suites: ["general-tests"],
sdk_version: "test_current",
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 04622fd..81dab08 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -58,7 +58,7 @@
"androidx.test.uiautomator_uiautomator",
"platform-test-annotations",
"platform-compat-test-rules",
- "truth-prebuilt",
+ "truth",
"print-test-util-lib",
"testng",
"servicestests-utils",
@@ -149,7 +149,7 @@
"androidx.test.runner",
"androidx.test.rules",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
libs: [
diff --git a/core/tests/hdmitests/Android.bp b/core/tests/hdmitests/Android.bp
index 3d04937..5f6eaf9 100644
--- a/core/tests/hdmitests/Android.bp
+++ b/core/tests/hdmitests/Android.bp
@@ -30,7 +30,7 @@
"frameworks-base-testutils",
"guava-android-testlib",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
],
libs: ["android.test.runner"],
platform_apis: true,
diff --git a/core/tests/mockingcoretests/Android.bp b/core/tests/mockingcoretests/Android.bp
index fde7c08..2d778b1 100644
--- a/core/tests/mockingcoretests/Android.bp
+++ b/core/tests/mockingcoretests/Android.bp
@@ -38,7 +38,7 @@
"androidx.test.ext.junit",
"mockito-target-extended-minus-junit4",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
"testables",
],
diff --git a/core/tests/nfctests/Android.bp b/core/tests/nfctests/Android.bp
index c74600b..f81be49 100644
--- a/core/tests/nfctests/Android.bp
+++ b/core/tests/nfctests/Android.bp
@@ -27,7 +27,7 @@
"androidx.test.ext.junit",
"androidx.test.rules",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
libs: [
"android.test.runner",
diff --git a/core/tests/overlaytests/device_self_targeting/Android.bp b/core/tests/overlaytests/device_self_targeting/Android.bp
index 063c569..931eac5 100644
--- a/core/tests/overlaytests/device_self_targeting/Android.bp
+++ b/core/tests/overlaytests/device_self_targeting/Android.bp
@@ -30,7 +30,7 @@
"androidx.test.runner",
"androidx.test.ext.junit",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
optimize: {
diff --git a/core/tests/packagemonitortests/Android.bp b/core/tests/packagemonitortests/Android.bp
index 7b5d7df..b08850e 100644
--- a/core/tests/packagemonitortests/Android.bp
+++ b/core/tests/packagemonitortests/Android.bp
@@ -32,7 +32,7 @@
"compatibility-device-util-axt",
"frameworks-base-testutils",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
libs: ["android.test.runner"],
platform_apis: true,
diff --git a/core/tests/privacytests/Android.bp b/core/tests/privacytests/Android.bp
index bc3dd81..4e24cd5 100644
--- a/core/tests/privacytests/Android.bp
+++ b/core/tests/privacytests/Android.bp
@@ -14,7 +14,7 @@
"junit",
"rappor-tests",
"androidx.test.rules",
- "truth-prebuilt",
+ "truth",
],
libs: ["android.test.runner"],
platform_apis: true,
diff --git a/core/tests/utiltests/Android.bp b/core/tests/utiltests/Android.bp
index 3798da5..580e73c 100644
--- a/core/tests/utiltests/Android.bp
+++ b/core/tests/utiltests/Android.bp
@@ -33,7 +33,7 @@
"frameworks-base-testutils",
"mockito-target-minus-junit4",
"androidx.test.ext.junit",
- "truth-prebuilt",
+ "truth",
"servicestests-utils",
],
diff --git a/core/tests/vibrator/Android.bp b/core/tests/vibrator/Android.bp
index 829409a..09608e9 100644
--- a/core/tests/vibrator/Android.bp
+++ b/core/tests/vibrator/Android.bp
@@ -18,7 +18,7 @@
"androidx.test.runner",
"androidx.test.rules",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
"testng",
],
diff --git a/errorprone/Android.bp b/errorprone/Android.bp
index ad08026..c1d2235 100644
--- a/errorprone/Android.bp
+++ b/errorprone/Android.bp
@@ -41,7 +41,7 @@
java_resource_dirs: ["tests/res"],
java_resources: [":error_prone_android_framework_testdata"],
static_libs: [
- "truth-prebuilt",
+ "truth",
"kxml2-2.3.0",
"compile-testing-prebuilt",
"error_prone_android_framework_lib",
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
index c55a781..11278e8 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
@@ -43,6 +43,7 @@
import java.security.interfaces.RSAPublicKey;
import javax.crypto.Cipher;
+import javax.crypto.KeyAgreement;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
@@ -181,6 +182,8 @@
spi = ((Mac) cryptoPrimitive).getCurrentSpi();
} else if (cryptoPrimitive instanceof Cipher) {
spi = ((Cipher) cryptoPrimitive).getCurrentSpi();
+ } else if (cryptoPrimitive instanceof KeyAgreement) {
+ spi = ((KeyAgreement) cryptoPrimitive).getCurrentSpi();
} else {
throw new IllegalArgumentException("Unsupported crypto primitive: " + cryptoPrimitive
+ ". Supported: Signature, Mac, Cipher");
diff --git a/libs/WindowManager/Jetpack/tests/unittest/Android.bp b/libs/WindowManager/Jetpack/tests/unittest/Android.bp
index b6e743a..ed2ff2d 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/Android.bp
+++ b/libs/WindowManager/Jetpack/tests/unittest/Android.bp
@@ -37,7 +37,7 @@
"androidx.test.rules",
"androidx.test.ext.junit",
"mockito-target-extended-minus-junit4",
- "truth-prebuilt",
+ "truth",
"testables",
"platform-test-annotations",
],
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
index f1ee8fa..a67821b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
@@ -318,7 +318,7 @@
/**
* Animates the dot to the given scale, running the optional callback when the animation ends.
*/
- private void animateDotScale(float toScale, @Nullable Runnable after) {
+ public void animateDotScale(float toScale, @Nullable Runnable after) {
mDotIsAnimating = true;
// Don't restart the animation if we're already animating to the given value.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
index df19757..dc099d9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
@@ -27,6 +27,7 @@
import android.graphics.drawable.InsetDrawable
import android.util.PathParser
import android.view.LayoutInflater
+import android.view.View.VISIBLE
import android.widget.FrameLayout
import com.android.launcher3.icons.BubbleIconFactory
import com.android.wm.shell.R
@@ -156,7 +157,9 @@
fun setShowDot(show: Boolean) {
showDot = show
- overflowBtn?.updateDotVisibility(true /* animate */)
+ if (overflowBtn?.visibility == VISIBLE) {
+ overflowBtn?.updateDotVisibility(true /* animate */)
+ }
}
/** Creates the expanded view for bubbles showing in the stack view. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index c124b53..2241c34 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -1864,6 +1864,14 @@
: GONE);
}
+ private void updateOverflowDotVisibility(boolean expanding) {
+ if (mBubbleOverflow.showDot()) {
+ mBubbleOverflow.getIconView().animateDotScale(expanding ? 1 : 0f, () -> {
+ mBubbleOverflow.setVisible(expanding ? VISIBLE : GONE);
+ });
+ }
+ }
+
// via BubbleData.Listener
void updateBubble(Bubble bubble) {
animateInFlyoutForBubble(bubble);
@@ -2274,6 +2282,7 @@
if (mIsExpanded && mExpandedBubble.getExpandedView() != null) {
maybeShowManageEdu();
}
+ updateOverflowDotVisibility(true /* expanding */);
} /* after */);
int index;
if (mExpandedBubble != null && BubbleOverflow.KEY.equals(mExpandedBubble.getKey())) {
@@ -2405,11 +2414,15 @@
// since we're about to animate collapsed.
mExpandedAnimationController.notifyPreparingToCollapse();
+ updateOverflowDotVisibility(false /* expanding */);
final Runnable collapseBackToStack = () -> mExpandedAnimationController.collapseBackToStack(
mStackAnimationController
.getStackPositionAlongNearestHorizontalEdge()
/* collapseTo */,
- () -> mBubbleContainer.setActiveController(mStackAnimationController));
+ () -> {
+ mBubbleContainer.setActiveController(mStackAnimationController);
+ updateOverflowVisibility();
+ });
final Runnable after = () -> {
final BubbleViewProvider previouslySelected = mExpandedBubble;
@@ -2424,7 +2437,6 @@
Log.d(TAG, BubbleDebugConfig.formatBubblesString(getBubblesOnScreen(),
mExpandedBubble));
}
- updateOverflowVisibility();
updateZOrder();
updateBadges(true /* setBadgeForCollapsedStack */);
afterExpandedViewAnimation();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
index 4d7042b..738c94e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java
@@ -34,6 +34,8 @@
import com.android.wm.shell.R;
import com.android.wm.shell.animation.Interpolators;
import com.android.wm.shell.animation.PhysicsAnimator;
+import com.android.wm.shell.bubbles.BadgedImageView;
+import com.android.wm.shell.bubbles.BubbleOverflow;
import com.android.wm.shell.bubbles.BubblePositioner;
import com.android.wm.shell.bubbles.BubbleStackView;
import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
@@ -63,6 +65,12 @@
/** Damping ratio for expand/collapse spring. */
private static final float DAMPING_RATIO_MEDIUM_LOW_BOUNCY = 0.65f;
+ /**
+ * Damping ratio for the overflow bubble spring; this is less bouncy so it doesn't bounce behind
+ * the top bubble when it goes to disappear.
+ */
+ private static final float DAMPING_RATIO_OVERFLOW_BOUNCY = 0.90f;
+
/** Stiffness for the expand/collapse path-following animation. */
private static final int EXPAND_COLLAPSE_ANIM_STIFFNESS = 400;
@@ -274,9 +282,14 @@
// of the screen where the bubble will be stacked.
path.lineTo(stackedX, p.y);
+ // The overflow should animate to the collapse point, so 0 offset.
+ final boolean isOverflow = bubble instanceof BadgedImageView
+ && BubbleOverflow.KEY.equals(((BadgedImageView) bubble).getKey());
+ final float offsetY = isOverflow
+ ? 0
+ : Math.min(index, NUM_VISIBLE_WHEN_RESTING - 1) * mStackOffsetPx;
// Then, draw a line down to the stack position.
- path.lineTo(stackedX, mCollapsePoint.y
- + Math.min(index, NUM_VISIBLE_WHEN_RESTING - 1) * mStackOffsetPx);
+ path.lineTo(stackedX, mCollapsePoint.y + offsetY);
}
// The lead bubble should be the bubble with the longest distance to travel when we're
@@ -505,8 +518,12 @@
@Override
SpringForce getSpringForce(DynamicAnimation.ViewProperty property, View view) {
+ boolean isOverflow = (view instanceof BadgedImageView)
+ && BubbleOverflow.KEY.equals(((BadgedImageView) view).getKey());
return new SpringForce()
- .setDampingRatio(DAMPING_RATIO_MEDIUM_LOW_BOUNCY)
+ .setDampingRatio(isOverflow
+ ? DAMPING_RATIO_OVERFLOW_BOUNCY
+ : DAMPING_RATIO_MEDIUM_LOW_BOUNCY)
.setStiffness(SpringForce.STIFFNESS_LOW);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
index 5e42782..e9344ff 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java
@@ -203,7 +203,7 @@
+ "SystemWindow:" + view);
return null;
}
- return root.getFocusGrantToken();
+ return root.getInputTransferToken();
}
private class PerDisplay {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 11aa0546..5dfba5e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -494,13 +494,14 @@
ToggleResizeDesktopTaskTransitionHandler toggleResizeDesktopTaskTransitionHandler,
@DynamicOverride DesktopModeTaskRepository desktopModeTaskRepository,
LaunchAdjacentController launchAdjacentController,
+ RecentsTransitionHandler recentsTransitionHandler,
@ShellMainThread ShellExecutor mainExecutor
) {
return new DesktopTasksController(context, shellInit, shellCommandHandler, shellController,
displayController, shellTaskOrganizer, syncQueue, rootTaskDisplayAreaOrganizer,
transitions, enterDesktopTransitionHandler, exitDesktopTransitionHandler,
toggleResizeDesktopTaskTransitionHandler, desktopModeTaskRepository,
- launchAdjacentController, mainExecutor);
+ launchAdjacentController, recentsTransitionHandler, mainExecutor);
}
@WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 09ba4f7..412a5b5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -60,6 +60,8 @@
import com.android.wm.shell.desktopmode.DesktopModeTaskRepository.VisibleTasksListener
import com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.TO_DESKTOP_INDICATOR
import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
+import com.android.wm.shell.recents.RecentsTransitionHandler
+import com.android.wm.shell.recents.RecentsTransitionStateListener
import com.android.wm.shell.splitscreen.SplitScreenController
import com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_ENTER_DESKTOP
import com.android.wm.shell.sysui.ShellCommandHandler
@@ -68,7 +70,6 @@
import com.android.wm.shell.sysui.ShellSharedConstants
import com.android.wm.shell.transition.OneShotRemoteHandler
import com.android.wm.shell.transition.Transitions
-import com.android.wm.shell.transition.Transitions.TransitionHandler
import com.android.wm.shell.util.KtProtoLog
import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration
import com.android.wm.shell.windowdecor.MoveToDesktopAnimator
@@ -93,6 +94,7 @@
ToggleResizeDesktopTaskTransitionHandler,
private val desktopModeTaskRepository: DesktopModeTaskRepository,
private val launchAdjacentController: LaunchAdjacentController,
+ private val recentsTransitionHandler: RecentsTransitionHandler,
@ShellMainThread private val mainExecutor: ShellExecutor
) : RemoteCallable<DesktopTasksController>, Transitions.TransitionHandler {
@@ -119,6 +121,8 @@
com.android.wm.shell.R.dimen.desktop_mode_transition_area_width
)
+ private var recentsAnimationRunning = false
+
// This is public to avoid cyclic dependency; it is set by SplitScreenController
lateinit var splitScreenController: SplitScreenController
@@ -139,6 +143,19 @@
)
transitions.addHandler(this)
desktopModeTaskRepository.addVisibleTasksListener(taskVisibilityListener, mainExecutor)
+
+ recentsTransitionHandler.addTransitionStateListener(
+ object : RecentsTransitionStateListener {
+ override fun onAnimationStateChanged(running: Boolean) {
+ KtProtoLog.v(
+ WM_SHELL_DESKTOP_MODE,
+ "DesktopTasksController: recents animation state changed running=%b",
+ running
+ )
+ recentsAnimationRunning = running
+ }
+ }
+ )
}
/** Show all tasks, that are part of the desktop, on top of launcher */
@@ -644,6 +661,10 @@
val triggerTask = request.triggerTask
val shouldHandleRequest =
when {
+ recentsAnimationRunning -> {
+ reason = "recents animation is running"
+ false
+ }
// Only handle open or to front transitions
request.type != TRANSIT_OPEN && request.type != TRANSIT_TO_FRONT -> {
reason = "transition type not handled (${request.type})"
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index ead2f9c..d31476c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -54,6 +54,7 @@
import android.window.WindowContainerTransaction;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.IResultReceiver;
import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
@@ -279,7 +280,7 @@
mDeathHandler = () -> {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
"[%d] RecentsController.DeathRecipient: binder died", mInstanceId);
- finish(mWillFinishToHome, false /* leaveHint */);
+ finish(mWillFinishToHome, false /* leaveHint */, null /* finishCb */);
};
try {
mListener.asBinder().linkToDeath(mDeathHandler, 0 /* flags */);
@@ -313,7 +314,7 @@
}
}
if (mFinishCB != null) {
- finishInner(toHome, false /* userLeave */);
+ finishInner(toHome, false /* userLeave */, null /* finishCb */);
} else {
cleanUp();
}
@@ -670,7 +671,8 @@
// now and let it do its animation (since recents is going to be occluded).
sendCancelWithSnapshots();
mExecutor.executeDelayed(
- () -> finishInner(true /* toHome */, false /* userLeaveHint */), 0);
+ () -> finishInner(true /* toHome */, false /* userLeaveHint */,
+ null /* finishCb */), 0);
return;
}
if (recentsOpening != null) {
@@ -899,11 +901,12 @@
@Override
@SuppressLint("NewApi")
- public void finish(boolean toHome, boolean sendUserLeaveHint) {
- mExecutor.execute(() -> finishInner(toHome, sendUserLeaveHint));
+ public void finish(boolean toHome, boolean sendUserLeaveHint, IResultReceiver finishCb) {
+ mExecutor.execute(() -> finishInner(toHome, sendUserLeaveHint, finishCb));
}
- private void finishInner(boolean toHome, boolean sendUserLeaveHint) {
+ private void finishInner(boolean toHome, boolean sendUserLeaveHint,
+ IResultReceiver runnerFinishCb) {
if (mFinishCB == null) {
Slog.e(TAG, "Duplicate call to finish");
return;
@@ -993,6 +996,16 @@
}
cleanUp();
finishCB.onTransitionFinished(wct.isEmpty() ? null : wct);
+ if (runnerFinishCb != null) {
+ try {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
+ "[%d] RecentsController.finishInner: calling finish callback",
+ mInstanceId);
+ runnerFinishCb.send(0, null);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to report transition finished", e);
+ }
+ }
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 83dc7fa..e828eed 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -23,6 +23,7 @@
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
+
import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED;
import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_ALPHA;
@@ -693,9 +694,19 @@
@NonNull SurfaceControl.Transaction startTransaction,
@NonNull SurfaceControl.Transaction finishTransaction,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
+ Transitions.TransitionFinishCallback finishCB = wct -> {
+ mixed.mInFlightSubAnimations--;
+ if (mixed.mInFlightSubAnimations == 0) {
+ mActiveTransitions.remove(mixed);
+ finishCallback.onTransitionFinished(wct);
+ }
+ };
+
+ mixed.mInFlightSubAnimations++;
boolean consumed = mRecentsHandler.startAnimation(
- mixed.mTransition, info, startTransaction, finishTransaction, finishCallback);
+ mixed.mTransition, info, startTransaction, finishTransaction, finishCB);
if (!consumed) {
+ mixed.mInFlightSubAnimations--;
return false;
}
if (mDesktopTasksController != null) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
index e0635ac..de03f58 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java
@@ -322,7 +322,6 @@
final Runnable onAnimFinish = () -> {
if (!animations.isEmpty()) return;
mAnimations.remove(transition);
- info.releaseAllSurfaces();
finishCallback.onTransitionFinished(null /* wct */);
};
diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp
index 54f9498..d09a90c 100644
--- a/libs/WindowManager/Shell/tests/unittest/Android.bp
+++ b/libs/WindowManager/Shell/tests/unittest/Android.bp
@@ -45,7 +45,7 @@
"kotlinx-coroutines-core",
"mockito-kotlin2",
"mockito-target-extended-minus-junit4",
- "truth-prebuilt",
+ "truth",
"testables",
"platform-test-annotations",
"servicestests-utils",
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index dea1617..ebcb640 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -54,6 +54,8 @@
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createFullscreenTask
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createHomeTask
import com.android.wm.shell.desktopmode.DesktopTestHelpers.Companion.createSplitScreenTask
+import com.android.wm.shell.recents.RecentsTransitionHandler
+import com.android.wm.shell.recents.RecentsTransitionStateListener
import com.android.wm.shell.splitscreen.SplitScreenController
import com.android.wm.shell.sysui.ShellCommandHandler
import com.android.wm.shell.sysui.ShellController
@@ -101,11 +103,13 @@
@Mock lateinit var launchAdjacentController: LaunchAdjacentController
@Mock lateinit var desktopModeWindowDecoration: DesktopModeWindowDecoration
@Mock lateinit var splitScreenController: SplitScreenController
+ @Mock lateinit var recentsTransitionHandler: RecentsTransitionHandler
private lateinit var mockitoSession: StaticMockitoSession
private lateinit var controller: DesktopTasksController
private lateinit var shellInit: ShellInit
private lateinit var desktopModeTaskRepository: DesktopModeTaskRepository
+ private lateinit var recentsTransitionStateListener: RecentsTransitionStateListener
private val shellExecutor = TestShellExecutor()
// Mock running tasks are registered here so we can get the list from mock shell task organizer
@@ -126,6 +130,10 @@
controller.splitScreenController = splitScreenController
shellInit.init()
+
+ val captor = ArgumentCaptor.forClass(RecentsTransitionStateListener::class.java)
+ verify(recentsTransitionHandler).addTransitionStateListener(captor.capture())
+ recentsTransitionStateListener = captor.value
}
private fun createController(): DesktopTasksController {
@@ -144,6 +152,7 @@
mToggleResizeDesktopTaskTransitionHandler,
desktopModeTaskRepository,
launchAdjacentController,
+ recentsTransitionHandler,
shellExecutor
)
}
@@ -355,7 +364,7 @@
@Test
fun moveToDesktop_splitTaskExitsSplit() {
- var task = setUpSplitScreenTask()
+ val task = setUpSplitScreenTask()
controller.moveToDesktop(desktopModeWindowDecoration, task)
val wct = getLatestMoveToDesktopWct()
assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
@@ -367,7 +376,7 @@
@Test
fun moveToDesktop_fullscreenTaskDoesNotExitSplit() {
- var task = setUpFullscreenTask()
+ val task = setUpFullscreenTask()
controller.moveToDesktop(desktopModeWindowDecoration, task)
val wct = getLatestMoveToDesktopWct()
assertThat(wct.changes[task.token.asBinder()]?.windowingMode)
@@ -666,6 +675,20 @@
}
@Test
+ fun handleRequest_recentsAnimationRunning_returnNull() {
+ // Set up a visible freeform task so a fullscreen task should be converted to freeform
+ val freeformTask = setUpFreeformTask()
+ markTaskVisible(freeformTask)
+
+ // Mark recents animation running
+ recentsTransitionStateListener.onAnimationStateChanged(true)
+
+ // Open a fullscreen task, check that it does not result in a WCT with changes to it
+ val fullscreenTask = createFullscreenTask()
+ assertThat(controller.handleRequest(Binder(), createTransition(fullscreenTask))).isNull()
+ }
+
+ @Test
fun stashDesktopApps_stateUpdates() {
whenever(DesktopModeStatus.isStashingEnabled()).thenReturn(true)
diff --git a/libs/dream/lowlight/tests/Android.bp b/libs/dream/lowlight/tests/Android.bp
index 64b53cb..4dafd0a 100644
--- a/libs/dream/lowlight/tests/Android.bp
+++ b/libs/dream/lowlight/tests/Android.bp
@@ -34,7 +34,7 @@
"mockito-target-extended-minus-junit4",
"platform-test-annotations",
"testables",
- "truth-prebuilt",
+ "truth",
],
libs: [
"android.test.mock",
diff --git a/libs/securebox/tests/Android.bp b/libs/securebox/tests/Android.bp
index 7df546a..80b501d 100644
--- a/libs/securebox/tests/Android.bp
+++ b/libs/securebox/tests/Android.bp
@@ -32,7 +32,7 @@
"platform-test-annotations",
"testables",
"testng",
- "truth-prebuilt",
+ "truth",
],
libs: [
"android.test.mock",
diff --git a/media/tests/MediaFrameworkTest/Android.bp b/media/tests/MediaFrameworkTest/Android.bp
index ca20225e..bdd7afe 100644
--- a/media/tests/MediaFrameworkTest/Android.bp
+++ b/media/tests/MediaFrameworkTest/Android.bp
@@ -22,7 +22,7 @@
"android-ex-camera2",
"testables",
"testng",
- "truth-prebuilt",
+ "truth",
],
jni_libs: [
"libdexmakerjvmtiagent",
diff --git a/media/tests/MediaRouter/Android.bp b/media/tests/MediaRouter/Android.bp
index 4cccf89..61b18c8 100644
--- a/media/tests/MediaRouter/Android.bp
+++ b/media/tests/MediaRouter/Android.bp
@@ -24,7 +24,7 @@
"compatibility-device-util-axt",
"mockito-target-minus-junit4",
"testng",
- "truth-prebuilt",
+ "truth",
],
test_suites: ["general-tests"],
platform_apis: true,
diff --git a/media/tests/projection/Android.bp b/media/tests/projection/Android.bp
index e313c46..48cd8b6 100644
--- a/media/tests/projection/Android.bp
+++ b/media/tests/projection/Android.bp
@@ -30,7 +30,7 @@
"platform-test-annotations",
"testng",
"testables",
- "truth-prebuilt",
+ "truth",
"platform-compat-test-rules",
],
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
index ba88484..2318bb9 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/autofill/CredentialAutofillService.kt
@@ -18,21 +18,23 @@
import android.app.assist.AssistStructure
import android.content.Context
-import android.credentials.GetCredentialRequest
import android.credentials.CredentialManager
-import android.credentials.GetCandidateCredentialsResponse
import android.credentials.CredentialOption
import android.credentials.GetCandidateCredentialsException
+import android.credentials.GetCandidateCredentialsResponse
+import android.credentials.GetCredentialRequest
import android.os.Bundle
import android.os.CancellationSignal
import android.os.OutcomeReceiver
-import android.service.autofill.FillRequest
import android.service.autofill.AutofillService
-import android.service.autofill.FillResponse
import android.service.autofill.FillCallback
-import android.service.autofill.SaveRequest
+import android.service.autofill.FillRequest
+import android.service.autofill.FillResponse
import android.service.autofill.SaveCallback
+import android.service.autofill.SaveRequest
+import android.service.credentials.CredentialProviderService
import android.util.Log
+import android.view.autofill.AutofillId
import org.json.JSONObject
import java.util.concurrent.Executors
@@ -129,27 +131,31 @@
}
private fun traverseNode(
- viewNode: AssistStructure.ViewNode?,
+ viewNode: AssistStructure.ViewNode,
cmRequests: MutableList<CredentialOption>
) {
- val options = getCredentialOptionsFromViewNode(viewNode)
- cmRequests.addAll(options)
+ viewNode.autofillId?.let {
+ val options = getCredentialOptionsFromViewNode(viewNode, it)
+ cmRequests.addAll(options)
+ }
- val children: List<AssistStructure.ViewNode>? =
- viewNode?.run {
+ val children: List<AssistStructure.ViewNode> =
+ viewNode.run {
(0 until childCount).map { getChildAt(it) }
}
- children?.forEach { childNode: AssistStructure.ViewNode ->
+ children.forEach { childNode: AssistStructure.ViewNode ->
traverseNode(childNode, cmRequests)
}
}
- private fun getCredentialOptionsFromViewNode(viewNode: AssistStructure.ViewNode?):
- List<CredentialOption> {
+ private fun getCredentialOptionsFromViewNode(
+ viewNode: AssistStructure.ViewNode,
+ autofillId: AutofillId
+ ): List<CredentialOption> {
// TODO(b/293945193) Replace with isCredential check from viewNode
val credentialHints: MutableList<String> = mutableListOf()
- if (viewNode != null && viewNode.autofillHints != null) {
+ if (viewNode.autofillHints != null) {
for (hint in viewNode.autofillHints!!) {
if (hint.startsWith(CRED_HINT_PREFIX)) {
credentialHints.add(hint.substringAfter(CRED_HINT_PREFIX))
@@ -159,12 +165,14 @@
val credentialOptions: MutableList<CredentialOption> = mutableListOf()
for (credentialHint in credentialHints) {
- convertJsonToCredentialOption(credentialHint).let { credentialOptions.addAll(it) }
+ convertJsonToCredentialOption(credentialHint, autofillId)
+ .let { credentialOptions.addAll(it) }
}
return credentialOptions
}
- private fun convertJsonToCredentialOption(jsonString: String): List<CredentialOption> {
+ private fun convertJsonToCredentialOption(jsonString: String, autofillId: AutofillId):
+ List<CredentialOption> {
// TODO(b/302000646) Move this logic to jetpack so that is consistent
// with building the json
val credentialOptions: MutableList<CredentialOption> = mutableListOf()
@@ -173,11 +181,14 @@
val options = json.getJSONArray(CRED_OPTIONS_KEY)
for (i in 0 until options.length()) {
val option = options.getJSONObject(i)
-
+ val candidateBundle = convertJsonToBundle(option.getJSONObject(CANDIDATE_DATA_KEY))
+ candidateBundle.putParcelable(
+ CredentialProviderService.EXTRA_AUTOFILL_ID,
+ autofillId)
credentialOptions.add(CredentialOption(
option.getString(TYPE_KEY),
convertJsonToBundle(option.getJSONObject(REQUEST_DATA_KEY)),
- convertJsonToBundle(option.getJSONObject(CANDIDATE_DATA_KEY)),
+ candidateBundle,
option.getBoolean(SYS_PROVIDER_REQ_KEY),
))
}
diff --git a/packages/ExternalStorageProvider/tests/Android.bp b/packages/ExternalStorageProvider/tests/Android.bp
index 633f186..86c62ef 100644
--- a/packages/ExternalStorageProvider/tests/Android.bp
+++ b/packages/ExternalStorageProvider/tests/Android.bp
@@ -25,7 +25,7 @@
static_libs: [
"androidx.test.rules",
"mockito-target",
- "truth-prebuilt",
+ "truth",
],
certificate: "platform",
diff --git a/packages/FusedLocation/Android.bp b/packages/FusedLocation/Android.bp
index 64b4c54..61a8270 100644
--- a/packages/FusedLocation/Android.bp
+++ b/packages/FusedLocation/Android.bp
@@ -47,7 +47,7 @@
test_config: "test/AndroidTest.xml",
srcs: [
"test/src/**/*.java",
- "src/**/*.java", // include real sources because we're forced to test this directly
+ "src/**/*.java", // include real sources because we're forced to test this directly
],
libs: [
"android.test.base",
@@ -60,9 +60,9 @@
"androidx.test.ext.junit",
"androidx.test.ext.truth",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
platform_apis: true,
certificate: "platform",
- test_suites: ["device-tests"]
+ test_suites: ["device-tests"],
}
diff --git a/packages/InputDevices/res/raw/keyboard_layout_persian.kcm b/packages/InputDevices/res/raw/keyboard_layout_persian.kcm
index 6744922..fc53cba 100644
--- a/packages/InputDevices/res/raw/keyboard_layout_persian.kcm
+++ b/packages/InputDevices/res/raw/keyboard_layout_persian.kcm
@@ -12,9 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
-
-type FULL
+type OVERLAY
### Basic QWERTY keys ###
diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml
index 88bb30b..7f23f74 100644
--- a/packages/InputDevices/res/xml/keyboard_layouts.xml
+++ b/packages/InputDevices/res/xml/keyboard_layouts.xml
@@ -227,13 +227,6 @@
android:label="@string/keyboard_layout_turkish"
android:keyboardLayout="@raw/keyboard_layout_turkish"
android:keyboardLocale="tr-Latn"
- android:keyboardLayoutType="qwerty" />
-
- <keyboard-layout
- android:name="keyboard_layout_turkish"
- android:label="@string/keyboard_layout_turkish"
- android:keyboardLayout="@raw/keyboard_layout_turkish"
- android:keyboardLocale="tr-Latn"
android:keyboardLayoutType="turkish_q" />
<keyboard-layout
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsTextFieldPassword.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsTextFieldPassword.kt
index d0a6188..0757df3 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsTextFieldPassword.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/editor/SettingsTextFieldPassword.kt
@@ -29,8 +29,8 @@
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.remember
import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
@@ -46,6 +46,7 @@
fun SettingsTextFieldPassword(
value: String,
label: String,
+ enabled: Boolean = true,
onTextChange: (String) -> Unit,
) {
var visibility by remember { mutableStateOf(false) }
@@ -60,6 +61,7 @@
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Send
),
+ enabled = enabled,
trailingIcon = {
Icon(
imageVector = if (visibility) Icons.Outlined.VisibilityOff
diff --git a/packages/SettingsLib/Spa/testutils/Android.bp b/packages/SettingsLib/Spa/testutils/Android.bp
index 4031cd7..639d1a7 100644
--- a/packages/SettingsLib/Spa/testutils/Android.bp
+++ b/packages/SettingsLib/Spa/testutils/Android.bp
@@ -31,7 +31,7 @@
"androidx.compose.ui_ui-test-manifest",
"androidx.lifecycle_lifecycle-runtime-testing",
"mockito-kotlin2",
- "truth-prebuilt",
+ "truth",
],
kotlincflags: [
"-Xjvm-default=all",
diff --git a/packages/SettingsLib/tests/integ/Android.bp b/packages/SettingsLib/tests/integ/Android.bp
index b03c43c..4b4caf5 100644
--- a/packages/SettingsLib/tests/integ/Android.bp
+++ b/packages/SettingsLib/tests/integ/Android.bp
@@ -52,7 +52,7 @@
"flag-junit",
"mockito-target-minus-junit4",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
"SettingsLibDeviceStateRotationLock",
"SettingsLibSettingsSpinner",
"SettingsLibUsageProgressBarPreference",
diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp
index dd9cb9c..2d875cf 100644
--- a/packages/SettingsLib/tests/robotests/Android.bp
+++ b/packages/SettingsLib/tests/robotests/Android.bp
@@ -96,6 +96,6 @@
libs: [
"Robolectric_all-target_upstream",
"mockito-robolectric-prebuilt",
- "truth-prebuilt",
+ "truth",
],
}
diff --git a/packages/SettingsLib/tests/unit/Android.bp b/packages/SettingsLib/tests/unit/Android.bp
index 19ab1c6..6d6e2ff 100644
--- a/packages/SettingsLib/tests/unit/Android.bp
+++ b/packages/SettingsLib/tests/unit/Android.bp
@@ -31,6 +31,6 @@
"SettingsLib",
"androidx.test.ext.junit",
"androidx.test.runner",
- "truth-prebuilt",
+ "truth",
],
}
diff --git a/packages/SettingsProvider/Android.bp b/packages/SettingsProvider/Android.bp
index 92ebe09..f4ca260 100644
--- a/packages/SettingsProvider/Android.bp
+++ b/packages/SettingsProvider/Android.bp
@@ -64,7 +64,7 @@
"SettingsLibDeviceStateRotationLock",
"SettingsLibDisplayUtils",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
],
libs: [
"android.test.base",
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 91d2d1b..ba4ad36 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -218,6 +218,7 @@
Settings.Secure.ACCESSIBILITY_FORCE_INVERT_COLOR_ENABLED,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED,
Settings.Secure.ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED,
+ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_GESTURE,
Settings.Secure.ODI_CAPTIONS_VOLUME_UI_ENABLED,
Settings.Secure.NOTIFICATION_BUBBLES,
Settings.Secure.LOCATION_TIME_ZONE_DETECTION_ENABLED,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index bec1447..19fde75 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -308,6 +308,10 @@
VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_FOLLOW_TYPING_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_ALWAYS_ON_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ACCESSIBILITY_MAGNIFICATION_GESTURE,
+ new InclusiveIntegerRangeValidator(
+ Secure.ACCESSIBILITY_MAGNIFICATION_GESTURE_NONE,
+ Secure.ACCESSIBILITY_MAGNIFICATION_GESTURE_ALL));
VALIDATORS.put(
Secure.ACCESSIBILITY_BUTTON_TARGETS,
ACCESSIBILITY_SHORTCUT_TARGET_LIST_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 3c8d4bc..f06b31c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1850,6 +1850,10 @@
SecureSettingsProto.Accessibility
.ACCESSIBILITY_MAGNIFICATION_JOYSTICK_ENABLED);
dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_GESTURE,
+ SecureSettingsProto.Accessibility
+ .ACCESSIBILITY_MAGNIFICATION_GESTURE);
+ dumpSetting(s, p,
Settings.Secure.HEARING_AID_RINGTONE_ROUTING,
SecureSettingsProto.Accessibility.HEARING_AID_RINGTONE_ROUTING);
dumpSetting(s, p,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 40f7ba6..34d3d44 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2054,12 +2054,14 @@
final Uri ringtoneUri = Uri.parse(value);
// Stream selected ringtone into cache, so it's available for playback
// when CE storage is still locked
- try (InputStream in = openRingtone(getContext(), ringtoneUri);
- OutputStream out = new FileOutputStream(cacheFile)) {
- FileUtils.copy(in, out);
- } catch (IOException e) {
- Slog.w(LOG_TAG, "Failed to cache ringtone: " + e);
- }
+ Binder.withCleanCallingIdentity(() -> {
+ try (InputStream in = openRingtone(getContext(), ringtoneUri);
+ OutputStream out = new FileOutputStream(cacheFile)) {
+ FileUtils.copy(in, out);
+ } catch (IOException e) {
+ Slog.w(LOG_TAG, "Failed to cache ringtone: " + e);
+ }
+ });
}
return true;
}
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 3c57852..e40fcb2 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -466,7 +466,7 @@
"hamcrest-library",
"androidx.test.rules",
"testables",
- "truth-prebuilt",
+ "truth",
"monet",
"libmonet",
"dagger2",
@@ -583,7 +583,7 @@
"android.test.runner",
"android.test.base",
"android.test.mock",
- "truth-prebuilt",
+ "truth",
],
upstream: true,
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
index 008732e..96e1e3f 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/AccessibilityMenuService.java
@@ -63,6 +63,7 @@
private static final String TAG = "A11yMenuService";
private static final long BUFFER_MILLISECONDS_TO_PREVENT_UPDATE_FAILURE = 100L;
+ private static final long TAKE_SCREENSHOT_DELAY_MS = 100L;
private static final int BRIGHTNESS_UP_INCREMENT_GAMMA =
(int) Math.ceil(BrightnessUtils.GAMMA_SPACE_MAX * 0.11f);
@@ -301,7 +302,14 @@
} else if (viewTag == ShortcutId.ID_NOTIFICATION_VALUE.ordinal()) {
performGlobalActionInternal(GLOBAL_ACTION_NOTIFICATIONS);
} else if (viewTag == ShortcutId.ID_SCREENSHOT_VALUE.ordinal()) {
- performGlobalActionInternal(GLOBAL_ACTION_TAKE_SCREENSHOT);
+ if (Flags.a11yMenuHideBeforeTakingAction()) {
+ // Delay before taking a screenshot to give time for the UI to close.
+ mHandler.postDelayed(
+ () -> performGlobalActionInternal(GLOBAL_ACTION_TAKE_SCREENSHOT),
+ TAKE_SCREENSHOT_DELAY_MS);
+ } else {
+ performGlobalActionInternal(GLOBAL_ACTION_TAKE_SCREENSHOT);
+ }
}
if (!Flags.a11yMenuHideBeforeTakingAction()) {
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
index 538ecb3..3fc351c 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
+++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/Android.bp
@@ -32,7 +32,7 @@
"androidx.test.ext.junit",
"compatibility-device-util-axt",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
],
srcs: [
"src/**/*.java",
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 437f8af..18117a8 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -13,3 +13,11 @@
description: "Enables all the sysui classic flags that are marked as being in teamfood"
bug: "302578396"
}
+
+flag {
+ name: "notifications_footer_view_refactor"
+ namespace: "systemui"
+ description: "Enables the refactored version of the footer view in the notification shade "
+ "(containing the \"Clear all\" button). Should not bring any behavior changes"
+ bug: "293167744"
+}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
index 0f2e4ba..4aac279 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt
@@ -39,6 +39,7 @@
import android.view.WindowManager
import android.view.animation.Interpolator
import android.view.animation.PathInterpolator
+import androidx.annotation.AnyThread
import androidx.annotation.BinderThread
import androidx.annotation.UiThread
import com.android.app.animation.Interpolators
@@ -149,6 +150,10 @@
override fun onLaunchAnimationProgress(linearProgress: Float) {
listeners.forEach { it.onLaunchAnimationProgress(linearProgress) }
}
+
+ override fun onLaunchAnimationCancelled() {
+ listeners.forEach { it.onLaunchAnimationCancelled() }
+ }
}
/**
@@ -191,6 +196,7 @@
"ActivityLaunchAnimator.callback must be set before using this animator"
)
val runner = createRunner(controller)
+ val runnerDelegate = runner.delegate!!
val hideKeyguardWithAnimation = callback.isOnKeyguard() && !showOverLockscreen
// Pass the RemoteAnimationAdapter to the intent starter only if we are not hiding the
@@ -241,12 +247,15 @@
// If we expect an animation, post a timeout to cancel it in case the remote animation is
// never started.
if (willAnimate) {
- runner.delegate.postTimeout()
+ runnerDelegate.postTimeout()
// Hide the keyguard using the launch animation instead of the default unlock animation.
if (hideKeyguardWithAnimation) {
callback.hideKeyguardWithAnimation(runner)
}
+ } else {
+ // We need to make sure delegate references are dropped to avoid memory leaks.
+ runner.dispose()
}
}
@@ -344,6 +353,13 @@
*/
fun onLaunchAnimationEnd() {}
+ /**
+ * The animation was cancelled. Note that [onLaunchAnimationEnd] will still be called after
+ * this if the animation was already started, i.e. if [onLaunchAnimationStart] was called
+ * before the cancellation.
+ */
+ fun onLaunchAnimationCancelled() {}
+
/** Called when an activity launch animation made progress. */
fun onLaunchAnimationProgress(linearProgress: Float) {}
}
@@ -426,6 +442,39 @@
fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean? = null) {}
}
+ /**
+ * Invokes [onAnimationComplete] when animation is either cancelled or completed. Delegates all
+ * events to the passed [delegate].
+ */
+ @VisibleForTesting
+ inner class DelegatingAnimationCompletionListener(
+ private val delegate: Listener?,
+ private val onAnimationComplete: () -> Unit
+ ) : Listener {
+ var cancelled = false
+
+ override fun onLaunchAnimationStart() {
+ delegate?.onLaunchAnimationStart()
+ }
+
+ override fun onLaunchAnimationProgress(linearProgress: Float) {
+ delegate?.onLaunchAnimationProgress(linearProgress)
+ }
+
+ override fun onLaunchAnimationEnd() {
+ delegate?.onLaunchAnimationEnd()
+ if (!cancelled) {
+ onAnimationComplete.invoke()
+ }
+ }
+
+ override fun onLaunchAnimationCancelled() {
+ cancelled = true
+ delegate?.onLaunchAnimationCancelled()
+ onAnimationComplete.invoke()
+ }
+ }
+
@VisibleForTesting
inner class Runner(
controller: Controller,
@@ -436,11 +485,21 @@
listener: Listener? = null
) : IRemoteAnimationRunner.Stub() {
private val context = controller.launchContainer.context
- internal val delegate: AnimationDelegate
+
+ // This is being passed across IPC boundaries and cycles (through PendingIntentRecords,
+ // etc.) are possible. So we need to make sure we drop any references that might
+ // transitively cause leaks when we're done with animation.
+ @VisibleForTesting var delegate: AnimationDelegate?
init {
delegate =
- AnimationDelegate(controller, callback, listener, launchAnimator, disableWmTimeout)
+ AnimationDelegate(
+ controller,
+ callback,
+ DelegatingAnimationCompletionListener(listener, this::dispose),
+ launchAnimator,
+ disableWmTimeout
+ )
}
@BinderThread
@@ -451,14 +510,33 @@
nonApps: Array<out RemoteAnimationTarget>?,
finishedCallback: IRemoteAnimationFinishedCallback?
) {
+ val delegate = delegate
context.mainExecutor.execute {
- delegate.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback)
+ if (delegate == null) {
+ Log.i(TAG, "onAnimationStart called after completion")
+ // Animation started too late and timed out already. We need to still
+ // signal back that we're done with it.
+ finishedCallback?.onAnimationFinished()
+ } else {
+ delegate.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback)
+ }
}
}
@BinderThread
override fun onAnimationCancelled() {
- context.mainExecutor.execute { delegate.onAnimationCancelled() }
+ val delegate = delegate
+ context.mainExecutor.execute {
+ delegate ?: Log.wtf(TAG, "onAnimationCancelled called after completion")
+ delegate?.onAnimationCancelled()
+ }
+ }
+
+ @AnyThread
+ fun dispose() {
+ // Drop references to animation controller once we're done with the animation
+ // to avoid leaking.
+ context.mainExecutor.execute { delegate = null }
}
}
@@ -584,6 +662,7 @@
)
}
controller.onLaunchAnimationCancelled()
+ listener?.onLaunchAnimationCancelled()
return
}
@@ -821,6 +900,7 @@
Log.d(TAG, "Calling controller.onLaunchAnimationCancelled() [animation timed out]")
}
controller.onLaunchAnimationCancelled()
+ listener?.onLaunchAnimationCancelled()
}
@UiThread
@@ -842,6 +922,7 @@
)
}
controller.onLaunchAnimationCancelled()
+ listener?.onLaunchAnimationCancelled()
}
private fun IRemoteAnimationFinishedCallback.invoke() {
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/AnimateToScene.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/AnimateToScene.kt
index 88944f10..60c3fd3 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/AnimateToScene.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/AnimateToScene.kt
@@ -108,7 +108,7 @@
) {
val fromScene = layoutImpl.state.transitionState.currentScene
val isUserInput =
- (layoutImpl.state.transitionState as? TransitionState.Transition)?.isUserInputDriven
+ (layoutImpl.state.transitionState as? TransitionState.Transition)?.isInitiatedByUserInput
?: false
val animationSpec = layoutImpl.transitions.transitionSpec(fromScene, target).spec
@@ -119,9 +119,23 @@
val targetProgress = if (reversed) 0f else 1f
val transition =
if (reversed) {
- OneOffTransition(target, fromScene, currentScene = target, isUserInput, animatable)
+ OneOffTransition(
+ fromScene = target,
+ toScene = fromScene,
+ currentScene = target,
+ isUserInput,
+ isUserInputOngoing = false,
+ animatable,
+ )
} else {
- OneOffTransition(fromScene, target, currentScene = target, isUserInput, animatable)
+ OneOffTransition(
+ fromScene = fromScene,
+ toScene = target,
+ currentScene = target,
+ isUserInput,
+ isUserInputOngoing = false,
+ animatable,
+ )
}
// Change the current layout state to use this new transition.
@@ -142,7 +156,8 @@
override val fromScene: SceneKey,
override val toScene: SceneKey,
override val currentScene: SceneKey,
- override val isUserInputDriven: Boolean,
+ override val isInitiatedByUserInput: Boolean,
+ override val isUserInputOngoing: Boolean,
private val animatable: Animatable<Float, AnimationVector1D>,
) : TransitionState.Transition {
override val progress: Float
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/ObservableTransitionState.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/ObservableTransitionState.kt
index ccdec6e..1b79dbd 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/ObservableTransitionState.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/ObservableTransitionState.kt
@@ -52,7 +52,14 @@
* scene, this value will remain true after the pointer is no longer touching the screen and
* will be true in any transition created to animate back to the original position.
*/
- val isUserInputDriven: Boolean,
+ val isInitiatedByUserInput: Boolean,
+
+ /**
+ * Whether user input is currently driving the transition. For example, if a user is
+ * dragging a pointer, this emits true. Once they lift their finger, this emits false while
+ * the transition completes/settles.
+ */
+ val isUserInputOngoing: Flow<Boolean>,
) : ObservableTransitionState()
}
@@ -73,7 +80,8 @@
fromScene = state.fromScene,
toScene = state.toScene,
progress = snapshotFlow { state.progress },
- isUserInputDriven = state.isUserInputDriven,
+ isInitiatedByUserInput = state.isInitiatedByUserInput,
+ isUserInputOngoing = snapshotFlow { state.isUserInputOngoing },
)
}
}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayout.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
index 39173d9..58c7bdb 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayout.kt
@@ -130,10 +130,23 @@
sealed interface UserAction
/** The user navigated back, either using a gesture or by triggering a KEYCODE_BACK event. */
-object Back : UserAction
+data object Back : UserAction
/** The user swiped on the container. */
-enum class Swipe : UserAction {
+data class Swipe(
+ val direction: SwipeDirection,
+ val pointerCount: Int = 1,
+ val fromEdge: Edge? = null,
+) : UserAction {
+ companion object {
+ val Left = Swipe(SwipeDirection.Left)
+ val Up = Swipe(SwipeDirection.Up)
+ val Right = Swipe(SwipeDirection.Right)
+ val Down = Swipe(SwipeDirection.Down)
+ }
+}
+
+enum class SwipeDirection {
Up,
Down,
Left,
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
index 7a21211..b9f83c5 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
@@ -70,6 +70,9 @@
val progress: Float
/** Whether the transition was triggered by user input rather than being programmatic. */
- val isUserInputDriven: Boolean
+ val isInitiatedByUserInput: Boolean
+
+ /** Whether user input is currently driving the transition. */
+ val isUserInputOngoing: Boolean
}
}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SwipeToScene.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SwipeToScene.kt
index 1cbfe30..e275fca 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SwipeToScene.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/scene/SwipeToScene.kt
@@ -66,7 +66,7 @@
// swipe in the other direction.
val startDragImmediately =
state == transition &&
- transition.isAnimatingOffset &&
+ !transition.isUserInputOngoing &&
!currentScene.shouldEnableSwipes(orientation.opposite())
// The velocity threshold at which the intent of the user is to swipe up or down. It is the same
@@ -126,7 +126,7 @@
override val progress: Float
get() {
- val offset = if (isAnimatingOffset) offsetAnimatable.value else dragOffset
+ val offset = if (isUserInputOngoing) dragOffset else offsetAnimatable.value
if (distance == 0f) {
// This can happen only if fromScene == toScene.
error(
@@ -137,16 +137,15 @@
return offset / distance
}
- override val isUserInputDriven = true
+ override val isInitiatedByUserInput = true
+
+ var _isUserInputOngoing by mutableStateOf(false)
+ override val isUserInputOngoing: Boolean
+ get() = _isUserInputOngoing
/** The current offset caused by the drag gesture. */
var dragOffset by mutableFloatStateOf(0f)
- /**
- * Whether the offset is animated (the user lifted their finger) or if it is driven by gesture.
- */
- var isAnimatingOffset by mutableStateOf(false)
-
/** The animatable used to animate the offset once the user lifted its finger. */
val offsetAnimatable = Animatable(0f, visibilityThreshold = OffsetVisibilityThreshold)
@@ -209,9 +208,11 @@
transition: SwipeTransition,
orientation: Orientation,
) {
+ transition._isUserInputOngoing = true
+
if (layoutImpl.state.transitionState == transition) {
// This [transition] was already driving the animation: simply take over it.
- if (transition.isAnimatingOffset) {
+ if (!transition.isUserInputOngoing) {
// Stop animating and start from where the current offset. Setting the animation job to
// `null` will effectively cancel the animation.
transition.stopOffsetAnimation()
@@ -456,30 +457,29 @@
) {
transition.startOffsetAnimation {
launch {
- if (!transition.isAnimatingOffset) {
- transition.offsetAnimatable.snapTo(transition.dragOffset)
- }
- transition.isAnimatingOffset = true
-
- transition.offsetAnimatable.animateTo(
- targetOffset,
- // TODO(b/290184746): Make this spring spec configurable.
- spring(
- stiffness = Spring.StiffnessMediumLow,
- visibilityThreshold = OffsetVisibilityThreshold
- ),
- initialVelocity = initialVelocity,
- )
-
- // Now that the animation is done, the state should be idle. Note that if the state
- // was changed since this animation started, some external code changed it and we
- // shouldn't do anything here. Note also that this job will be cancelled in the case
- // where the user intercepts this swipe.
- if (layoutImpl.state.transitionState == transition) {
- layoutImpl.state.transitionState = TransitionState.Idle(targetScene)
- }
+ if (transition.isUserInputOngoing) {
+ transition.offsetAnimatable.snapTo(transition.dragOffset)
}
- .also { it.invokeOnCompletion { transition.isAnimatingOffset = false } }
+ transition._isUserInputOngoing = false
+
+ transition.offsetAnimatable.animateTo(
+ targetOffset,
+ // TODO(b/290184746): Make this spring spec configurable.
+ spring(
+ stiffness = Spring.StiffnessMediumLow,
+ visibilityThreshold = OffsetVisibilityThreshold
+ ),
+ initialVelocity = initialVelocity,
+ )
+
+ // Now that the animation is done, the state should be idle. Note that if the state
+ // was changed since this animation started, some external code changed it and we
+ // shouldn't do anything here. Note also that this job will be cancelled in the case
+ // where the user intercepts this swipe.
+ if (layoutImpl.state.transitionState == transition) {
+ layoutImpl.state.transitionState = TransitionState.Idle(targetScene)
+ }
+ }
}
}
diff --git a/packages/SystemUI/compose/core/tests/Android.bp b/packages/SystemUI/compose/core/tests/Android.bp
index 52c6385..8e9c586 100644
--- a/packages/SystemUI/compose/core/tests/Android.bp
+++ b/packages/SystemUI/compose/core/tests/Android.bp
@@ -43,7 +43,7 @@
"androidx.compose.ui_ui-test-junit4",
"androidx.compose.ui_ui-test-manifest",
- "truth-prebuilt",
+ "truth",
],
kotlincflags: ["-Xjvm-default=all"],
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
index 2232370..53ed2b5 100644
--- a/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/animation/scene/SwipeToSceneTest.kt
@@ -122,7 +122,8 @@
assertThat(transition.toScene).isEqualTo(TestScenes.SceneB)
assertThat(transition.currentScene).isEqualTo(TestScenes.SceneA)
assertThat(transition.progress).isEqualTo(55.dp / LayoutWidth)
- assertThat(transition.isUserInputDriven).isTrue()
+ assertThat(transition.isInitiatedByUserInput).isTrue()
+ assertThat(transition.isUserInputOngoing).isTrue()
// Release the finger. We should now be animating back to A (currentScene = SceneA) given
// that 55dp < positional threshold.
@@ -134,7 +135,8 @@
assertThat(transition.toScene).isEqualTo(TestScenes.SceneB)
assertThat(transition.currentScene).isEqualTo(TestScenes.SceneA)
assertThat(transition.progress).isEqualTo(55.dp / LayoutWidth)
- assertThat(transition.isUserInputDriven).isTrue()
+ assertThat(transition.isInitiatedByUserInput).isTrue()
+ assertThat(transition.isUserInputOngoing).isFalse()
// Wait for the animation to finish. We should now be in scene A.
rule.waitForIdle()
@@ -156,7 +158,8 @@
assertThat(transition.toScene).isEqualTo(TestScenes.SceneC)
assertThat(transition.currentScene).isEqualTo(TestScenes.SceneA)
assertThat(transition.progress).isEqualTo(56.dp / LayoutHeight)
- assertThat(transition.isUserInputDriven).isTrue()
+ assertThat(transition.isInitiatedByUserInput).isTrue()
+ assertThat(transition.isUserInputOngoing).isTrue()
// Release the finger. We should now be animating to C (currentScene = SceneC) given
// that 56dp >= positional threshold.
@@ -168,7 +171,8 @@
assertThat(transition.toScene).isEqualTo(TestScenes.SceneC)
assertThat(transition.currentScene).isEqualTo(TestScenes.SceneC)
assertThat(transition.progress).isEqualTo(56.dp / LayoutHeight)
- assertThat(transition.isUserInputDriven).isTrue()
+ assertThat(transition.isInitiatedByUserInput).isTrue()
+ assertThat(transition.isUserInputOngoing).isFalse()
// Wait for the animation to finish. We should now be in scene C.
rule.waitForIdle()
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
index c3a3752..ee310ab 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/keyguard/ui/composable/LockscreenScene.kt
@@ -36,13 +36,14 @@
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.view.isVisible
import com.android.compose.animation.scene.SceneScope
-import com.android.systemui.res.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.qualifiers.KeyguardRootView
import com.android.systemui.keyguard.ui.viewmodel.KeyguardLongPressViewModel
import com.android.systemui.keyguard.ui.viewmodel.LockscreenSceneViewModel
+import com.android.systemui.res.R
import com.android.systemui.scene.shared.model.Direction
+import com.android.systemui.scene.shared.model.Edge
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.UserAction
@@ -99,7 +100,9 @@
return buildMap {
up?.let { this[UserAction.Swipe(Direction.UP)] = SceneModel(up) }
left?.let { this[UserAction.Swipe(Direction.LEFT)] = SceneModel(left) }
- this[UserAction.Swipe(Direction.DOWN)] = SceneModel(SceneKey.Shade)
+ this[UserAction.Swipe(fromEdge = Edge.TOP, direction = Direction.DOWN)] =
+ SceneModel(SceneKey.QuickSettings)
+ this[UserAction.Swipe(direction = Direction.DOWN)] = SceneModel(SceneKey.Shade)
}
}
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
index 1f9c3e6..a33eac5 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt
@@ -23,11 +23,13 @@
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.android.compose.animation.scene.SceneScope
+import com.android.compose.windowsizeclass.LocalWindowSizeClass
import com.android.systemui.battery.BatteryMeterViewController
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.qs.footer.ui.compose.QuickSettings
@@ -37,6 +39,7 @@
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.UserAction
import com.android.systemui.scene.ui.composable.ComposableScene
+import com.android.systemui.shade.ui.composable.CollapsedShadeHeader
import com.android.systemui.shade.ui.composable.ExpandedShadeHeader
import com.android.systemui.statusbar.phone.StatusBarIconController
import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager
@@ -98,12 +101,22 @@
.clickable(onClick = { viewModel.onContentClicked() })
.padding(start = 16.dp, end = 16.dp, bottom = 48.dp)
) {
- ExpandedShadeHeader(
- viewModel = viewModel.shadeHeaderViewModel,
- createTintedIconManager = createTintedIconManager,
- createBatteryMeterViewController = createBatteryMeterViewController,
- statusBarIconController = statusBarIconController,
- )
+ when (LocalWindowSizeClass.current.widthSizeClass) {
+ WindowWidthSizeClass.Compact ->
+ ExpandedShadeHeader(
+ viewModel = viewModel.shadeHeaderViewModel,
+ createTintedIconManager = createTintedIconManager,
+ createBatteryMeterViewController = createBatteryMeterViewController,
+ statusBarIconController = statusBarIconController,
+ )
+ else ->
+ CollapsedShadeHeader(
+ viewModel = viewModel.shadeHeaderViewModel,
+ createTintedIconManager = createTintedIconManager,
+ createBatteryMeterViewController = createBatteryMeterViewController,
+ statusBarIconController = statusBarIconController,
+ )
+ }
Spacer(modifier = Modifier.height(16.dp))
QuickSettings()
}
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
index 2ee461f..f35ea83 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/GoneScene.kt
@@ -22,6 +22,7 @@
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.scene.shared.model.Direction
+import com.android.systemui.scene.shared.model.Edge
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
import com.android.systemui.scene.shared.model.UserAction
@@ -41,7 +42,12 @@
override val destinationScenes: StateFlow<Map<UserAction, SceneModel>> =
MutableStateFlow<Map<UserAction, SceneModel>>(
mapOf(
- UserAction.Swipe(Direction.DOWN) to SceneModel(SceneKey.Shade),
+ UserAction.Swipe(
+ pointerCount = 2,
+ fromEdge = Edge.TOP,
+ direction = Direction.DOWN,
+ ) to SceneModel(SceneKey.QuickSettings),
+ UserAction.Swipe(direction = Direction.DOWN) to SceneModel(SceneKey.Shade),
)
)
.asStateFlow()
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
index ef01266..0da562b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainer.kt
@@ -35,15 +35,18 @@
import androidx.compose.ui.input.pointer.motionEventSpy
import androidx.compose.ui.input.pointer.pointerInput
import com.android.compose.animation.scene.Back
+import com.android.compose.animation.scene.Edge as SceneTransitionEdge
import com.android.compose.animation.scene.ObservableTransitionState as SceneTransitionObservableTransitionState
import com.android.compose.animation.scene.SceneKey as SceneTransitionSceneKey
import com.android.compose.animation.scene.SceneTransitionLayout
import com.android.compose.animation.scene.SceneTransitionLayoutState
import com.android.compose.animation.scene.Swipe
+import com.android.compose.animation.scene.SwipeDirection
import com.android.compose.animation.scene.UserAction as SceneTransitionUserAction
import com.android.compose.animation.scene.observableTransitionState
import com.android.systemui.ribbon.ui.composable.BottomRightCornerRibbon
import com.android.systemui.scene.shared.model.Direction
+import com.android.systemui.scene.shared.model.Edge
import com.android.systemui.scene.shared.model.ObservableTransitionState
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.scene.shared.model.SceneModel
@@ -158,7 +161,8 @@
fromScene = fromScene.toModel().key,
toScene = toScene.toModel().key,
progress = progress,
- isUserInputDriven = isUserInputDriven,
+ isInitiatedByUserInput = isInitiatedByUserInput,
+ isUserInputOngoing = isUserInputOngoing,
)
}
}
@@ -180,12 +184,24 @@
private fun UserAction.toTransitionUserAction(): SceneTransitionUserAction {
return when (this) {
is UserAction.Swipe ->
- when (this.direction) {
- Direction.LEFT -> Swipe.Left
- Direction.UP -> Swipe.Up
- Direction.RIGHT -> Swipe.Right
- Direction.DOWN -> Swipe.Down
- }
+ Swipe(
+ pointerCount = pointerCount,
+ fromEdge =
+ when (this.fromEdge) {
+ null -> null
+ Edge.LEFT -> SceneTransitionEdge.Left
+ Edge.TOP -> SceneTransitionEdge.Top
+ Edge.RIGHT -> SceneTransitionEdge.Right
+ Edge.BOTTOM -> SceneTransitionEdge.Bottom
+ },
+ direction =
+ when (this.direction) {
+ Direction.LEFT -> SwipeDirection.Left
+ Direction.UP -> SwipeDirection.Up
+ Direction.RIGHT -> SwipeDirection.Right
+ Direction.DOWN -> SwipeDirection.Down
+ }
+ )
is UserAction.Back -> Back
}
}
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 6629a25..591fa76 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
@@ -30,6 +30,7 @@
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
+import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
@@ -50,6 +51,7 @@
import com.android.compose.animation.scene.SceneScope
import com.android.compose.animation.scene.ValueKey
import com.android.compose.animation.scene.animateSharedFloatAsState
+import com.android.compose.windowsizeclass.LocalWindowSizeClass
import com.android.settingslib.Utils
import com.android.systemui.battery.BatteryMeterView
import com.android.systemui.battery.BatteryMeterViewController
@@ -98,12 +100,12 @@
ShadeHeader.Keys.transitionProgress,
ShadeHeader.Elements.FormatPlaceholder
)
- val useExpandedFormat by
- remember(formatProgress) { derivedStateOf { formatProgress.value > 0.5f } }
val cutoutWidth = LocalDisplayCutout.current.width()
val cutoutLocation = LocalDisplayCutout.current.location
+ val useExpandedFormat = formatProgress.value > 0.5f || cutoutLocation != CutoutLocation.CENTER
+
// This layout assumes it is globally positioned at (0, 0) and is the
// same size as the screen.
Layout(
@@ -131,6 +133,14 @@
{
Row(horizontalArrangement = Arrangement.End) {
SystemIconContainer {
+ when (LocalWindowSizeClass.current.widthSizeClass) {
+ WindowWidthSizeClass.Medium,
+ WindowWidthSizeClass.Expanded ->
+ ShadeCarrierGroup(
+ viewModel = viewModel,
+ modifier = Modifier.align(Alignment.CenterVertically),
+ )
+ }
StatusIcons(
viewModel = viewModel,
createTintedIconManager = createTintedIconManager,
diff --git a/packages/SystemUI/customization/res/values-af/strings.xml b/packages/SystemUI/customization/res/values-af/strings.xml
new file mode 100644
index 0000000..4c2c627
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-af/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Verstek vir digitaal"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-am/strings.xml b/packages/SystemUI/customization/res/values-am/strings.xml
new file mode 100644
index 0000000..847d7a5
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-am/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ዲጂታል ነባሪ"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ar/strings.xml b/packages/SystemUI/customization/res/values-ar/strings.xml
new file mode 100644
index 0000000..57d1612
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ar/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"رقمية تلقائية"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-as/strings.xml b/packages/SystemUI/customization/res/values-as/strings.xml
new file mode 100644
index 0000000..2f3b64b
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-as/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ডিজিটেল ডিফ’ল্ট"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-az/strings.xml b/packages/SystemUI/customization/res/values-az/strings.xml
new file mode 100644
index 0000000..eb52f95
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-az/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Rəqəmsal defolt"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/customization/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..90e6678
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitalni podrazumevani"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-be/strings.xml b/packages/SystemUI/customization/res/values-be/strings.xml
new file mode 100644
index 0000000..f327da2
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-be/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"электронны, стандартны шрыфт"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-bg/strings.xml b/packages/SystemUI/customization/res/values-bg/strings.xml
new file mode 100644
index 0000000..6e3754a
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-bg/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Стандартно дигитално"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-bn/strings.xml b/packages/SystemUI/customization/res/values-bn/strings.xml
new file mode 100644
index 0000000..adf1256
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-bn/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ডিজিটাল ডিফল্ট"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-bs/strings.xml b/packages/SystemUI/customization/res/values-bs/strings.xml
new file mode 100644
index 0000000..8de04ab
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-bs/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitalno zadano"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ca/strings.xml b/packages/SystemUI/customization/res/values-ca/strings.xml
new file mode 100644
index 0000000..967bb3f
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ca/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital predeterminat"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-cs/strings.xml b/packages/SystemUI/customization/res/values-cs/strings.xml
new file mode 100644
index 0000000..45da4d7
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-cs/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitální výchozí"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-da/strings.xml b/packages/SystemUI/customization/res/values-da/strings.xml
new file mode 100644
index 0000000..3ffaa8b
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-da/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Standard (digital)"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-de/strings.xml b/packages/SystemUI/customization/res/values-de/strings.xml
new file mode 100644
index 0000000..64f95e0
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-de/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital (Standard)"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-el/strings.xml b/packages/SystemUI/customization/res/values-el/strings.xml
new file mode 100644
index 0000000..57134b5
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-el/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Ψηφιακή προεπιλογή"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-en-rAU/strings.xml b/packages/SystemUI/customization/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..a6110d5
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-en-rAU/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital default"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-en-rCA/strings.xml b/packages/SystemUI/customization/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..79919c0
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-en-rCA/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for clock_default_description (5309401440896597541) -->
+ <skip />
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-en-rGB/strings.xml b/packages/SystemUI/customization/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..a6110d5
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-en-rGB/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital default"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-en-rIN/strings.xml b/packages/SystemUI/customization/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..a6110d5
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-en-rIN/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital default"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-en-rXC/strings.xml b/packages/SystemUI/customization/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..7c540da
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-en-rXC/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital default"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-es-rUS/strings.xml b/packages/SystemUI/customization/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..59be786
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-es-rUS/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Configuración predeterminada digital"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-es/strings.xml b/packages/SystemUI/customization/res/values-es/strings.xml
new file mode 100644
index 0000000..03ef0e5
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-es/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital predeterminada"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-et/strings.xml b/packages/SystemUI/customization/res/values-et/strings.xml
new file mode 100644
index 0000000..fec793e
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-et/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitaalne vaikimisi"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-eu/strings.xml b/packages/SystemUI/customization/res/values-eu/strings.xml
new file mode 100644
index 0000000..a70c808
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-eu/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital lehenetsia"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-fa/strings.xml b/packages/SystemUI/customization/res/values-fa/strings.xml
new file mode 100644
index 0000000..6426d51
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-fa/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"دیجیتال پیشفرض"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-fi/strings.xml b/packages/SystemUI/customization/res/values-fi/strings.xml
new file mode 100644
index 0000000..9b19373
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-fi/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitaalinen (oletus)"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-fr-rCA/strings.xml b/packages/SystemUI/customization/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..bbd1208
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-fr-rCA/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Numérique, par défaut"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-fr/strings.xml b/packages/SystemUI/customization/res/values-fr/strings.xml
new file mode 100644
index 0000000..5579a42
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-fr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Numérique par défaut"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-gl/strings.xml b/packages/SystemUI/customization/res/values-gl/strings.xml
new file mode 100644
index 0000000..2da93c6
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-gl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Predeterminada dixital"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-gu/strings.xml b/packages/SystemUI/customization/res/values-gu/strings.xml
new file mode 100644
index 0000000..c578a2e
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-gu/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ડિજિટલ ડિફૉલ્ટ"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-hi/strings.xml b/packages/SystemUI/customization/res/values-hi/strings.xml
new file mode 100644
index 0000000..6080f80
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-hi/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"डिजिटल डिफ़ॉल्ट"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-hr/strings.xml b/packages/SystemUI/customization/res/values-hr/strings.xml
new file mode 100644
index 0000000..0a1440f
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-hr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitalni zadani"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-hu/strings.xml b/packages/SystemUI/customization/res/values-hu/strings.xml
new file mode 100644
index 0000000..32618a8
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-hu/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitális, alapértelmezett"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-hy/strings.xml b/packages/SystemUI/customization/res/values-hy/strings.xml
new file mode 100644
index 0000000..d45afbf
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-hy/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Թվային, կանխադրված"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-in/strings.xml b/packages/SystemUI/customization/res/values-in/strings.xml
new file mode 100644
index 0000000..a6110d5
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-in/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital default"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-is/strings.xml b/packages/SystemUI/customization/res/values-is/strings.xml
new file mode 100644
index 0000000..5a370d6
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-is/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Stafræn, sjálfgefið"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-it/strings.xml b/packages/SystemUI/customization/res/values-it/strings.xml
new file mode 100644
index 0000000..2a5087d
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-it/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitale - predefinito"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-iw/strings.xml b/packages/SystemUI/customization/res/values-iw/strings.xml
new file mode 100644
index 0000000..ddd28f2
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-iw/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"דיגיטלי ברירת מחדל"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ja/strings.xml b/packages/SystemUI/customization/res/values-ja/strings.xml
new file mode 100644
index 0000000..744604a
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ja/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"デジタル デフォルト"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ka/strings.xml b/packages/SystemUI/customization/res/values-ka/strings.xml
new file mode 100644
index 0000000..88ba1df
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ka/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ციფრული ნაგულისხმევი"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-kk/strings.xml b/packages/SystemUI/customization/res/values-kk/strings.xml
new file mode 100644
index 0000000..9ee6522
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-kk/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Цифрлық әдепкі"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-km/strings.xml b/packages/SystemUI/customization/res/values-km/strings.xml
new file mode 100644
index 0000000..bbc438a
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-km/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"លំនាំដើមឌីជីថល"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-kn/strings.xml b/packages/SystemUI/customization/res/values-kn/strings.xml
new file mode 100644
index 0000000..e67319d
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-kn/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ಡಿಜಿಟಲ್ ಡೀಫಾಲ್ಟ್"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ko/strings.xml b/packages/SystemUI/customization/res/values-ko/strings.xml
new file mode 100644
index 0000000..fa9103b
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ko/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"디지털 기본"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ky/strings.xml b/packages/SystemUI/customization/res/values-ky/strings.xml
new file mode 100644
index 0000000..76cc5e2
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ky/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Демейки санариптик"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-lo/strings.xml b/packages/SystemUI/customization/res/values-lo/strings.xml
new file mode 100644
index 0000000..28f5000
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-lo/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ດິຈິຕອນຕາມຄ່າເລີ່ມຕົ້ນ"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-lt/strings.xml b/packages/SystemUI/customization/res/values-lt/strings.xml
new file mode 100644
index 0000000..2fe7315
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-lt/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Skaitmeninis numatytasis"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-lv/strings.xml b/packages/SystemUI/customization/res/values-lv/strings.xml
new file mode 100644
index 0000000..e0b904a
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-lv/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitālais pulkstenis — noklusējums"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-mk/strings.xml b/packages/SystemUI/customization/res/values-mk/strings.xml
new file mode 100644
index 0000000..9b95a6e
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-mk/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Дигитален стандарден приказ"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ml/strings.xml b/packages/SystemUI/customization/res/values-ml/strings.xml
new file mode 100644
index 0000000..7f6be8a
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ml/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ഡിജിറ്റൽ ഡിഫോൾട്ട്"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-mn/strings.xml b/packages/SystemUI/customization/res/values-mn/strings.xml
new file mode 100644
index 0000000..38369b6
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-mn/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Дижитал өгөгдмөл"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-mr/strings.xml b/packages/SystemUI/customization/res/values-mr/strings.xml
new file mode 100644
index 0000000..821ff10
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-mr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"डिजिटल डीफॉल्टसह क्लॉक फेस"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ms/strings.xml b/packages/SystemUI/customization/res/values-ms/strings.xml
new file mode 100644
index 0000000..2f61b47
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ms/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital lalai"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-my/strings.xml b/packages/SystemUI/customization/res/values-my/strings.xml
new file mode 100644
index 0000000..3d137eb
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-my/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ဒစ်ဂျစ်တယ်နာရီ မူရင်း"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-nb/strings.xml b/packages/SystemUI/customization/res/values-nb/strings.xml
new file mode 100644
index 0000000..6eb4373
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-nb/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital – standard"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ne/strings.xml b/packages/SystemUI/customization/res/values-ne/strings.xml
new file mode 100644
index 0000000..c5b0877
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ne/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"डिजिटल डिफल्ट"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-nl/strings.xml b/packages/SystemUI/customization/res/values-nl/strings.xml
new file mode 100644
index 0000000..4f46ab8
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-nl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Standaard digitaal"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-or/strings.xml b/packages/SystemUI/customization/res/values-or/strings.xml
new file mode 100644
index 0000000..a74017f
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-or/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ଡିଜିଟାଲ ଡିଫଲ୍ଟ"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-pa/strings.xml b/packages/SystemUI/customization/res/values-pa/strings.xml
new file mode 100644
index 0000000..a77661a
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-pa/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ਡਿਜੀਟਲ ਡਿਫਾਲਟ"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-pl/strings.xml b/packages/SystemUI/customization/res/values-pl/strings.xml
new file mode 100644
index 0000000..6f5b6f2
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-pl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Cyfrowa domyślna"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-pt-rPT/strings.xml b/packages/SystemUI/customization/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..c6c3cc0
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-pt-rPT/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Predefinição digital"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-pt/strings.xml b/packages/SystemUI/customization/res/values-pt/strings.xml
new file mode 100644
index 0000000..bbe4355
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-pt/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital padrão"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ro/strings.xml b/packages/SystemUI/customization/res/values-ro/strings.xml
new file mode 100644
index 0000000..ef163e9
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ro/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Implicit digital"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ru/strings.xml b/packages/SystemUI/customization/res/values-ru/strings.xml
new file mode 100644
index 0000000..5ee928e
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ru/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Цифровые часы, стандартный"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-si/strings.xml b/packages/SystemUI/customization/res/values-si/strings.xml
new file mode 100644
index 0000000..caf9610
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-si/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ඩිජිටල් පෙරනිමිය"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-sk/strings.xml b/packages/SystemUI/customization/res/values-sk/strings.xml
new file mode 100644
index 0000000..1843f97
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-sk/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitálne predvolené"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-sl/strings.xml b/packages/SystemUI/customization/res/values-sl/strings.xml
new file mode 100644
index 0000000..12df66f
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-sl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digitalna (privzeta)"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-sq/strings.xml b/packages/SystemUI/customization/res/values-sq/strings.xml
new file mode 100644
index 0000000..1fc9f25
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-sq/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Dixhitale e parazgjedhur"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-sr/strings.xml b/packages/SystemUI/customization/res/values-sr/strings.xml
new file mode 100644
index 0000000..6b127c9
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-sr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Дигитални подразумевани"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-sv/strings.xml b/packages/SystemUI/customization/res/values-sv/strings.xml
new file mode 100644
index 0000000..84ad25c
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-sv/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital standard"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-sw/strings.xml b/packages/SystemUI/customization/res/values-sw/strings.xml
new file mode 100644
index 0000000..e2ec3de
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-sw/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Dijitali chaguomsingi"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ta/strings.xml b/packages/SystemUI/customization/res/values-ta/strings.xml
new file mode 100644
index 0000000..f4eea07
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ta/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"டிஜிட்டல் இயல்பு"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-te/strings.xml b/packages/SystemUI/customization/res/values-te/strings.xml
new file mode 100644
index 0000000..c7c77d5
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-te/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"డిజిటల్ ఆటోమేటిక్ సెట్టింగ్"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-th/strings.xml b/packages/SystemUI/customization/res/values-th/strings.xml
new file mode 100644
index 0000000..61d880e
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-th/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ดิจิทัลแบบเริ่มต้น"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-tl/strings.xml b/packages/SystemUI/customization/res/values-tl/strings.xml
new file mode 100644
index 0000000..a3484a7
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-tl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Digital na default"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-tr/strings.xml b/packages/SystemUI/customization/res/values-tr/strings.xml
new file mode 100644
index 0000000..a90e985
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-tr/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Dijital varsayılan"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-uk/strings.xml b/packages/SystemUI/customization/res/values-uk/strings.xml
new file mode 100644
index 0000000..ee9b77b
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-uk/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Цифровий, стандартний"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-ur/strings.xml b/packages/SystemUI/customization/res/values-ur/strings.xml
new file mode 100644
index 0000000..06a6a7c
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-ur/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"ڈیجیٹل ڈیفالٹ"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-uz/strings.xml b/packages/SystemUI/customization/res/values-uz/strings.xml
new file mode 100644
index 0000000..6b31b04
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-uz/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Raqamli soat, standart"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-vi/strings.xml b/packages/SystemUI/customization/res/values-vi/strings.xml
new file mode 100644
index 0000000..830b6e2
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-vi/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Mặt số mặc định"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-zh-rCN/strings.xml b/packages/SystemUI/customization/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..747567e
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-zh-rCN/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"默认数字"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-zh-rHK/strings.xml b/packages/SystemUI/customization/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..c19cc68
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-zh-rHK/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"數碼時鐘 (預設)"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-zh-rTW/strings.xml b/packages/SystemUI/customization/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..6fcd313
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-zh-rTW/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"數位預設"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values-zu/strings.xml b/packages/SystemUI/customization/res/values-zu/strings.xml
new file mode 100644
index 0000000..c87c250a
--- /dev/null
+++ b/packages/SystemUI/customization/res/values-zu/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="clock_default_description" msgid="5309401440896597541">"Okuzenzakalelayo kwedijithali"</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/res/values/strings.xml b/packages/SystemUI/customization/res/values/strings.xml
new file mode 100644
index 0000000..897c842
--- /dev/null
+++ b/packages/SystemUI/customization/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2023, 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- default clock face name [CHAR LIMIT=NONE]-->
+ <string name="clock_default_name">Default</string>
+
+ <!-- default clock face description [CHAR LIMIT=NONE]-->
+ <string name="clock_default_description">Digital default</string>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
index b28920c..b076b2c 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
@@ -65,7 +65,13 @@
protected var onSecondaryDisplay: Boolean = false
override val events: DefaultClockEvents
- override val config = ClockConfig(DEFAULT_CLOCK_ID)
+ override val config: ClockConfig by lazy {
+ ClockConfig(
+ DEFAULT_CLOCK_ID,
+ resources.getString(R.string.clock_default_name),
+ resources.getString(R.string.clock_default_description)
+ )
+ }
init {
val parent = FrameLayout(ctx)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
index 949641a..dd52e39 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
@@ -25,7 +25,6 @@
import com.android.systemui.plugins.ClockSettings
private val TAG = DefaultClockProvider::class.simpleName
-const val DEFAULT_CLOCK_NAME = "Default Clock"
const val DEFAULT_CLOCK_ID = "DEFAULT"
/** Provides the default system clock */
@@ -35,8 +34,7 @@
val resources: Resources,
val hasStepClockAnimation: Boolean = false
) : ClockProvider {
- override fun getClocks(): List<ClockMetadata> =
- listOf(ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME))
+ override fun getClocks(): List<ClockMetadata> = listOf(ClockMetadata(DEFAULT_CLOCK_ID))
override fun createClock(settings: ClockSettings): ClockController {
if (settings.clockId != DEFAULT_CLOCK_ID) {
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
index e2f4793..485c27e 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
@@ -192,15 +192,18 @@
/** Some data about a clock design */
data class ClockMetadata(
val clockId: ClockId,
- val name: String,
-) {
- constructor(clockId: ClockId) : this(clockId, clockId) {}
-}
+)
/** Render configuration for the full clock. Modifies the way systemUI behaves with this clock. */
data class ClockConfig(
val id: String,
+ /** Localized name of the clock */
+ val name: String,
+
+ /** Localized accessibility description for the clock */
+ val description: String,
+
/** Transition to AOD should move smartspace like large clock instead of small clock */
val useAlternateSmartspaceAODTransition: Boolean = false,
diff --git a/packages/SystemUI/res-keyguard/layout/alternate_bouncer.xml b/packages/SystemUI/res-keyguard/layout/alternate_bouncer.xml
new file mode 100644
index 0000000..2187352
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/alternate_bouncer.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 2023 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.
+ ~
+ -->
+
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:sysui="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/alternate_bouncer"
+ android:focusable="true"
+ android:clickable="true"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.android.systemui.scrim.ScrimView
+ android:id="@+id/alternate_bouncer_scrim"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:importantForAccessibility="no"
+ sysui:ignoreRightInset="true"
+ />
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml
index d4b73a4..acee425 100644
--- a/packages/SystemUI/res/layout/super_notification_shade.xml
+++ b/packages/SystemUI/res/layout/super_notification_shade.xml
@@ -130,6 +130,11 @@
android:inflatedId="@+id/multi_shade"
android:layout="@layout/multi_shade" />
+ <include layout="@layout/alternate_bouncer"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:visibility="invisible" />
+
<com.android.systemui.biometrics.AuthRippleView
android:id="@+id/auth_ripple"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
index 0094820..a6e04ce 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
@@ -23,6 +23,7 @@
import android.window.PictureInPictureSurfaceTransaction;
import android.window.TaskSnapshot;
+import com.android.internal.os.IResultReceiver;
import com.android.systemui.shared.recents.model.ThumbnailData;
public class RecentsAnimationControllerCompat {
@@ -89,11 +90,16 @@
* @param sendUserLeaveHint determines whether userLeaveHint will be set true to the previous
* app.
*/
- public void finish(boolean toHome, boolean sendUserLeaveHint) {
+ public void finish(boolean toHome, boolean sendUserLeaveHint, IResultReceiver finishCb) {
try {
- mAnimationController.finish(toHome, sendUserLeaveHint);
+ mAnimationController.finish(toHome, sendUserLeaveHint, finishCb);
} catch (RemoteException e) {
Log.e(TAG, "Failed to finish recents animation", e);
+ try {
+ finishCb.send(0, null);
+ } catch (Exception ex) {
+ // Local call, can ignore
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index bb0cf6d4..eb7a735 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -34,7 +34,6 @@
import com.android.systemui.customization.R
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.dagger.qualifiers.DisplaySpecific
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags.DOZING_MIGRATION_1
@@ -80,8 +79,8 @@
private val batteryController: BatteryController,
private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
private val configurationController: ConfigurationController,
- @DisplaySpecific private val resources: Resources,
- @DisplaySpecific private val context: Context,
+ @Main private val resources: Resources,
+ private val context: Context,
@Main private val mainExecutor: DelayableExecutor,
@Background private val bgExecutor: Executor,
@KeyguardSmallClockLog private val smallLogBuffer: LogBuffer?,
@@ -212,13 +211,13 @@
if (regionSamplingEnabled) {
clock?.let { clock ->
smallRegionSampler?.let {
- smallClockIsDark = it.currentRegionDarkness().isDark
- clock.smallClock.events.onRegionDarknessChanged(smallClockIsDark)
+ val isRegionDark = it.currentRegionDarkness().isDark
+ clock.smallClock.events.onRegionDarknessChanged(isRegionDark)
}
largeRegionSampler?.let {
- largeClockIsDark = it.currentRegionDarkness().isDark
- clock.largeClock.events.onRegionDarknessChanged(largeClockIsDark)
+ val isRegionDark = it.currentRegionDarkness().isDark
+ clock.largeClock.events.onRegionDarknessChanged(isRegionDark)
}
}
return
@@ -226,12 +225,12 @@
val isLightTheme = TypedValue()
context.theme.resolveAttribute(android.R.attr.isLightTheme, isLightTheme, true)
- smallClockIsDark = isLightTheme.data == 0
- largeClockIsDark = isLightTheme.data == 0
+ val isRegionDark = isLightTheme.data == 0
clock?.run {
- smallClock.events.onRegionDarknessChanged(smallClockIsDark)
- largeClock.events.onRegionDarknessChanged(largeClockIsDark)
+ Log.i(TAG, "Region isDark: $isRegionDark")
+ smallClock.events.onRegionDarknessChanged(isRegionDark)
+ largeClock.events.onRegionDarknessChanged(isRegionDark)
}
}
protected open fun createRegionSampler(
@@ -261,9 +260,6 @@
get() = isKeyguardVisible && dozeAmount < DOZE_TICKRATE_THRESHOLD
private var cachedWeatherData: WeatherData? = null
- private var smallClockIsDark = true
- private var largeClockIsDark = true
-
private val configListener =
object : ConfigurationController.ConfigurationListener {
override fun onThemeChanged() {
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconView.java b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
index 1d2d77f..40d0be1 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconView.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconView.java
@@ -18,6 +18,7 @@
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
@@ -68,6 +69,7 @@
private boolean mUseBackground = false;
private float mDozeAmount = 0f;
+ @SuppressLint("ClickableViewAccessibility")
public LockIconView(Context context, AttributeSet attrs) {
super(context, attrs);
mSensorRect = new RectF();
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
index 9b00b5f..0d3f726 100644
--- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
+++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java
@@ -29,6 +29,7 @@
import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION;
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -57,11 +58,11 @@
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import com.android.systemui.Dumpable;
-import com.android.systemui.res.R;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.AuthRippleController;
import com.android.systemui.biometrics.UdfpsController;
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams;
+import com.android.systemui.bouncer.domain.interactor.BouncerInteractor;
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
@@ -73,12 +74,16 @@
import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.res.R;
+import com.android.systemui.scene.shared.flag.SceneContainerFlags;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.DelayableExecutor;
+import dagger.Lazy;
+
import java.io.PrintWriter;
import java.util.Objects;
import java.util.function.Consumer;
@@ -127,6 +132,8 @@
@NonNull private final KeyguardTransitionInteractor mTransitionInteractor;
@NonNull private final KeyguardInteractor mKeyguardInteractor;
@NonNull private final View.AccessibilityDelegate mAccessibilityDelegate;
+ @NonNull private final Lazy<BouncerInteractor> mBouncerInteractor;
+ @NonNull private final SceneContainerFlags mSceneContainerFlags;
// Tracks the velocity of a touch to help filter out the touches that move too fast.
private VelocityTracker mVelocityTracker;
@@ -203,7 +210,9 @@
@NonNull KeyguardInteractor keyguardInteractor,
@NonNull FeatureFlags featureFlags,
PrimaryBouncerInteractor primaryBouncerInteractor,
- Context context
+ Context context,
+ Lazy<BouncerInteractor> bouncerInteractor,
+ SceneContainerFlags sceneContainerFlags
) {
mStatusBarStateController = statusBarStateController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
@@ -232,6 +241,8 @@
dumpManager.registerDumpable(TAG, this);
mResources = resources;
mContext = context;
+ mBouncerInteractor = bouncerInteractor;
+ mSceneContainerFlags = sceneContainerFlags;
mAccessibilityDelegate = new View.AccessibilityDelegate() {
private final AccessibilityNodeInfo.AccessibilityAction mAccessibilityAuthenticateHint =
@@ -256,6 +267,7 @@
}
/** Sets the LockIconView to the controller and rebinds any that depend on it. */
+ @SuppressLint("ClickableViewAccessibility")
public void setLockIconView(LockIconView lockIconView) {
mView = lockIconView;
mView.setImageDrawable(mIcon);
@@ -305,6 +317,8 @@
if (lockIconView.isAttachedToWindow()) {
registerCallbacks();
}
+
+ lockIconView.setOnTouchListener((view, motionEvent) -> onTouchEvent(motionEvent));
}
private void registerCallbacks() {
@@ -635,19 +649,18 @@
};
/**
- * Handles the touch if it is within the lock icon view and {@link #isActionable()} is true.
+ * Handles the touch if {@link #isActionable()} is true.
* Subsequently, will trigger {@link #onLongPress()} if a touch is continuously in the lock icon
* area for {@link #mLongPressTimeout} ms.
*
* Touch speed debouncing mimics logic from the velocity tracker in {@link UdfpsController}.
*/
- public boolean onTouchEvent(MotionEvent event, Runnable onGestureDetectedRunnable) {
- if (!onInterceptTouchEvent(event)) {
+ private boolean onTouchEvent(MotionEvent event) {
+ if (!actionableDownEventStartedOnView(event)) {
cancelTouches();
return false;
}
- mOnGestureDetectedRunnable = onGestureDetectedRunnable;
switch(event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_HOVER_ENTER:
@@ -700,12 +713,8 @@
return true;
}
- /**
- * Intercepts the touch if the onDown event and current event are within this lock icon view's
- * bounds.
- */
- public boolean onInterceptTouchEvent(MotionEvent event) {
- if (!inLockIconArea(event) || !isActionable()) {
+ private boolean actionableDownEventStartedOnView(MotionEvent event) {
+ if (!isActionable()) {
return false;
}
@@ -716,7 +725,8 @@
return mDownDetected;
}
- private void onLongPress() {
+ @VisibleForTesting
+ protected void onLongPress() {
cancelTouches();
if (mFalsingManager.isFalseLongTap(FalsingManager.LOW_PENALTY)) {
Log.v(TAG, "lock icon long-press rejected by the falsing manager.");
@@ -729,14 +739,15 @@
mAuthRippleController.showUnlockRipple(FINGERPRINT);
}
updateVisibility();
- if (mOnGestureDetectedRunnable != null) {
- mOnGestureDetectedRunnable.run();
- }
// play device entry haptic (consistent with UDFPS controller longpress)
vibrateOnLongPress();
- mKeyguardViewController.showPrimaryBouncer(/* scrim */ true);
+ if (mSceneContainerFlags.isEnabled()) {
+ mBouncerInteractor.get().showOrUnlockDevice(null);
+ } else {
+ mKeyguardViewController.showPrimaryBouncer(/* scrim */ true);
+ }
}
@@ -751,12 +762,6 @@
}
}
- private boolean inLockIconArea(MotionEvent event) {
- mView.getHitRect(mSensorTouchLocation);
- return mSensorTouchLocation.contains((int) event.getX(), (int) event.getY())
- && mView.getVisibility() == View.VISIBLE;
- }
-
private boolean isActionable() {
if (mIsBouncerShowing) {
Log.v(TAG, "lock icon long-press ignored, bouncer already showing.");
@@ -834,6 +839,19 @@
}
};
+ /**
+ * Whether the lock icon will handle a touch while dozing.
+ */
+ public boolean willHandleTouchWhileDozing(MotionEvent event) {
+ // is in lock icon area
+ mView.getHitRect(mSensorTouchLocation);
+ final boolean inLockIconArea =
+ mSensorTouchLocation.contains((int) event.getX(), (int) event.getY())
+ && mView.getVisibility() == View.VISIBLE;
+
+ return inLockIconArea && actionableDownEventStartedOnView(event);
+ }
+
private final View.OnClickListener mA11yClickListener = v -> onLongPress();
private final AccessibilityManager.AccessibilityStateChangeListener
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 0180384..7739021 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -87,7 +87,6 @@
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
-import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager;
import com.android.systemui.statusbar.phone.AutoHideController;
@@ -130,14 +129,14 @@
import com.android.systemui.util.leak.LeakReporter;
import com.android.systemui.util.sensors.AsyncSensorManager;
+import dagger.Lazy;
+
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import javax.inject.Inject;
import javax.inject.Named;
-import dagger.Lazy;
-
/**
* Class to handle ugly dependencies throughout sysui until we determine the
* long-term dependency injection solution.
@@ -298,7 +297,6 @@
@Inject Lazy<AccessibilityFloatingMenuController> mAccessibilityFloatingMenuController;
@Inject Lazy<StatusBarStateController> mStatusBarStateController;
@Inject Lazy<NotificationLockscreenUserManager> mNotificationLockscreenUserManager;
- @Inject Lazy<NotificationGutsManager> mNotificationGutsManager;
@Inject Lazy<NotificationMediaManager> mNotificationMediaManager;
@Inject Lazy<NotificationRemoteInputManager> mNotificationRemoteInputManager;
@Inject Lazy<SmartReplyConstants> mSmartReplyConstants;
@@ -498,7 +496,6 @@
mProviders.put(NotificationLockscreenUserManager.class,
mNotificationLockscreenUserManager::get);
mProviders.put(NotificationMediaManager.class, mNotificationMediaManager::get);
- mProviders.put(NotificationGutsManager.class, mNotificationGutsManager::get);
mProviders.put(NotificationRemoteInputManager.class,
mNotificationRemoteInputManager::get);
mProviders.put(SmartReplyConstants.class, mSmartReplyConstants::get);
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
index 046ccf16..a90980f 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSysUIComponent.java
@@ -18,7 +18,6 @@
import com.android.systemui.globalactions.ShutdownUiModule;
import com.android.systemui.keyguard.CustomizationProvider;
-import com.android.systemui.shade.ShadeModule;
import com.android.systemui.statusbar.NotificationInsetsModule;
import com.android.systemui.statusbar.QsFrameTranslateModule;
@@ -33,7 +32,6 @@
DependencyProvider.class,
NotificationInsetsModule.class,
QsFrameTranslateModule.class,
- ShadeModule.class,
ShutdownUiModule.class,
SystemUIBinder.class,
SystemUIModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
index 9e5fd55..1dd4abf 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ReferenceSystemUIModule.java
@@ -21,12 +21,9 @@
import android.content.Context;
import android.hardware.SensorPrivacyManager;
-import android.os.Handler;
-import com.android.internal.logging.UiEventLogger;
import com.android.keyguard.KeyguardViewController;
import com.android.systemui.battery.BatterySaverModule;
-import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dock.DockManagerImpl;
import com.android.systemui.doze.DozeHost;
@@ -34,7 +31,6 @@
import com.android.systemui.navigationbar.NavigationBarControllerModule;
import com.android.systemui.navigationbar.gestural.GestureModule;
import com.android.systemui.plugins.qs.QSFactory;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.power.dagger.PowerModule;
import com.android.systemui.qs.dagger.QSModule;
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
@@ -45,7 +41,7 @@
import com.android.systemui.screenshot.ReferenceScreenshotModule;
import com.android.systemui.settings.dagger.MultiUserUtilsModule;
import com.android.systemui.shade.NotificationShadeWindowControllerImpl;
-import com.android.systemui.shade.ShadeExpansionStateManager;
+import com.android.systemui.shade.ShadeModule;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyboardShortcutsModule;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -53,20 +49,13 @@
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.dagger.StartCentralSurfacesModule;
import com.android.systemui.statusbar.events.StatusBarEventsModule;
-import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
-import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.phone.DozeServiceHost;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
-import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.HeadsUpModule;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentStartableModule;
-import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.AospPolicyModule;
-import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.statusbar.policy.HeadsUpManagerLogger;
import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController;
import com.android.systemui.statusbar.policy.IndividualSensorPrivacyControllerImpl;
import com.android.systemui.statusbar.policy.SensorPrivacyController;
@@ -100,11 +89,13 @@
BatterySaverModule.class,
CollapsedStatusBarFragmentStartableModule.class,
GestureModule.class,
+ HeadsUpModule.class,
MediaModule.class,
MultiUserUtilsModule.class,
NavigationBarControllerModule.class,
PowerModule.class,
QSModule.class,
+ ShadeModule.class,
ReferenceScreenshotModule.class,
RotationLockModule.class,
SceneContainerFrameworkModule.class,
@@ -161,38 +152,6 @@
return true;
}
- @SysUISingleton
- @Provides
- static HeadsUpManagerPhone provideHeadsUpManagerPhone(
- Context context,
- HeadsUpManagerLogger headsUpManagerLogger,
- StatusBarStateController statusBarStateController,
- KeyguardBypassController bypassController,
- GroupMembershipManager groupManager,
- VisualStabilityProvider visualStabilityProvider,
- ConfigurationController configurationController,
- @Main Handler handler,
- AccessibilityManagerWrapper accessibilityManagerWrapper,
- UiEventLogger uiEventLogger,
- ShadeExpansionStateManager shadeExpansionStateManager) {
- return new HeadsUpManagerPhone(
- context,
- headsUpManagerLogger,
- statusBarStateController,
- bypassController,
- groupManager,
- visualStabilityProvider,
- configurationController,
- handler,
- accessibilityManagerWrapper,
- uiEventLogger,
- shadeExpansionStateManager
- );
- }
-
- @Binds
- abstract HeadsUpManager bindHeadsUpManagerPhone(HeadsUpManagerPhone headsUpManagerPhone);
-
@Provides
@SysUISingleton
static Recents provideRecents(Context context, RecentsImplementation recentsImplementation,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index d89332d..5d6949b 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -37,6 +37,7 @@
import com.android.systemui.keyguard.KeyguardViewConfigurator
import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.data.quickaffordance.MuteQuickAffordanceCoreStartable
+import com.android.systemui.keyguard.ui.binder.AlternateBouncerBinder
import com.android.systemui.keyguard.ui.binder.KeyguardDismissActionBinder
import com.android.systemui.keyguard.ui.binder.KeyguardDismissBinder
import com.android.systemui.log.SessionTracker
@@ -92,6 +93,11 @@
@ClassKey(AuthController::class)
abstract fun bindAuthController(service: AuthController): CoreStartable
+ @Binds
+ @IntoMap
+ @ClassKey(AlternateBouncerBinder::class)
+ abstract fun bindAlternateBouncerBinder(impl: AlternateBouncerBinder): CoreStartable
+
/** Inject into BiometricNotificationService */
@Binds
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 74ee206..f6f24e0 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -144,11 +144,6 @@
"lockscreen_custom_clocks"
)
- // TODO(b/275694445): Tracking Bug
- @JvmField
- val LOCKSCREEN_WITHOUT_SECURE_LOCK_WHEN_DREAMING =
- releasedFlag("lockscreen_without_secure_lock_when_dreaming")
-
// TODO(b/286092087): Tracking Bug
@JvmField
val ENABLE_SYSTEM_UI_DREAM_CONTROLLER = unreleasedFlag("enable_system_ui_dream_controller")
@@ -309,6 +304,11 @@
@JvmField
val WALLPAPER_PICKER_PREVIEW_ANIMATION = releasedFlag("wallpaper_picker_preview_animation")
+ /** Flag to enable rest to unlock feature. */
+ // TODO(b/303672286): Tracking bug
+ @JvmField
+ val REST_TO_UNLOCK: UnreleasedFlag = unreleasedFlag("rest_to_unlock")
+
/**
* TODO(b/278086361): Tracking bug
* Complete rewrite of the interactions between System UI and Window Manager involving keyguard
@@ -331,7 +331,7 @@
/** Flag to use a separate view for the alternate bouncer. */
// TODO(b/300440924): Tracking bug
@JvmField
- val ALTERNATE_BOUNCER_REFACTOR: UnreleasedFlag = unreleasedFlag("alternate_bouncer_view")
+ val ALTERNATE_BOUNCER_VIEW: UnreleasedFlag = unreleasedFlag("alternate_bouncer_view")
// 300 - power menu
// TODO(b/254512600): Tracking Bug
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 7678f4d..39742a0 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -171,6 +171,8 @@
import com.android.systemui.wallpapers.data.repository.WallpaperRepository;
import com.android.wm.shell.keyguard.KeyguardTransitions;
+import dagger.Lazy;
+
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -180,7 +182,8 @@
import java.util.concurrent.Executor;
import java.util.function.Consumer;
-import dagger.Lazy;
+
+
import kotlinx.coroutines.CoroutineDispatcher;
/**
@@ -1933,11 +1936,7 @@
public void onDreamingStarted() {
mUpdateMonitor.dispatchDreamingStarted();
synchronized (this) {
- final boolean alwaysShowKeyguard =
- mFeatureFlags.isEnabled(Flags.LOCKSCREEN_WITHOUT_SECURE_LOCK_WHEN_DREAMING);
- if (mDeviceInteractive
- && (alwaysShowKeyguard ||
- mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser()))) {
+ if (mDeviceInteractive) {
doKeyguardLaterLocked();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
index 3ccf446..d06f31f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt
@@ -32,6 +32,7 @@
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import javax.inject.Inject
+import kotlin.time.Duration.Companion.milliseconds
@SysUISingleton
class FromAlternateBouncerTransitionInteractor
@@ -129,11 +130,11 @@
override fun getDefaultAnimatorForTransitionsToState(toState: KeyguardState): ValueAnimator {
return ValueAnimator().apply {
interpolator = Interpolators.LINEAR
- duration = TRANSITION_DURATION_MS
+ duration = TRANSITION_DURATION_MS.inWholeMilliseconds
}
}
companion object {
- private const val TRANSITION_DURATION_MS = 300L
+ val TRANSITION_DURATION_MS = 300.milliseconds
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt
index e57c919..89aca76 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractor.kt
@@ -61,6 +61,7 @@
fun onSwipeUpOnBouncer()
fun onPrimaryBouncerUserInput()
fun onAccessibilityAction()
+ fun onWalletLaunched()
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NoopKeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NoopKeyguardFaceAuthInteractor.kt
index 596a1c0..f38bb2b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NoopKeyguardFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/NoopKeyguardFaceAuthInteractor.kt
@@ -61,4 +61,5 @@
override fun onSwipeUpOnBouncer() {}
override fun onPrimaryBouncerUserInput() {}
override fun onAccessibilityAction() {}
+ override fun onWalletLaunched() = Unit
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
index ef1d5ac..797dec2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/SystemUIKeyguardFaceAuthInteractor.kt
@@ -24,6 +24,7 @@
import com.android.systemui.CoreStartable
import com.android.systemui.biometrics.data.repository.FacePropertyRepository
import com.android.systemui.biometrics.shared.model.LockoutMode
+import com.android.systemui.biometrics.shared.model.SensorStrength
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.dagger.SysUISingleton
@@ -33,7 +34,6 @@
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.DeviceEntryFaceAuthRepository
import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
-import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.keyguard.shared.model.ErrorFaceAuthenticationStatus
import com.android.systemui.keyguard.shared.model.FaceAuthenticationStatus
import com.android.systemui.keyguard.shared.model.TransitionState
@@ -44,6 +44,7 @@
import com.android.systemui.user.data.repository.UserRepository
import com.android.systemui.util.kotlin.pairwise
import com.android.systemui.util.kotlin.sample
+import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
@@ -56,7 +57,6 @@
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.yield
-import javax.inject.Inject
/**
* Encapsulates business logic related face authentication being triggered for device entry from
@@ -79,7 +79,6 @@
private val deviceEntryFingerprintAuthRepository: DeviceEntryFingerprintAuthRepository,
private val userRepository: UserRepository,
private val facePropertyRepository: FacePropertyRepository,
- private val keyguardRepository: KeyguardRepository,
private val faceWakeUpTriggersConfig: FaceWakeUpTriggersConfig,
private val powerInteractor: PowerInteractor,
) : CoreStartable, KeyguardFaceAuthInteractor {
@@ -207,6 +206,12 @@
runFaceAuth(FaceAuthUiEvent.FACE_AUTH_ACCESSIBILITY_ACTION, false)
}
+ override fun onWalletLaunched() {
+ if (facePropertyRepository.sensorInfo.value?.strength == SensorStrength.STRONG) {
+ runFaceAuth(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_OCCLUDING_APP_REQUESTED, true)
+ }
+ }
+
override fun registerListener(listener: FaceAuthenticationListener) {
listeners.add(listener)
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt
new file mode 100644
index 0000000..41af9e8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/AlternateBouncerViewBinder.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2023 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.keyguard.ui.binder
+
+import android.view.View
+import android.view.ViewGroup
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.CoreStartable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.flags.FeatureFlagsClassic
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerViewModel
+import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.res.R
+import com.android.systemui.scrim.ScrimView
+import com.android.systemui.shade.NotificationShadeWindowView
+import com.android.systemui.statusbar.NotificationShadeWindowController
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.launch
+import javax.inject.Inject
+
+@ExperimentalCoroutinesApi
+@SysUISingleton
+class AlternateBouncerBinder
+@Inject
+constructor(
+ private val notificationShadeWindowView: NotificationShadeWindowView,
+ private val featureFlags: FeatureFlagsClassic,
+ private val alternateBouncerViewModel: AlternateBouncerViewModel,
+ @Application private val scope: CoroutineScope,
+ private val notificationShadeWindowController: NotificationShadeWindowController,
+) : CoreStartable {
+ override fun start() {
+ if (!featureFlags.isEnabled(Flags.ALTERNATE_BOUNCER_VIEW)) {
+ return
+ }
+
+ AlternateBouncerViewBinder.bind(
+ notificationShadeWindowView.requireViewById(R.id.alternate_bouncer),
+ alternateBouncerViewModel,
+ scope,
+ notificationShadeWindowController,
+ )
+ }
+}
+
+/**
+ * Binds the alternate bouncer view to its view-model.
+ *
+ * To use this properly, users should maintain a one-to-one relationship between the [View] and the
+ * view-binding, binding each view only once. It is okay and expected for the same instance of the
+ * view-model to be reused for multiple view/view-binder bindings.
+ */
+@ExperimentalCoroutinesApi
+object AlternateBouncerViewBinder {
+
+ /** Binds the view to the view-model, continuing to update the former based on the latter. */
+ @JvmStatic
+ fun bind(
+ view: ViewGroup,
+ viewModel: AlternateBouncerViewModel,
+ scope: CoroutineScope,
+ notificationShadeWindowController: NotificationShadeWindowController,
+ ) {
+ scope.launch {
+ // forcePluginOpen is necessary to show over occluded apps.
+ // This cannot be tied to the view's lifecycle because setting this allows the view
+ // to be started in the first place.
+ viewModel.forcePluginOpen.collect {
+ notificationShadeWindowController.setForcePluginOpen(it, this)
+ }
+ }
+
+ val scrim = view.requireViewById(R.id.alternate_bouncer_scrim) as ScrimView
+ view.repeatWhenAttached { alternateBouncerViewContainer ->
+ repeatOnLifecycle(Lifecycle.State.STARTED) {
+ scrim.viewAlpha = 0f
+
+ launch {
+ viewModel.onClickListener.collect {
+ // TODO (b/287599719): Support swiping to dismiss altBouncer
+ alternateBouncerViewContainer.setOnClickListener(it)
+ }
+ }
+
+ launch {
+ viewModel.scrimAlpha.collect {
+ alternateBouncerViewContainer.visibility =
+ if (it < .1f) View.INVISIBLE else View.VISIBLE
+ scrim.viewAlpha = it
+ }
+ }
+
+ launch { viewModel.scrimColor.collect { scrim.tint = it } }
+ }
+ }
+ }
+}
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 5ae2aba..c6d8ec7 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
@@ -27,11 +27,14 @@
import android.os.Bundle
import android.os.Handler
import android.os.IBinder
+import android.view.Display
+import android.view.Display.DEFAULT_DISPLAY
import android.view.LayoutInflater
import android.view.SurfaceControlViewHost
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
+import android.view.WindowManager.LayoutParams.TYPE_KEYGUARD
import android.widget.FrameLayout
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isInvisible
@@ -125,6 +128,8 @@
private val shouldHideClock: Boolean =
bundle.getBoolean(ClockPreviewConstants.KEY_HIDE_CLOCK, false)
private val wallpaperColors: WallpaperColors? = bundle.getParcelable(KEY_COLORS)
+ private val displayId = bundle.getInt(KEY_DISPLAY_ID, DEFAULT_DISPLAY)
+ private val display: Display = displayManager.getDisplay(displayId)
private var host: SurfaceControlViewHost
@@ -164,7 +169,7 @@
host =
SurfaceControlViewHost(
context,
- displayManager.getDisplay(bundle.getInt(KEY_DISPLAY_ID)),
+ displayManager.getDisplay(DEFAULT_DISPLAY),
hostToken,
"KeyguardPreviewRenderer"
)
@@ -174,21 +179,27 @@
fun render() {
mainHandler.post {
- val rootView = FrameLayout(context)
+ val previewContext = context.createDisplayContext(display)
- setupKeyguardRootView(rootView)
+ val rootView = FrameLayout(previewContext)
+
+ setupKeyguardRootView(previewContext, rootView)
if (!featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) {
setUpBottomArea(rootView)
}
+ val windowContext = context.createWindowContext(display, TYPE_KEYGUARD, null)
+ val windowManagerOfDisplay = windowContext.getSystemService(WindowManager::class.java)
rootView.measure(
View.MeasureSpec.makeMeasureSpec(
- windowManager.currentWindowMetrics.bounds.width(),
+ windowManagerOfDisplay?.currentWindowMetrics?.bounds?.width()
+ ?: windowManager.currentWindowMetrics.bounds.width(),
View.MeasureSpec.EXACTLY
),
View.MeasureSpec.makeMeasureSpec(
- windowManager.currentWindowMetrics.bounds.height(),
+ windowManagerOfDisplay?.currentWindowMetrics?.bounds?.height()
+ ?: windowManager.currentWindowMetrics.bounds.height(),
View.MeasureSpec.EXACTLY
),
)
@@ -251,7 +262,7 @@
*
* The end padding is as follows: Below clock padding end
*/
- private fun setUpSmartspace(parentView: ViewGroup) {
+ private fun setUpSmartspace(previewContext: Context, parentView: ViewGroup) {
if (
!lockscreenSmartspaceController.isEnabled() ||
!lockscreenSmartspaceController.isDateWeatherDecoupled()
@@ -263,12 +274,12 @@
val topPadding: Int =
KeyguardPreviewSmartspaceViewModel.getLargeClockSmartspaceTopPadding(
- context.resources,
+ previewContext.resources,
)
val startPadding: Int =
- context.resources.getDimensionPixelSize(R.dimen.below_clock_padding_start)
+ previewContext.resources.getDimensionPixelSize(R.dimen.below_clock_padding_start)
val endPadding: Int =
- context.resources.getDimensionPixelSize(R.dimen.below_clock_padding_end)
+ previewContext.resources.getDimensionPixelSize(R.dimen.below_clock_padding_end)
smartSpaceView?.let {
it.setPaddingRelative(startPadding, topPadding, endPadding, 0)
@@ -308,8 +319,8 @@
}
@OptIn(ExperimentalCoroutinesApi::class)
- private fun setupKeyguardRootView(rootView: FrameLayout) {
- val keyguardRootView = KeyguardRootView(context, null).apply { removeAllViews() }
+ private fun setupKeyguardRootView(previewContext: Context, rootView: FrameLayout) {
+ val keyguardRootView = KeyguardRootView(previewContext, null).apply { removeAllViews() }
disposables.add(
KeyguardRootViewBinder.bind(
keyguardRootView,
@@ -333,10 +344,10 @@
if (featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) {
setupShortcuts(keyguardRootView)
}
- setUpUdfps(rootView)
+ setUpUdfps(previewContext, rootView)
if (!shouldHideClock) {
- setUpClock(rootView)
+ setUpClock(previewContext, rootView)
KeyguardPreviewClockViewBinder.bind(
largeClockHostView,
smallClockHostView,
@@ -344,7 +355,7 @@
)
}
- setUpSmartspace(rootView)
+ setUpSmartspace(previewContext, rootView)
smartSpaceView?.let {
KeyguardPreviewSmartspaceViewBinder.bind(it, smartspaceViewModel)
}
@@ -381,7 +392,7 @@
}
}
- private fun setUpUdfps(parentView: ViewGroup) {
+ private fun setUpUdfps(previewContext: Context, parentView: ViewGroup) {
val sensorBounds = udfpsOverlayInteractor.udfpsOverlayParams.value.sensorBounds
// If sensorBounds are default rect, then there is no UDFPS
@@ -399,7 +410,7 @@
sensorBounds.bottom
)
val finger =
- LayoutInflater.from(context)
+ LayoutInflater.from(previewContext)
.inflate(
R.layout.udfps_keyguard_preview,
parentView,
@@ -408,12 +419,12 @@
parentView.addView(finger, fingerprintLayoutParams)
}
- private fun setUpClock(parentView: ViewGroup) {
+ private fun setUpClock(previewContext: Context, parentView: ViewGroup) {
largeClockHostView =
if (featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
parentView.requireViewById<FrameLayout>(R.id.lockscreen_clock_view_large)
} else {
- val hostView = FrameLayout(context)
+ val hostView = FrameLayout(previewContext)
hostView.layoutParams =
FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
@@ -429,7 +440,7 @@
parentView.requireViewById<FrameLayout>(R.id.lockscreen_clock_view)
} else {
val resources = parentView.resources
- val hostView = FrameLayout(context)
+ val hostView = FrameLayout(previewContext)
val layoutParams =
FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt
new file mode 100644
index 0000000..235a28d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModel.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2023 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.keyguard.ui.viewmodel
+
+import android.graphics.Color
+import android.view.View
+import com.android.systemui.keyguard.domain.interactor.FromAlternateBouncerTransitionInteractor.Companion.TRANSITION_DURATION_MS
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER
+import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
+import com.android.wm.shell.animation.Interpolators
+import javax.inject.Inject
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
+
+@ExperimentalCoroutinesApi
+class AlternateBouncerViewModel
+@Inject
+constructor(
+ statusBarKeyguardViewManager: StatusBarKeyguardViewManager,
+ transitionInteractor: KeyguardTransitionInteractor,
+ falsingManager: FalsingManager,
+) {
+ // When we're fully transitioned to the AlternateBouncer, the alpha of the scrim should be:
+ private val alternateBouncerScrimAlpha = .66f
+ private val toAlternateBouncerTransition =
+ KeyguardTransitionAnimationFlow(
+ transitionDuration = TRANSITION_DURATION_MS,
+ transitionFlow = transitionInteractor.anyStateToAlternateBouncerTransition,
+ )
+ .createFlow(
+ duration = TRANSITION_DURATION_MS,
+ onStep = { it },
+ onFinish = { 1f },
+ // Reset on cancel
+ onCancel = { 0f },
+ interpolator = Interpolators.FAST_OUT_SLOW_IN,
+ )
+ private val fromAlternateBouncerTransition =
+ KeyguardTransitionAnimationFlow(
+ transitionDuration = TRANSITION_DURATION_MS,
+ transitionFlow = transitionInteractor.transitionStepsFromState(ALTERNATE_BOUNCER),
+ )
+ .createFlow(
+ duration = TRANSITION_DURATION_MS,
+ onStep = { 1f - it },
+ // Reset on cancel
+ onCancel = { 0f },
+ interpolator = Interpolators.FAST_OUT_SLOW_IN,
+ )
+
+ /** Progress to a fully transitioned alternate bouncer. 1f represents fully transitioned. */
+ private val transitionToAlternateBouncerProgress =
+ merge(fromAlternateBouncerTransition, toAlternateBouncerTransition)
+
+ val forcePluginOpen: Flow<Boolean> =
+ transitionToAlternateBouncerProgress.map { it > 0f }.distinctUntilChanged()
+
+ /** An observable for the scrim alpha. */
+ val scrimAlpha = transitionToAlternateBouncerProgress.map { it * alternateBouncerScrimAlpha }
+
+ /** An observable for the scrim color. Change color for easier debugging. */
+ val scrimColor: Flow<Int> = flowOf(Color.BLACK)
+
+ private val clickListener =
+ View.OnClickListener {
+ if (!falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
+ statusBarKeyguardViewManager.showPrimaryBouncer(/* scrimmed */ true)
+ }
+ }
+
+ val onClickListener: Flow<View.OnClickListener?> =
+ transitionToAlternateBouncerProgress
+ .map {
+ if (it == 1f) {
+ clickListener
+ } else {
+ null
+ }
+ }
+ .distinctUntilChanged()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt
index 54abc5b..0b1079f 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsLockscreenViewModel.kt
@@ -19,13 +19,13 @@
import android.content.Context
import androidx.annotation.ColorInt
import com.android.settingslib.Utils.getColorAttrDefaultColor
-import com.android.systemui.res.R
import com.android.systemui.keyguard.domain.interactor.BurnInOffsets
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.domain.interactor.UdfpsKeyguardInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.StatusBarState
+import com.android.systemui.res.R
import com.android.wm.shell.animation.Interpolators
import javax.inject.Inject
import kotlin.math.roundToInt
@@ -62,7 +62,7 @@
private val toAlternateBouncer: Flow<TransitionViewModel> =
keyguardInteractor.statusBarState.flatMapLatest { statusBarState ->
- transitionInteractor.anyStateToAlternateBouncerTransition.map {
+ transitionInteractor.transitionStepsToState(KeyguardState.ALTERNATE_BOUNCER).map {
TransitionViewModel(
alpha = 1f,
scale =
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
index 2b56d0c..d08d040 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/MediaProjectionPermissionActivity.java
@@ -239,6 +239,8 @@
protected void onDestroy() {
super.onDestroy();
if (mDialog != null) {
+ mDialog.setOnDismissListener(null);
+ mDialog.setOnCancelListener(null);
mDialog.dismiss();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragmentLegacy.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragmentLegacy.java
index 8589ae9..68bf88b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragmentLegacy.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragmentLegacy.java
@@ -72,7 +72,7 @@
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
- QSFragmentComponent qsFragmentComponent = mQsComponentFactory.create(this);
+ QSFragmentComponent qsFragmentComponent = mQsComponentFactory.create(getView());
mQsImpl = mQsImplProvider.get();
mQsImpl.onComponentCreated(qsFragmentComponent, savedInstanceState);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
index a32a024..202254b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSImpl.java
@@ -199,11 +199,13 @@
mListeningAndVisibilityLifecycleOwner = new ListeningAndVisibilityLifecycleOwner();
}
+ /**
+ * This method will set up all the necessary fields. Methods from the implemented interfaces
+ * should not be called before this method returns.
+ */
public void onComponentCreated(QSComponent qsComponent, @Nullable Bundle savedInstanceState) {
mRootView = qsComponent.getRootView();
- mCommandQueue.addCallback(this);
-
mQSPanelController = qsComponent.getQSPanelController();
mQuickQSPanelController = qsComponent.getQuickQSPanelController();
@@ -270,6 +272,9 @@
mQSPanelController.getMediaHost().getHostView().setAlpha(1.0f);
mQSAnimator.requestAnimatorUpdate();
});
+
+ // This will immediately call disable, so it needs to be added after setting up the fields.
+ mCommandQueue.addCallback(this);
}
private void bindFooterActionsView(View root) {
@@ -323,6 +328,8 @@
public void onDestroy() {
mCommandQueue.removeCallback(this);
mStatusBarStateController.removeCallback(this);
+ mQSPanelController.destroy();
+ mQuickQSPanelController.destroy();
if (mListening) {
setListening(false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 60c92c0..fc2f5f9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -158,6 +158,7 @@
protected void onInit() {
mView.initialize(mQSLogger);
mQSLogger.logAllTilesChangeListening(mView.isListening(), mView.getDumpableTag(), "");
+ mHost.addCallback(mQSHostCallback);
}
/**
@@ -172,6 +173,18 @@
}
@Override
+ public void destroy() {
+ super.destroy();
+ mHost.removeCallback(mQSHostCallback);
+
+ for (TileRecord record : mRecords) {
+ record.tile.removeCallback(record.callback);
+ mView.removeTile(record);
+ }
+ mRecords.clear();
+ }
+
+ @Override
protected void onViewAttached() {
mQsTileRevealController = createTileRevealController();
if (mQsTileRevealController != null) {
@@ -180,7 +193,6 @@
mMediaHost.addVisibilityChangeListener(mMediaHostVisibilityListener);
mView.addOnConfigurationChangedListener(mOnConfigurationChangedListener);
- mHost.addCallback(mQSHostCallback);
setTiles();
mLastOrientation = getResources().getConfiguration().orientation;
mQSLogger.logOnViewAttached(mLastOrientation, mView.getDumpableTag());
@@ -193,16 +205,11 @@
protected void onViewDetached() {
mQSLogger.logOnViewDetached(mLastOrientation, mView.getDumpableTag());
mView.removeOnConfigurationChangedListener(mOnConfigurationChangedListener);
- mHost.removeCallback(mQSHostCallback);
mView.getTileLayout().setListening(false, mUiEventLogger);
mMediaHost.removeVisibilityChangeListener(mMediaHostVisibilityListener);
- for (TileRecord record : mRecords) {
- record.tile.removeCallback(record.callback);
- }
- mRecords.clear();
mDumpManager.unregisterDumpable(mView.getDumpableTag());
}
@@ -222,15 +229,30 @@
if (!collapsedView && mQsTileRevealController != null) {
mQsTileRevealController.updateRevealedTiles(tiles);
}
-
- for (QSPanelControllerBase.TileRecord record : mRecords) {
- mView.removeTile(record);
- record.tile.removeCallback(record.callback);
+ boolean shouldChange = false;
+ if (tiles.size() == mRecords.size()) {
+ int i = 0;
+ for (QSTile tile : tiles) {
+ if (tile != mRecords.get(i).tile) {
+ shouldChange = true;
+ break;
+ }
+ i++;
+ }
+ } else {
+ shouldChange = true;
}
- mRecords.clear();
- mCachedSpecs = "";
- for (QSTile tile : tiles) {
- addTile(tile, collapsedView);
+
+ if (shouldChange) {
+ for (QSPanelControllerBase.TileRecord record : mRecords) {
+ mView.removeTile(record);
+ record.tile.removeCallback(record.callback);
+ }
+ mRecords.clear();
+ mCachedSpecs = "";
+ for (QSTile tile : tiles) {
+ addTile(tile, collapsedView);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java
index 327e858..ce8db7898 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java
@@ -16,6 +16,9 @@
package com.android.systemui.qs.dagger;
+import android.view.View;
+
+import com.android.systemui.dagger.qualifiers.RootView;
import com.android.systemui.qs.QSFragmentLegacy;
import dagger.BindsInstance;
@@ -31,6 +34,7 @@
/** Factory for building a {@link QSFragmentComponent}. */
@Subcomponent.Factory
interface Factory {
- QSFragmentComponent create(@BindsInstance QSFragmentLegacy qsFragment);
+ /** */
+ QSFragmentComponent create(@BindsInstance @RootView View view);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
index 0c9c24d..0e75b21 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
@@ -20,34 +20,17 @@
import static com.android.systemui.util.Utils.useQsMediaPlayer;
import android.content.Context;
-import android.view.View;
-import com.android.systemui.dagger.qualifiers.RootView;
-import com.android.systemui.plugins.qs.QS;
-import com.android.systemui.qs.QSFragmentLegacy;
-
-import javax.inject.Named;
-
-import dagger.Binds;
import dagger.Module;
import dagger.Provides;
+import javax.inject.Named;
+
/**
* Dagger Module for {@link QSFragmentComponent}.
*/
@Module(includes = {QSScopeModule.class})
public interface QSFragmentModule {
-
- @Provides
- @RootView
- static View provideRootView(QSFragmentLegacy qsFragment) {
- return qsFragment.getView();
- }
-
- /** */
- @Binds
- QS bindQS(QSFragmentLegacy qsFragment);
-
/** */
@Provides
@Named(QSScopeModule.QS_USING_MEDIA_PLAYER)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt
index c5512c1..4bb8c6e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt
@@ -272,7 +272,6 @@
// repository
launch { tileSpecRepository.setTiles(currentUser.value, resolvedSpecs) }
}
- Log.d("Fabian", "Finished resolving tiles")
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/ObservableTransitionState.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/ObservableTransitionState.kt
index 3927873..f704894 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/ObservableTransitionState.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/ObservableTransitionState.kt
@@ -42,6 +42,13 @@
* scene, this value will remain true after the pointer is no longer touching the screen and
* will be true in any transition created to animate back to the original position.
*/
- val isUserInputDriven: Boolean,
+ val isInitiatedByUserInput: Boolean,
+
+ /**
+ * Whether user input is currently driving the transition. For example, if a user is
+ * dragging a pointer, this emits true. Once they lift their finger, this emits false while
+ * the transition completes/settles.
+ */
+ val isUserInputOngoing: Flow<Boolean>,
) : ObservableTransitionState()
}
diff --git a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
index 4bc93a8..2e45353 100644
--- a/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
+++ b/packages/SystemUI/src/com/android/systemui/scene/shared/model/Scene.kt
@@ -61,12 +61,17 @@
data class Swipe(
/** The direction of the swipe. */
val direction: Direction,
+ /**
+ * The edge from which the swipe originated or `null`, if the swipe didn't start close to an
+ * edge.
+ */
+ val fromEdge: Edge? = null,
/** The number of pointers that were used (for example, one or two fingers). */
val pointerCount: Int = 1,
) : UserAction
/** The user has hit the back button or performed the back navigation gesture. */
- object Back : UserAction
+ data object Back : UserAction
}
/** Enumerates all known "cardinal" directions for user actions. */
@@ -76,3 +81,11 @@
RIGHT,
DOWN,
}
+
+/** Enumerates all known edges from which a swipe can start. */
+enum class Edge {
+ LEFT,
+ TOP,
+ RIGHT,
+ BOTTOM,
+}
diff --git a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
index 2f87301..393a698 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
@@ -132,6 +132,7 @@
setUserIdInternal(startingUser)
val filter = IntentFilter().apply {
+ addAction(Intent.ACTION_LOCALE_CHANGED)
addAction(Intent.ACTION_USER_INFO_CHANGED)
// These get called when a managed profile goes in or out of quiet mode.
addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)
@@ -149,6 +150,7 @@
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
+ Intent.ACTION_LOCALE_CHANGED,
Intent.ACTION_USER_INFO_CHANGED,
Intent.ACTION_MANAGED_PROFILE_AVAILABLE,
Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java b/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java
index 9235fcc..c42fdf8 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/DebugDrawable.java
@@ -67,8 +67,6 @@
mDebugPaint.setStrokeWidth(2);
mDebugPaint.setStyle(Paint.Style.STROKE);
mDebugPaint.setTextSize(24);
- String headerDebugInfo = mNotificationPanelViewController.getHeaderDebugInfo();
- if (headerDebugInfo != null) canvas.drawText(headerDebugInfo, 50, 100, mDebugPaint);
drawDebugInfo(canvas, mNotificationPanelViewController.getMaxPanelHeight(),
Color.RED, "getMaxPanelHeight()");
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 1c62b6a..2ef83dd 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -138,7 +138,6 @@
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.shared.model.TransitionState;
import com.android.systemui.keyguard.shared.model.TransitionStep;
-import com.android.systemui.power.shared.model.WakefulnessModel;
import com.android.systemui.keyguard.ui.binder.KeyguardLongPressViewBinder;
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingLockscreenHostedTransitionViewModel;
@@ -162,9 +161,10 @@
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
+import com.android.systemui.power.domain.interactor.PowerInteractor;
+import com.android.systemui.power.shared.model.WakefulnessModel;
import com.android.systemui.res.R;
import com.android.systemui.shade.data.repository.ShadeRepository;
-import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.shade.transition.ShadeTransitionController;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.statusbar.CommandQueue;
@@ -200,7 +200,6 @@
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
import com.android.systemui.statusbar.phone.KeyguardBottomAreaViewController;
@@ -217,6 +216,7 @@
import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController;
@@ -362,7 +362,7 @@
private boolean mIsLaunchAnimationRunning;
private float mOverExpansion;
private CentralSurfaces mCentralSurfaces;
- private HeadsUpManagerPhone mHeadsUpManager;
+ private HeadsUpManager mHeadsUpManager;
private float mExpandedHeight = 0;
/** The current squish amount for the predictive back animation */
private float mCurrentBackProgress = 0.0f;
@@ -3026,7 +3026,7 @@
return headsUpVisible || isExpanded() || mBouncerShowing;
}
- private void setHeadsUpManager(HeadsUpManagerPhone headsUpManager) {
+ private void setHeadsUpManager(HeadsUpManager headsUpManager) {
mHeadsUpManager = headsUpManager;
mHeadsUpManager.addListener(mOnHeadsUpChangedListener);
mHeadsUpTouchHelper = new HeadsUpTouchHelper(
@@ -3508,7 +3508,7 @@
GestureRecorder recorder,
Runnable hideExpandedRunnable,
NotificationShelfController notificationShelfController,
- HeadsUpManagerPhone headsUpManager) {
+ HeadsUpManager headsUpManager) {
setHeadsUpManager(headsUpManager);
// TODO(b/254859580): this can be injected.
mCentralSurfaces = centralSurfaces;
@@ -3557,10 +3557,6 @@
mView.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
}
- String getHeaderDebugInfo() {
- return "USER " + mHeadsUpManager.getUser();
- }
-
@Override
public void onThemeChanged() {
mConfigurationListener.onThemeChanged();
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index 6cf4ff5..5414b3f 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -21,7 +21,6 @@
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
import android.app.StatusBarManager;
-import android.os.PowerManager;
import android.util.Log;
import android.view.GestureDetector;
import android.view.InputDevice;
@@ -36,10 +35,11 @@
import com.android.keyguard.LockIconViewController;
import com.android.keyguard.dagger.KeyguardBouncerComponent;
import com.android.systemui.Dumpable;
-import com.android.systemui.res.R;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.back.domain.interactor.BackActionInteractor;
+import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor;
+import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
import com.android.systemui.bouncer.ui.binder.KeyguardBouncerViewBinder;
import com.android.systemui.bouncer.ui.viewmodel.KeyguardBouncerViewModel;
import com.android.systemui.classifier.FalsingCollector;
@@ -56,6 +56,7 @@
import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel;
import com.android.systemui.log.BouncerLogger;
import com.android.systemui.power.domain.interactor.PowerInteractor;
+import com.android.systemui.res.R;
import com.android.systemui.shared.animation.DisableSubpixelTextTransitionListener;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
@@ -106,6 +107,8 @@
private final boolean mIsTrackpadCommonEnabled;
private final FeatureFlags mFeatureFlags;
private final KeyEventInteractor mKeyEventInteractor;
+ private final PrimaryBouncerInteractor mPrimaryBouncerInteractor;
+ private final AlternateBouncerInteractor mAlternateBouncerInteractor;
private GestureDetector mPulsingWakeupGestureHandler;
private GestureDetector mDreamingWakeupGestureHandler;
private View mBrightnessMirror;
@@ -182,7 +185,9 @@
SystemClock clock,
BouncerMessageInteractor bouncerMessageInteractor,
BouncerLogger bouncerLogger,
- KeyEventInteractor keyEventInteractor) {
+ KeyEventInteractor keyEventInteractor,
+ PrimaryBouncerInteractor primaryBouncerInteractor,
+ AlternateBouncerInteractor alternateBouncerInteractor) {
mLockscreenShadeTransitionController = transitionController;
mFalsingCollector = falsingCollector;
mStatusBarStateController = statusBarStateController;
@@ -210,6 +215,8 @@
mIsTrackpadCommonEnabled = featureFlags.isEnabled(TRACKPAD_GESTURE_COMMON);
mFeatureFlags = featureFlags;
mKeyEventInteractor = keyEventInteractor;
+ mPrimaryBouncerInteractor = primaryBouncerInteractor;
+ mAlternateBouncerInteractor = alternateBouncerInteractor;
// This view is not part of the newly inflated expanded status bar.
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
@@ -351,16 +358,6 @@
if (mStatusBarStateController.isDozing()) {
mDozeScrimController.extendPulse();
}
- mLockIconViewController.onTouchEvent(
- ev,
- /* onGestureDetectedRunnable */
- () -> {
- mService.userActivity();
- mPowerInteractor.wakeUpIfDozing(
- "LOCK_ICON_TOUCH",
- PowerManager.WAKE_REASON_GESTURE);
- }
- );
// In case we start outside of the view bounds (below the status bar), we need to
// dispatch the touch manually as the view system can't accommodate for touches
@@ -415,8 +412,18 @@
private boolean shouldInterceptTouchEventInternal(MotionEvent ev) {
mLastInterceptWasDragDownHelper = false;
- if (mStatusBarStateController.isDozing() && !mDozeServiceHost.isPulsing()
- && !mDockManager.isDocked()) {
+ // When the device starts dozing, there's a delay before the device's display state
+ // changes from ON => DOZE to allow for the light reveal animation to run at
+ // a higher refresh rate and to delay visual changes (ie: display blink) when
+ // changing the display state. We'll call this specific state the
+ // "aodDefermentState". In this state we:
+ // - don't want touches to get sent to underlying views, except the lock icon
+ // - handle the tap to wake gesture via the PulsingGestureListener
+ if (mStatusBarStateController.isDozing()
+ && !mDozeServiceHost.isPulsing()
+ && !mDockManager.isDocked()
+ && !mLockIconViewController.willHandleTouchWhileDozing(ev)
+ ) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mShadeLogger.d("NSWVC: capture all touch events in always-on");
}
@@ -432,16 +439,15 @@
return true;
}
- if (mLockIconViewController.onInterceptTouchEvent(ev)) {
- // immediately return true; don't send the touch to the drag down helper
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- mShadeLogger.d("NSWVC: don't send touch to drag down helper");
- }
- return true;
+ boolean bouncerShowing;
+ if (mFeatureFlags.isEnabled(Flags.ALTERNATE_BOUNCER_VIEW)) {
+ bouncerShowing = mPrimaryBouncerInteractor.isBouncerShowing()
+ || mAlternateBouncerInteractor.isVisibleState();
+ } else {
+ bouncerShowing = mService.isBouncerShowing();
}
-
if (mNotificationPanelViewController.isFullyExpanded()
- && !mService.isBouncerShowing()
+ && !bouncerShowing
&& !mStatusBarStateController.isDozing()) {
if (mDragDownHelper.isDragDownEnabled()) {
// This handles drag down over lockscreen
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java
index 447a15d..2c4b0b9 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeController.java
@@ -178,9 +178,6 @@
/** Listens for shade visibility changes. */
interface ShadeVisibilityListener {
- /** Called when the visibility of the shade changes. */
- void visibilityChanged(boolean visible);
-
/** Called when shade expanded and visible state changed. */
void expandedVisibleChanged(boolean expandedVisible);
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
index 367449b..fdc7eec 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeControllerImpl.java
@@ -24,6 +24,7 @@
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
+import com.android.systemui.DejankUtils;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
@@ -75,6 +76,7 @@
private final ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
private boolean mExpandedVisible;
+ private boolean mLockscreenOrShadeVisible;
private NotificationPresenter mPresenter;
private NotificationShadeWindowViewController mNotificationShadeWindowViewController;
@@ -399,8 +401,19 @@
}
private void notifyVisibilityChanged(boolean visible) {
- mShadeVisibilityListener.visibilityChanged(visible);
mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(visible);
+ if (mLockscreenOrShadeVisible != visible) {
+ mLockscreenOrShadeVisible = visible;
+ if (visible) {
+ // It would be best if this could be done as a side effect of listening to the
+ // [WindowRootViewVisibilityInteractor.isLockscreenOrShadeVisible] flow inside
+ // NotificationShadeWindowViewController. However, there's no guarantee that the
+ // flow will emit in the same frame as when the visibility changed, and we want the
+ // DejankUtils to be notified immediately, so we do it immediately here.
+ DejankUtils.notifyRendererOfExpensiveFrame(
+ getNotificationShadeWindowView(), "onShadeVisibilityChanged");
+ }
+ }
}
private void notifyExpandedVisibleChanged(boolean expandedVisible) {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt
index 6ee6cbf..4e23e7d 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeSurface.kt
@@ -20,7 +20,7 @@
import com.android.systemui.statusbar.NotificationShelfController
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.phone.CentralSurfaces
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
+import com.android.systemui.statusbar.policy.HeadsUpManager
/**
* Allows CentralSurfacesImpl to interact with the shade. Only CentralSurfacesImpl should reference
@@ -34,7 +34,7 @@
recorder: GestureRecorder,
hideExpandedRunnable: Runnable,
notificationShelfController: NotificationShelfController,
- headsUpManager: HeadsUpManagerPhone
+ headsUpManager: HeadsUpManager
)
/** Cancels any pending collapses. */
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
index e487a6f..6117f9f 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
@@ -261,7 +261,7 @@
when (state) {
is ObservableTransitionState.Idle -> false
is ObservableTransitionState.Transition ->
- state.isUserInputDriven &&
+ state.isInitiatedByUserInput &&
(state.toScene == sceneKey || state.fromScene == sceneKey)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
index 3640ae0..4ea7026 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
@@ -31,22 +31,22 @@
import com.android.app.animation.Interpolators
import com.android.systemui.Dumpable
import com.android.systemui.Gefingerpoken
-import com.android.systemui.res.R
import com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.res.R
import com.android.systemui.shade.ShadeExpansionStateManager
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.HeadsUpManager
import java.io.PrintWriter
import javax.inject.Inject
import kotlin.math.max
@@ -63,7 +63,7 @@
context: Context,
private val wakeUpCoordinator: NotificationWakeUpCoordinator,
private val bypassController: KeyguardBypassController,
- private val headsUpManager: HeadsUpManagerPhone,
+ private val headsUpManager: HeadsUpManager,
private val roundnessManager: NotificationRoundnessManager,
configurationController: ConfigurationController,
private val statusBarStateController: StatusBarStateController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
index c62546f..756151b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
@@ -24,7 +24,7 @@
import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.stack.NotificationListContainer
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
+import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.statusbar.policy.HeadsUpUtil
import kotlin.math.ceil
import kotlin.math.max
@@ -35,7 +35,7 @@
class NotificationLaunchAnimatorControllerProvider(
private val notificationExpansionRepository: NotificationExpansionRepository,
private val notificationListContainer: NotificationListContainer,
- private val headsUpManager: HeadsUpManagerPhone,
+ private val headsUpManager: HeadsUpManager,
private val jankMonitor: InteractionJankMonitor
) {
@JvmOverloads
@@ -62,7 +62,7 @@
class NotificationLaunchAnimatorController(
private val notificationExpansionRepository: NotificationExpansionRepository,
private val notificationListContainer: NotificationListContainer,
- private val headsUpManager: HeadsUpManagerPhone,
+ private val headsUpManager: HeadsUpManager,
private val notification: ExpandableNotificationRow,
private val jankMonitor: InteractionJankMonitor,
private val onFinishAnimationCallback: Runnable?
@@ -152,16 +152,17 @@
}
}
- private val headsUpNotificationRow: ExpandableNotificationRow? get() {
- val summaryEntry = notificationEntry.parent?.summary
+ private val headsUpNotificationRow: ExpandableNotificationRow?
+ get() {
+ val summaryEntry = notificationEntry.parent?.summary
- return when {
- headsUpManager.isAlerting(notificationKey) -> notification
- summaryEntry == null -> null
- headsUpManager.isAlerting(summaryEntry.key) -> summaryEntry.row
- else -> null
+ return when {
+ headsUpManager.isAlerting(notificationKey) -> notification
+ summaryEntry == null -> null
+ headsUpManager.isAlerting(summaryEntry.key) -> summaryEntry.row
+ else -> null
+ }
}
- }
private fun removeHun(animate: Boolean) {
val row = headsUpNotificationRow ?: return
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
index 07eb8a00..2d83970 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.kt
@@ -37,8 +37,8 @@
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
-import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider
+import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationListInteractor
import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.statusbar.policy.headsUpEvents
import com.android.systemui.util.asIndenting
@@ -85,7 +85,7 @@
@Application private val scope: CoroutineScope,
private val sectionHeaderVisibilityProvider: SectionHeaderVisibilityProvider,
private val secureSettings: SecureSettings,
- private val seenNotifsProvider: SeenNotificationsProviderImpl,
+ private val notificationListInteractor: NotificationListInteractor,
private val statusBarStateController: StatusBarStateController,
) : Coordinator, Dumpable {
@@ -351,7 +351,7 @@
override fun onCleanup() {
logger.logProviderHasFilteredOutSeenNotifs(hasFilteredAnyNotifs)
- seenNotifsProvider.hasFilteredOutSeenNotifications = hasFilteredAnyNotifs
+ notificationListInteractor.setHasFilteredOutSeenNotifications(hasFilteredAnyNotifs)
hasFilteredAnyNotifs = false
}
}
@@ -388,8 +388,8 @@
override fun dump(pw: PrintWriter, args: Array<out String>) =
with(pw.asIndenting()) {
println(
- "seenNotifsProvider.hasFilteredOutSeenNotifications=" +
- seenNotifsProvider.hasFilteredOutSeenNotifications
+ "notificationListInteractor.hasFilteredOutSeenNotifications.value=" +
+ notificationListInteractor.hasFilteredOutSeenNotifications.value
)
println("unseen notifications:")
indentIfPossible {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
index 657c394d..c0f674846 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
@@ -28,6 +28,7 @@
import com.android.systemui.statusbar.notification.row.NotificationGutsManager
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.Compile
+import com.android.systemui.util.traceSection
import javax.inject.Inject
/**
@@ -122,8 +123,10 @@
private fun updateNotificationsOnUiModeChanged() {
log { "ViewConfigCoordinator.updateNotificationsOnUiModeChanged()" }
- mPipeline?.allNotifs?.forEach { entry ->
- entry.row?.onUiModeChanged()
+ traceSection("updateNotifOnUiModeChanged") {
+ mPipeline?.allNotifs?.forEach { entry ->
+ entry.row?.onUiModeChanged()
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SeenNotificationsProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SeenNotificationsProvider.kt
deleted file mode 100644
index cff47e2..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SeenNotificationsProvider.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.collection.provider
-
-import com.android.systemui.dagger.SysUISingleton
-import dagger.Binds
-import dagger.Module
-import javax.inject.Inject
-
-/** Keeps track of whether "seen" notification content has been filtered out of the shade. */
-interface SeenNotificationsProvider {
- /** Are any already-seen notifications currently filtered out of the shade? */
- val hasFilteredOutSeenNotifications: Boolean
-}
-
-@Module
-interface SeenNotificationsProviderModule {
- @Binds
- fun bindSeenNotificationsProvider(
- impl: SeenNotificationsProviderImpl
- ): SeenNotificationsProvider
-}
-
-@SysUISingleton
-class SeenNotificationsProviderImpl @Inject constructor() : SeenNotificationsProvider {
- override var hasFilteredOutSeenNotifications: Boolean = false
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
index 59fc387..1a88815 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
@@ -231,18 +231,24 @@
fun getChildCount(): Int = controller.getChildCount()
fun addChildAt(child: ShadeNode, index: Int) {
- controller.addChildAt(child.controller, index)
- child.controller.onViewAdded()
+ traceSection("ShadeNode#addChildAt") {
+ controller.addChildAt(child.controller, index)
+ child.controller.onViewAdded()
+ }
}
fun moveChildTo(child: ShadeNode, index: Int) {
- controller.moveChildTo(child.controller, index)
- child.controller.onViewMoved()
+ traceSection("ShadeNode#moveChildTo") {
+ controller.moveChildTo(child.controller, index)
+ child.controller.onViewMoved()
+ }
}
fun removeChild(child: ShadeNode, isTransfer: Boolean) {
- controller.removeChild(child.controller, isTransfer)
- child.controller.onViewRemoved()
+ traceSection("ShadeNode#removeChild") {
+ controller.removeChild(child.controller, isTransfer)
+ child.controller.onViewRemoved()
+ }
}
fun offerToKeepInParentForAnimation(): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index f2e9a479..8561869 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -20,10 +20,10 @@
import com.android.internal.jank.InteractionJankMonitor;
import com.android.systemui.CoreStartable;
-import com.android.systemui.res.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.UiBackground;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.res.R;
import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor;
import com.android.systemui.shade.ShadeEventsModule;
import com.android.systemui.statusbar.NotificationListener;
@@ -45,7 +45,6 @@
import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProviderImpl;
import com.android.systemui.statusbar.notification.collection.provider.NotificationVisibilityProviderImpl;
-import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderModule;
import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManagerImpl;
@@ -75,9 +74,9 @@
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationListViewModelModule;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.util.kotlin.JavaAdapter;
import dagger.Binds;
@@ -96,7 +95,6 @@
@Module(includes = {
CoordinatorsModule.class,
KeyguardNotificationVisibilityProviderModule.class,
- SeenNotificationsProviderModule.class,
ShadeEventsModule.class,
NotificationDataLayerModule.class,
NotifPipelineChoreographerModule.class,
@@ -208,7 +206,7 @@
static NotificationLaunchAnimatorControllerProvider provideNotifLaunchAnimControllerProvider(
NotificationExpansionRepository notificationExpansionRepository,
NotificationListContainer notificationListContainer,
- HeadsUpManagerPhone headsUpManager,
+ HeadsUpManager headsUpManager,
InteractionJankMonitor jankMonitor) {
return new NotificationLaunchAnimatorControllerProvider(
notificationExpansionRepository,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index c61258b..847d948 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -355,12 +355,8 @@
AnimatorListenerAdapter animationListener) {
enableAppearDrawing(true);
mIsHeadsUpAnimation = isHeadsUpAnimation;
- if (mDrawingAppearAnimation) {
- startAppearAnimation(false /* isAppearing */, translationDirection,
- delay, duration, onFinishedRunnable, animationListener);
- } else if (onFinishedRunnable != null) {
- onFinishedRunnable.run();
- }
+ startAppearAnimation(false /* isAppearing */, translationDirection,
+ delay, duration, onFinishedRunnable, animationListener);
return 0;
}
@@ -369,10 +365,8 @@
Runnable onFinishRunnable) {
enableAppearDrawing(true);
mIsHeadsUpAnimation = isHeadsUpAppear;
- if (mDrawingAppearAnimation) {
- startAppearAnimation(true /* isAppearing */, isHeadsUpAppear ? 0.0f : -1.0f, delay,
- duration, null, null);
- }
+ startAppearAnimation(true /* isAppearing */, isHeadsUpAppear ? 0.0f : -1.0f, delay,
+ duration, null, null);
}
private void startAppearAnimation(boolean isAppearing, float translationDirection, long delay,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java
index 42c80ed..40897da 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FeedbackInfo.java
@@ -42,9 +42,8 @@
import android.widget.TextView;
import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.Dependency;
-import com.android.systemui.res.R;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.util.Compile;
@@ -76,7 +75,9 @@
final StatusBarNotification sbn,
final NotificationEntry entry,
final ExpandableNotificationRow row,
- final AssistantFeedbackController controller) {
+ final AssistantFeedbackController controller,
+ final IStatusBarService statusBarService,
+ final NotificationGutsManager notificationGutsManager) {
mPkg = sbn.getPackageName();
mPm = pm;
mEntry = entry;
@@ -84,8 +85,8 @@
mRanking = entry.getRanking();
mFeedbackController = controller;
mAppName = mPkg;
- mStatusBarService = Dependency.get(IStatusBarService.class);
- mNotificationGutsManager = Dependency.get(NotificationGutsManager.class);
+ mStatusBarService = statusBarService;
+ mNotificationGutsManager = notificationGutsManager;
bindHeader();
bindPrompt();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 6d656605..9e9116b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -44,9 +44,9 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.settingslib.notification.ConversationIconFactory;
import com.android.systemui.CoreStartable;
-import com.android.systemui.res.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
@@ -54,6 +54,7 @@
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.res.R;
import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor;
import com.android.systemui.settings.UserContextProvider;
import com.android.systemui.shade.ShadeController;
@@ -69,8 +70,8 @@
import com.android.systemui.statusbar.notification.collection.render.NotifGutsViewManager;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.CentralSurfaces;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.util.kotlin.JavaAdapter;
import com.android.systemui.wmshell.BubblesManager;
@@ -99,6 +100,7 @@
// Dependencies:
private final NotificationLockscreenUserManager mLockscreenUserManager;
private final StatusBarStateController mStatusBarStateController;
+ private final IStatusBarService mStatusBarService;
private final DeviceProvisionedController mDeviceProvisionedController;
private final AssistantFeedbackController mAssistantFeedbackController;
@@ -127,7 +129,7 @@
private final ShadeController mShadeController;
private final WindowRootViewVisibilityInteractor mWindowRootViewVisibilityInteractor;
private NotifGutsViewListener mGutsListener;
- private final HeadsUpManagerPhone mHeadsUpManagerPhone;
+ private final HeadsUpManager mHeadsUpManager;
private final ActivityStarter mActivityStarter;
@Inject
@@ -152,9 +154,10 @@
WindowRootViewVisibilityInteractor windowRootViewVisibilityInteractor,
NotificationLockscreenUserManager notificationLockscreenUserManager,
StatusBarStateController statusBarStateController,
+ IStatusBarService statusBarService,
DeviceProvisionedController deviceProvisionedController,
MetricsLogger metricsLogger,
- HeadsUpManagerPhone headsUpManagerPhone,
+ HeadsUpManager headsUpManager,
ActivityStarter activityStarter) {
mContext = context;
mMainHandler = mainHandler;
@@ -177,9 +180,10 @@
mWindowRootViewVisibilityInteractor = windowRootViewVisibilityInteractor;
mLockscreenUserManager = notificationLockscreenUserManager;
mStatusBarStateController = statusBarStateController;
+ mStatusBarService = statusBarService;
mDeviceProvisionedController = deviceProvisionedController;
mMetricsLogger = metricsLogger;
- mHeadsUpManagerPhone = headsUpManagerPhone;
+ mHeadsUpManager = headsUpManager;
mActivityStarter = activityStarter;
}
@@ -296,7 +300,7 @@
if (mGutsListener != null) {
mGutsListener.onGutsClose(entry);
}
- mHeadsUpManagerPhone.setGutsShown(row.getEntry(), false);
+ mHeadsUpManager.setGutsShown(row.getEntry(), false);
});
View gutsView = item.getGutsView();
@@ -358,7 +362,8 @@
PackageManager pmUser = CentralSurfaces.getPackageManagerForUser(mContext,
userHandle.getIdentifier());
- feedbackInfo.bindGuts(pmUser, sbn, row.getEntry(), row, mAssistantFeedbackController);
+ feedbackInfo.bindGuts(pmUser, sbn, row.getEntry(), row, mAssistantFeedbackController,
+ mStatusBarService, this);
}
/**
@@ -676,7 +681,7 @@
row.closeRemoteInput();
mListContainer.onHeightChanged(row, true /* needsAnimation */);
mGutsMenuItem = menuItem;
- mHeadsUpManagerPhone.setGutsShown(row.getEntry(), true);
+ mHeadsUpManager.setGutsShown(row.getEntry(), true);
}
};
guts.post(mOpenRunnable);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 66b2555..9695cb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -99,7 +99,6 @@
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
-import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProvider;
import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.NotifStackController;
@@ -115,10 +114,10 @@
import com.android.systemui.statusbar.notification.row.NotificationGuts;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.NotificationSnooze;
+import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationListInteractor;
import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationListViewBinder;
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationListViewModel;
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
@@ -127,6 +126,7 @@
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.policy.SplitShadeStateController;
import com.android.systemui.statusbar.policy.ZenModeController;
@@ -156,7 +156,7 @@
private final NotificationGutsManager mNotificationGutsManager;
private final NotificationsController mNotificationsController;
private final NotificationVisibilityProvider mVisibilityProvider;
- private final HeadsUpManagerPhone mHeadsUpManager;
+ private final HeadsUpManager mHeadsUpManager;
private final NotificationRoundnessManager mNotificationRoundnessManager;
private final TunerService mTunerService;
private final DeviceProvisionedController mDeviceProvisionedController;
@@ -194,7 +194,7 @@
private final GroupExpansionManager mGroupExpansionManager;
private final NotifPipelineFlags mNotifPipelineFlags;
- private final SeenNotificationsProvider mSeenNotificationsProvider;
+ private final NotificationListInteractor mNotificationListInteractor;
private final KeyguardTransitionRepository mKeyguardTransitionRepo;
private NotificationStackScrollLayout mView;
@@ -631,7 +631,7 @@
NotificationGutsManager notificationGutsManager,
NotificationsController notificationsController,
NotificationVisibilityProvider visibilityProvider,
- HeadsUpManagerPhone headsUpManager,
+ HeadsUpManager headsUpManager,
NotificationRoundnessManager notificationRoundnessManager,
TunerService tunerService,
DeviceProvisionedController deviceProvisionedController,
@@ -662,7 +662,7 @@
UiEventLogger uiEventLogger,
NotificationRemoteInputManager remoteInputManager,
VisibilityLocationProviderDelegator visibilityLocationProviderDelegator,
- SeenNotificationsProvider seenNotificationsProvider,
+ NotificationListInteractor notificationListInteractor,
ShadeController shadeController,
InteractionJankMonitor jankMonitor,
StackStateLogger stackLogger,
@@ -715,7 +715,7 @@
mUiEventLogger = uiEventLogger;
mRemoteInputManager = remoteInputManager;
mVisibilityLocationProviderDelegator = visibilityLocationProviderDelegator;
- mSeenNotificationsProvider = seenNotificationsProvider;
+ mNotificationListInteractor = notificationListInteractor;
mShadeController = shadeController;
mNotifIconAreaController = notifIconAreaController;
mFeatureFlags = featureFlags;
@@ -2006,7 +2006,7 @@
public void setNotifStats(@NonNull NotifStats notifStats) {
mNotifStats = notifStats;
mView.setHasFilteredOutSeenNotifications(
- mSeenNotificationsProvider.getHasFilteredOutSeenNotifications());
+ mNotificationListInteractor.getHasFilteredOutSeenNotifications().getValue());
updateFooter();
updateShowEmptyShadeView();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationListRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationListRepository.kt
new file mode 100644
index 0000000..f6ed8c8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/data/repository/NotificationListRepository.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 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.statusbar.notification.stack.data.repository
+
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+/** Repository for information about the current notification list. */
+@SysUISingleton
+class NotificationListRepository @Inject constructor() {
+ private val _hasFilteredOutSeenNotifications = MutableStateFlow(false)
+ val hasFilteredOutSeenNotifications: StateFlow<Boolean> =
+ _hasFilteredOutSeenNotifications.asStateFlow()
+
+ fun setHasFilteredOutSeenNotifications(value: Boolean) {
+ _hasFilteredOutSeenNotifications.value = value
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationListInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationListInteractor.kt
new file mode 100644
index 0000000..3fd68a8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/domain/interactor/NotificationListInteractor.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 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.statusbar.notification.stack.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.stack.data.repository.NotificationListRepository
+import javax.inject.Inject
+import kotlinx.coroutines.flow.StateFlow
+
+/** Interactor for business logic associated with the notification stack. */
+@SysUISingleton
+class NotificationListInteractor
+@Inject
+constructor(
+ private val notificationListRepository: NotificationListRepository,
+) {
+ /** Are any already-seen notifications currently filtered out of the shade? */
+ val hasFilteredOutSeenNotifications: StateFlow<Boolean>
+ get() = notificationListRepository.hasFilteredOutSeenNotifications
+
+ fun setHasFilteredOutSeenNotifications(value: Boolean) {
+ notificationListRepository.setHasFilteredOutSeenNotifications(value)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 3176222..6e6318e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -220,6 +220,7 @@
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
import com.android.systemui.statusbar.policy.ExtensionController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
@@ -236,6 +237,8 @@
import com.android.wm.shell.startingsurface.SplashscreenContentDrawer;
import com.android.wm.shell.startingsurface.StartingSurface;
+import dagger.Lazy;
+
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
@@ -247,8 +250,6 @@
import javax.inject.Named;
import javax.inject.Provider;
-import dagger.Lazy;
-
/**
* A class handling initialization and coordination between some of the key central surfaces in
* System UI: The notification shade, the keyguard (lockscreen), and the status bar.
@@ -417,7 +418,7 @@
private final NotificationWakeUpCoordinator mWakeUpCoordinator;
private final KeyguardBypassController mKeyguardBypassController;
private final KeyguardStateController mKeyguardStateController;
- private final HeadsUpManagerPhone mHeadsUpManager;
+ private final HeadsUpManager mHeadsUpManager;
private final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
private final FalsingCollector mFalsingCollector;
private final FalsingManager mFalsingManager;
@@ -611,7 +612,7 @@
NotificationWakeUpCoordinator notificationWakeUpCoordinator,
KeyguardBypassController keyguardBypassController,
KeyguardStateController keyguardStateController,
- HeadsUpManagerPhone headsUpManagerPhone,
+ HeadsUpManager headsUpManager,
DynamicPrivacyController dynamicPrivacyController,
FalsingManager falsingManager,
FalsingCollector falsingCollector,
@@ -718,7 +719,7 @@
mWakeUpCoordinator = notificationWakeUpCoordinator;
mKeyguardBypassController = keyguardBypassController;
mKeyguardStateController = keyguardStateController;
- mHeadsUpManager = headsUpManagerPhone;
+ mHeadsUpManager = headsUpManager;
mBackActionInteractor = backActionInteractor;
mKeyguardIndicationController = keyguardIndicationController;
mStatusBarTouchableRegionManager = statusBarTouchableRegionManager;
@@ -1088,11 +1089,6 @@
void initShadeVisibilityListener() {
mShadeController.setVisibilityListener(new ShadeController.ShadeVisibilityListener() {
@Override
- public void visibilityChanged(boolean visible) {
- onShadeVisibilityChanged(visible);
- }
-
- @Override
public void expandedVisibleChanged(boolean expandedVisible) {
if (expandedVisible) {
setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
@@ -1195,7 +1191,7 @@
});
mStatusBarInitializer.initializeStatusBar();
- mStatusBarTouchableRegionManager.setup(this, getNotificationShadeWindowView());
+ mStatusBarTouchableRegionManager.setup(getNotificationShadeWindowView());
createNavigationBar(result);
@@ -2846,13 +2842,16 @@
mScrimController.setExpansionAffectsAlpha(!unlocking);
if (mAlternateBouncerInteractor.isVisibleState()) {
- if ((!mKeyguardStateController.isOccluded() || mShadeSurface.isPanelExpanded())
- && (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED
- || mTransitionToFullShadeProgress > 0f)) {
- mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED_SHADE);
- } else {
- mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED);
+ if (!mFeatureFlags.isEnabled(Flags.ALTERNATE_BOUNCER_VIEW)) {
+ if ((!mKeyguardStateController.isOccluded() || mShadeSurface.isPanelExpanded())
+ && (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED
+ || mTransitionToFullShadeProgress > 0f)) {
+ mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED_SHADE);
+ } else {
+ mScrimController.transitionTo(ScrimState.AUTH_SCRIMMED);
+ }
}
+
// This will cancel the keyguardFadingAway animation if it is running. We need to do
// this as otherwise it can remain pending and leave keyguard in a weird state.
mUnlockScrimCallback.onCancelled();
@@ -2915,8 +2914,6 @@
protected boolean mDeviceInteractive;
- protected boolean mVisible;
-
protected DevicePolicyManager mDevicePolicyManager;
private final PowerManager mPowerManager;
protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@@ -3034,16 +3031,6 @@
afterKeyguardGone);
}
- private void onShadeVisibilityChanged(boolean visible) {
- if (mVisible != visible) {
- mVisible = visible;
- if (visible) {
- DejankUtils.notifyRendererOfExpensiveFrame(
- getNotificationShadeWindowView(), "onShadeVisibilityChanged");
- }
- }
- }
-
private void clearNotificationEffects() {
try {
mBarService.clearNotificationEffects();
@@ -3165,7 +3152,6 @@
// TODO: Bring these out of CentralSurfaces.
mUserInfoControllerImpl.onDensityOrFontScaleChanged();
mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
- mHeadsUpManager.onDensityOrFontScaleChanged();
}
@Override
@@ -3202,7 +3188,8 @@
// down on the lockscreen), clear notification LED, vibration,
// ringing.
// Other transitions are covered in WindowRootViewVisibilityInteractor.
- if (mVisible && (newState == StatusBarState.SHADE_LOCKED
+ if (mWindowRootViewVisibilityInteractor.isLockscreenOrShadeVisible().getValue()
+ && (newState == StatusBarState.SHADE_LOCKED
|| mStatusBarStateController.goingToFullShade())) {
clearNotificationEffects();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index 4849f64..d3d11ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -49,6 +49,7 @@
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.util.Assert;
@@ -80,7 +81,7 @@
private final WakefulnessLifecycle mWakefulnessLifecycle;
private final SysuiStatusBarStateController mStatusBarStateController;
private final DeviceProvisionedController mDeviceProvisionedController;
- private final HeadsUpManagerPhone mHeadsUpManagerPhone;
+ private final HeadsUpManager mHeadsUpManager;
private final BatteryController mBatteryController;
private final ScrimController mScrimController;
private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
@@ -106,7 +107,7 @@
WakefulnessLifecycle wakefulnessLifecycle,
SysuiStatusBarStateController statusBarStateController,
DeviceProvisionedController deviceProvisionedController,
- HeadsUpManagerPhone headsUpManagerPhone, BatteryController batteryController,
+ HeadsUpManager headsUpManager, BatteryController batteryController,
ScrimController scrimController,
Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
Lazy<AssistManager> assistManagerLazy,
@@ -123,7 +124,7 @@
mWakefulnessLifecycle = wakefulnessLifecycle;
mStatusBarStateController = statusBarStateController;
mDeviceProvisionedController = deviceProvisionedController;
- mHeadsUpManagerPhone = headsUpManagerPhone;
+ mHeadsUpManager = headsUpManager;
mBatteryController = batteryController;
mScrimController = scrimController;
mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
@@ -135,7 +136,7 @@
mNotificationWakeUpCoordinator = notificationWakeUpCoordinator;
mAuthController = authController;
mNotificationIconAreaController = notificationIconAreaController;
- mHeadsUpManagerPhone.addListener(mOnHeadsUpChangedListener);
+ mHeadsUpManager.addListener(mOnHeadsUpChangedListener);
mDozeInteractor = dozeInteractor;
}
@@ -337,8 +338,8 @@
if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_REACH) {
mScrimController.setWakeLockScreenSensorActive(true);
}
- if (mDozeScrimController.isPulsing() && mHeadsUpManagerPhone.hasNotifications()) {
- mHeadsUpManagerPhone.extendHeadsUp();
+ if (mDozeScrimController.isPulsing() && mHeadsUpManager.hasNotifications()) {
+ mHeadsUpManager.extendHeadsUp();
} else {
mDozeScrimController.extendPulse();
}
@@ -493,7 +494,7 @@
mDozeScrimController.cancelPendingPulseTimeout();
}
}
- if (!isHeadsUp && !mHeadsUpManagerPhone.hasNotifications()) {
+ if (!isHeadsUp && !mHeadsUpManager.hasNotifications()) {
// There are no longer any notifications to show. We should end the
// pulse now.
stopPulsing();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index 270c40e..c493eeda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -26,9 +26,9 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.ViewClippingUtil;
-import com.android.systemui.res.R;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.res.R;
import com.android.systemui.shade.ShadeHeadsUpTracker;
import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.statusbar.CommandQueue;
@@ -43,6 +43,7 @@
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentScope;
import com.android.systemui.statusbar.policy.Clock;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.util.ViewController;
@@ -70,7 +71,7 @@
private static final SourceType HEADS_UP = SourceType.from("HeadsUp");
private static final SourceType PULSING = SourceType.from("Pulsing");
private final NotificationIconAreaController mNotificationIconAreaController;
- private final HeadsUpManagerPhone mHeadsUpManager;
+ private final HeadsUpManager mHeadsUpManager;
private final NotificationStackScrollLayoutController mStackScrollerController;
private final DarkIconDispatcher mDarkIconDispatcher;
@@ -108,7 +109,7 @@
@Inject
public HeadsUpAppearanceController(
NotificationIconAreaController notificationIconAreaController,
- HeadsUpManagerPhone headsUpManager,
+ HeadsUpManager headsUpManager,
StatusBarStateController stateController,
PhoneStatusBarTransitions phoneStatusBarTransitions,
KeyguardBypassController bypassController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index a5ea142..6b4382f73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -29,11 +29,11 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.policy.SystemBarUtils;
-import com.android.systemui.Dumpable;
-import com.android.systemui.res.R;
+import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
+import com.android.systemui.res.R;
import com.android.systemui.shade.ShadeExpansionStateManager;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -42,10 +42,12 @@
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
+import com.android.systemui.statusbar.policy.AnimationStateHandler;
+import com.android.systemui.statusbar.policy.BaseHeadsUpManager;
import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.HeadsUpManagerLogger;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
+import com.android.systemui.statusbar.policy.OnHeadsUpPhoneListenerChange;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -53,11 +55,11 @@
import java.util.List;
import java.util.Stack;
-/**
- * A implementation of HeadsUpManager for phone and car.
- */
-public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
- OnHeadsUpChangedListener {
+import javax.inject.Inject;
+
+/** A implementation of HeadsUpManager for phone. */
+@SysUISingleton
+public class HeadsUpManagerPhone extends BaseHeadsUpManager implements OnHeadsUpChangedListener {
private static final String TAG = "HeadsUpManagerPhone";
@VisibleForTesting
@@ -102,7 +104,7 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// Constructor:
-
+ @Inject
public HeadsUpManagerPhone(@NonNull final Context context,
HeadsUpManagerLogger logger,
StatusBarStateController statusBarStateController,
@@ -154,7 +156,8 @@
/**
* Add a listener to receive callbacks onHeadsUpGoingAway
*/
- void addHeadsUpPhoneListener(OnHeadsUpPhoneListenerChange listener) {
+ @Override
+ public void addHeadsUpPhoneListener(OnHeadsUpPhoneListenerChange listener) {
mHeadsUpPhoneListeners.add(listener);
}
@@ -162,7 +165,8 @@
* Gets the touchable region needed for heads up notifications. Returns null if no touchable
* region is required (ie: no heads up notification currently exists).
*/
- @Nullable Region getTouchableRegion() {
+ @Override
+ public @Nullable Region getTouchableRegion() {
NotificationEntry topEntry = getTopEntry();
// This call could be made in an inconsistent state while the pinnedMode hasn't been
@@ -197,8 +201,9 @@
* @param key the key of the touched notification
* @return whether the touch is invalid and should be discarded
*/
- boolean shouldSwallowClick(@NonNull String key) {
- HeadsUpManager.HeadsUpEntry entry = getHeadsUpEntry(key);
+ @Override
+ public boolean shouldSwallowClick(@NonNull String key) {
+ BaseHeadsUpManager.HeadsUpEntry entry = getHeadsUpEntry(key);
return entry != null && mClock.currentTimeMillis() < entry.mPostTime;
}
@@ -238,7 +243,8 @@
* Set that we are exiting the headsUp pinned mode, but some notifications might still be
* animating out. This is used to keep the touchable regions in a reasonable state.
*/
- void setHeadsUpGoingAway(boolean headsUpGoingAway) {
+ @Override
+ public void setHeadsUpGoingAway(boolean headsUpGoingAway) {
if (headsUpGoingAway != mHeadsUpGoingAway) {
mHeadsUpGoingAway = headsUpGoingAway;
for (OnHeadsUpPhoneListenerChange listener : mHeadsUpPhoneListeners) {
@@ -247,7 +253,8 @@
}
}
- boolean isHeadsUpGoingAway() {
+ @Override
+ public boolean isHeadsUpGoingAway() {
return mHeadsUpGoingAway;
}
@@ -260,8 +267,8 @@
public void setRemoteInputActive(
@NonNull NotificationEntry entry, boolean remoteInputActive) {
HeadsUpEntryPhone headsUpEntry = getHeadsUpEntryPhone(entry.getKey());
- if (headsUpEntry != null && headsUpEntry.remoteInputActive != remoteInputActive) {
- headsUpEntry.remoteInputActive = remoteInputActive;
+ if (headsUpEntry != null && headsUpEntry.mRemoteInputActive != remoteInputActive) {
+ headsUpEntry.mRemoteInputActive = remoteInputActive;
if (remoteInputActive) {
headsUpEntry.removeAutoRemovalCallbacks("setRemoteInputActive(true)");
} else {
@@ -313,6 +320,7 @@
mSwipedOutKeys.add(key);
}
+ @Override
public boolean removeNotification(@NonNull String key, boolean releaseImmediately,
boolean animate) {
if (animate) {
@@ -411,7 +419,7 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// HeadsUpEntryPhone:
- protected class HeadsUpEntryPhone extends HeadsUpManager.HeadsUpEntry {
+ protected class HeadsUpEntryPhone extends BaseHeadsUpManager.HeadsUpEntry {
private boolean mGutsShownPinned;
@@ -459,11 +467,11 @@
@Override
public void setExpanded(boolean expanded) {
- if (this.expanded == expanded) {
+ if (this.mExpanded == expanded) {
return;
}
- this.expanded = expanded;
+ this.mExpanded = expanded;
if (expanded) {
removeAutoRemovalCallbacks("setExpanded(true)");
} else {
@@ -504,21 +512,6 @@
}
}
- public interface AnimationStateHandler {
- void setHeadsUpGoingAwayAnimationsAllowed(boolean allowed);
- }
-
- /**
- * Listener to register for HeadsUpNotification Phone changes.
- */
- public interface OnHeadsUpPhoneListenerChange {
- /**
- * Called when a heads up notification is 'going away' or no longer 'going away'.
- * See {@link HeadsUpManagerPhone#setHeadsUpGoingAway}.
- */
- void onHeadsUpGoingAwayStateChanged(boolean headsUpGoingAway);
- }
-
private final StateListener mStatusBarStateListener = new StateListener() {
@Override
public void onStateChanged(int newState) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt
new file mode 100644
index 0000000..0d0f2cd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpModule.kt
@@ -0,0 +1,11 @@
+package com.android.systemui.statusbar.phone
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.policy.HeadsUpManager
+import dagger.Binds
+import dagger.Module
+
+@Module
+interface HeadsUpModule {
+ @Binds @SysUISingleton fun bindsHeadsUpManager(hum: HeadsUpManagerPhone): HeadsUpManager
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index dcbaac2..198272e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -26,13 +26,14 @@
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
/**
* A helper class to handle touches on the heads-up views.
*/
public class HeadsUpTouchHelper implements Gefingerpoken {
- private final HeadsUpManagerPhone mHeadsUpManager;
+ private final HeadsUpManager mHeadsUpManager;
private final IStatusBarService mStatusBarService;
private final Callback mCallback;
private int mTrackingPointer;
@@ -45,7 +46,7 @@
private final HeadsUpNotificationViewController mPanel;
private ExpandableNotificationRow mPickedChild;
- public HeadsUpTouchHelper(HeadsUpManagerPhone headsUpManager,
+ public HeadsUpTouchHelper(HeadsUpManager headsUpManager,
IStatusBarService statusBarService,
Callback callback,
HeadsUpNotificationViewController notificationPanelView) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java
index 4b39854..235ed25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeadsUpChangeListener.java
@@ -24,6 +24,7 @@
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.window.StatusBarWindowController;
@@ -39,7 +40,7 @@
private final ShadeViewController mShadeViewController;
private final NotificationStackScrollLayoutController mNsslController;
private final KeyguardBypassController mKeyguardBypassController;
- private final HeadsUpManagerPhone mHeadsUpManager;
+ private final HeadsUpManager mHeadsUpManager;
private final StatusBarStateController mStatusBarStateController;
private final NotificationRemoteInputManager mNotificationRemoteInputManager;
@@ -50,7 +51,7 @@
ShadeViewController shadeViewController,
NotificationStackScrollLayoutController nsslController,
KeyguardBypassController keyguardBypassController,
- HeadsUpManagerPhone headsUpManager,
+ HeadsUpManager headsUpManager,
StatusBarStateController statusBarStateController,
NotificationRemoteInputManager notificationRemoteInputManager) {
mNotificationShadeWindowController = notificationShadeWindowController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index eedf35f..62b2445 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -1573,6 +1573,9 @@
* notification shade's child views.
*/
public boolean shouldInterceptTouchEvent(MotionEvent event) {
+ if (mFlags.isEnabled(Flags.ALTERNATE_BOUNCER_VIEW)) {
+ return false;
+ }
return mAlternateBouncerInteractor.isVisibleState();
}
@@ -1581,6 +1584,10 @@
* showing.
*/
public boolean onTouch(MotionEvent event) {
+ if (mFlags.isEnabled(Flags.ALTERNATE_BOUNCER_VIEW)) {
+ return false;
+ }
+
boolean handleTouch = shouldInterceptTouchEvent(event);
if (handleTouch) {
final boolean actionDown = event.getActionMasked() == MotionEvent.ACTION_DOWN;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index dc4c709..dbee080 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -76,6 +76,7 @@
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowDragController;
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.HeadsUpUtil;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.wmshell.BubblesManager;
@@ -102,7 +103,7 @@
private final Executor mUiBgExecutor;
private final NotificationVisibilityProvider mVisibilityProvider;
- private final HeadsUpManagerPhone mHeadsUpManager;
+ private final HeadsUpManager mHeadsUpManager;
private final ActivityStarter mActivityStarter;
private final NotificationClickNotifier mClickNotifier;
private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@@ -141,7 +142,7 @@
Handler mainThreadHandler,
Executor uiBgExecutor,
NotificationVisibilityProvider visibilityProvider,
- HeadsUpManagerPhone headsUpManager,
+ HeadsUpManager headsUpManager,
ActivityStarter activityStarter,
NotificationClickNotifier clickNotifier,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
@@ -213,7 +214,9 @@
*/
@Override
public void onNotificationClicked(NotificationEntry entry, ExpandableNotificationRow row) {
- mLogger.logStartingActivityFromClick(entry);
+ mLogger.logStartingActivityFromClick(entry, row.isHeadsUpState(),
+ mKeyguardStateController.isVisible(),
+ mNotificationShadeWindowController.getPanelExpanded());
if (mRemoteInputManager.isRemoteInputActive(entry)) {
// We have an active remote input typed and the user clicked on the notification.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt
index 2d30a12..4211cab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt
@@ -30,11 +30,16 @@
class StatusBarNotificationActivityStarterLogger @Inject constructor(
@NotifInteractionLog private val buffer: LogBuffer
) {
- fun logStartingActivityFromClick(entry: NotificationEntry) {
+ fun logStartingActivityFromClick(entry: NotificationEntry, isHeadsUpState: Boolean,
+ isKeyguardVisible: Boolean, isPanelExpanded: Boolean) {
buffer.log(TAG, DEBUG, {
str1 = entry.logKey
+ bool1 = isHeadsUpState
+ bool2 = isKeyguardVisible
+ bool3 = isPanelExpanded
}, {
- "(1/5) onNotificationClicked: $str1"
+ "(1/5) onNotificationClicked: $str1 isHeadsUpState: $bool1 " +
+ "isKeyguardVisible: $bool2 isPanelExpanded: $bool3"
})
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index fb7f9d1..2d14f6b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -31,11 +31,11 @@
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.InitController;
-import com.android.systemui.res.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.power.domain.interactor.PowerInteractor;
+import com.android.systemui.res.R;
import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.QuickSettingsController;
import com.android.systemui.shade.ShadeViewController;
@@ -60,6 +60,7 @@
import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import javax.inject.Inject;
@@ -76,7 +77,7 @@
private final NotificationMediaManager mMediaManager;
private final NotificationGutsManager mGutsManager;
private final ShadeViewController mNotificationPanel;
- private final HeadsUpManagerPhone mHeadsUpManager;
+ private final HeadsUpManager mHeadsUpManager;
private final AboveShelfObserver mAboveShelfObserver;
private final DozeScrimController mDozeScrimController;
private final NotificationsInteractor mNotificationsInteractor;
@@ -98,7 +99,7 @@
Context context,
ShadeViewController panel,
QuickSettingsController quickSettingsController,
- HeadsUpManagerPhone headsUp,
+ HeadsUpManager headsUp,
NotificationShadeWindowView statusBarWindow,
ActivityStarter activityStarter,
NotificationStackScrollLayoutController stackScrollerController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
index 40bd8d3..ba73c10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -31,15 +31,18 @@
import com.android.internal.policy.SystemBarUtils;
import com.android.systemui.Dumpable;
-import com.android.systemui.res.R;
import com.android.systemui.ScreenDecorations;
+import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
+import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.res.R;
import com.android.systemui.scene.domain.interactor.SceneInteractor;
import com.android.systemui.scene.shared.flag.SceneContainerFlags;
import com.android.systemui.shade.ShadeExpansionStateManager;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.util.kotlin.JavaAdapter;
@@ -58,13 +61,12 @@
private static final String TAG = "TouchableRegionManager";
private final Context mContext;
- private final HeadsUpManagerPhone mHeadsUpManager;
+ private final HeadsUpManager mHeadsUpManager;
private final NotificationShadeWindowController mNotificationShadeWindowController;
private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private boolean mIsStatusBarExpanded = false;
private boolean mShouldAdjustInsets = false;
- private CentralSurfaces mCentralSurfaces;
private View mNotificationShadeWindowView;
private View mNotificationPanelView;
private boolean mForceCollapsedUntilLayout = false;
@@ -72,6 +74,8 @@
private Region mTouchableRegion = new Region();
private int mDisplayCutoutTouchableRegionSize;
private int mStatusBarHeight;
+ private final PrimaryBouncerInteractor mPrimaryBouncerInteractor;
+ private final AlternateBouncerInteractor mAlternateBouncerInteractor;
private final OnComputeInternalInsetsListener mOnComputeInternalInsetsListener;
@@ -80,12 +84,14 @@
Context context,
NotificationShadeWindowController notificationShadeWindowController,
ConfigurationController configurationController,
- HeadsUpManagerPhone headsUpManager,
+ HeadsUpManager headsUpManager,
ShadeExpansionStateManager shadeExpansionStateManager,
Provider<SceneInteractor> sceneInteractor,
Provider<JavaAdapter> javaAdapter,
SceneContainerFlags sceneContainerFlags,
- UnlockedScreenOffAnimationController unlockedScreenOffAnimationController
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
+ PrimaryBouncerInteractor primaryBouncerInteractor,
+ AlternateBouncerInteractor alternateBouncerInteractor
) {
mContext = context;
initResources();
@@ -128,13 +134,12 @@
this::onShadeExpansionFullyChanged);
}
+ mPrimaryBouncerInteractor = primaryBouncerInteractor;
+ mAlternateBouncerInteractor = alternateBouncerInteractor;
mOnComputeInternalInsetsListener = this::onComputeInternalInsets;
}
- protected void setup(
- @NonNull CentralSurfaces centralSurfaces,
- @NonNull View notificationShadeWindowView) {
- mCentralSurfaces = centralSurfaces;
+ protected void setup(@NonNull View notificationShadeWindowView) {
mNotificationShadeWindowView = notificationShadeWindowView;
mNotificationPanelView = mNotificationShadeWindowView.findViewById(R.id.notification_panel);
}
@@ -260,7 +265,8 @@
// since we don't want stray touches to go through the light reveal scrim to whatever is
// underneath.
return mIsStatusBarExpanded
- || mCentralSurfaces.isBouncerShowing()
+ || mPrimaryBouncerInteractor.isShowing().getValue()
+ || mAlternateBouncerInteractor.isVisibleState()
|| mUnlockedScreenOffAnimationController.isAnimationPlaying();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index babd435..63c022c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -38,11 +38,11 @@
import com.android.app.animation.InterpolatorsAndroidX;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.Dumpable;
-import com.android.systemui.res.R;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.res.R;
import com.android.systemui.shade.ShadeExpansionStateManager;
import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.statusbar.CommandQueue;
@@ -74,8 +74,6 @@
import com.android.systemui.util.CarrierConfigTracker.DefaultDataSubscriptionChangedListener;
import com.android.systemui.util.settings.SecureSettings;
-import kotlin.Unit;
-
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -85,6 +83,7 @@
import java.util.concurrent.Executor;
import javax.inject.Inject;
+import kotlin.Unit;
/**
* Contains the collapsed status bar and handles hiding/showing based on disable flags
@@ -279,7 +278,8 @@
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mDumpManager.registerDumpable(getClass().getSimpleName(), this);
- mStatusBarFragmentComponent = mStatusBarFragmentComponentFactory.create(this);
+ mStatusBarFragmentComponent = mStatusBarFragmentComponentFactory.create(
+ (PhoneStatusBarView) getView());
mStatusBarFragmentComponent.init();
mStartableStates.clear();
for (Startable startable : mStatusBarFragmentComponent.getStartables()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java
index d9a5844..0618abb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentComponent.java
@@ -27,11 +27,11 @@
import com.android.systemui.statusbar.phone.StatusBarDemoMode;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
-import java.util.Set;
-
import dagger.BindsInstance;
import dagger.Subcomponent;
+import java.util.Set;
+
/**
* A subcomponent that gets re-created each time we create a new {@link CollapsedStatusBarFragment}.
*
@@ -54,7 +54,7 @@
@Subcomponent.Factory
interface Factory {
StatusBarFragmentComponent create(
- @BindsInstance CollapsedStatusBarFragment collapsedStatusBarFragment);
+ @BindsInstance @RootView PhoneStatusBarView phoneStatusBarView);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java
index 6ef877b..3741f14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/dagger/StatusBarFragmentModule.java
@@ -19,15 +19,14 @@
import android.view.View;
import android.view.ViewStub;
-import com.android.systemui.res.R;
import com.android.systemui.battery.BatteryMeterView;
import com.android.systemui.dagger.qualifiers.RootView;
+import com.android.systemui.res.R;
import com.android.systemui.statusbar.HeadsUpStatusBarView;
import com.android.systemui.statusbar.phone.PhoneStatusBarTransitions;
import com.android.systemui.statusbar.phone.PhoneStatusBarView;
import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
import com.android.systemui.statusbar.phone.StatusBarLocation;
-import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.phone.userswitcher.StatusBarUserSwitcherContainer;
import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.statusbar.window.StatusBarWindowController;
@@ -51,15 +50,6 @@
/** */
@Provides
- @RootView
- @StatusBarFragmentScope
- static PhoneStatusBarView providePhoneStatusBarView(
- CollapsedStatusBarFragment collapsedStatusBarFragment) {
- return (PhoneStatusBarView) collapsedStatusBarFragment.getView();
- }
-
- /** */
- @Provides
@StatusBarFragmentScope
static BatteryMeterView provideBatteryMeterView(@RootView PhoneStatusBarView view) {
return view.findViewById(R.id.battery);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
similarity index 93%
rename from packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
index e59ec04..cec76f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BaseHeadsUpManager.java
@@ -34,8 +34,8 @@
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.EventLogTags;
-import com.android.systemui.res.R;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.res.R;
import com.android.systemui.statusbar.AlertingNotificationManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
@@ -47,7 +47,8 @@
* A manager which handles heads up notifications which is a special mode where
* they simply peek from the top of the screen.
*/
-public abstract class HeadsUpManager extends AlertingNotificationManager {
+public abstract class BaseHeadsUpManager extends AlertingNotificationManager implements
+ HeadsUpManager {
private static final String TAG = "HeadsUpManager";
private static final String SETTING_HEADS_UP_SNOOZE_LENGTH_MS = "heads_up_snooze_length_ms";
@@ -81,7 +82,7 @@
}
}
- public HeadsUpManager(@NonNull final Context context,
+ public BaseHeadsUpManager(@NonNull final Context context,
HeadsUpManagerLogger logger,
@Main Handler handler,
AccessibilityManagerWrapper accessibilityManagerWrapper,
@@ -131,6 +132,7 @@
mListeners.remove(listener);
}
+ /** Updates the notification with the given key. */
public void updateNotification(@NonNull String key, boolean alert) {
super.updateNotification(key, alert);
HeadsUpEntry headsUpEntry = getHeadsUpEntry(key);
@@ -146,7 +148,7 @@
// the NotificationEntry into AlertingNotificationManager's mAlertEntries map.
return hasFullScreenIntent(entry);
}
- return hasFullScreenIntent(entry) && !headsUpEntry.wasUnpinned;
+ return hasFullScreenIntent(entry) && !headsUpEntry.mWasUnpinned;
}
protected boolean hasFullScreenIntent(@NonNull NotificationEntry entry) {
@@ -154,11 +156,11 @@
}
protected void setEntryPinned(
- @NonNull HeadsUpManager.HeadsUpEntry headsUpEntry, boolean isPinned) {
+ @NonNull BaseHeadsUpManager.HeadsUpEntry headsUpEntry, boolean isPinned) {
mLogger.logSetEntryPinned(headsUpEntry.mEntry, isPinned);
NotificationEntry entry = headsUpEntry.mEntry;
if (!isPinned) {
- headsUpEntry.wasUnpinned = true;
+ headsUpEntry.mWasUnpinned = true;
}
if (entry.isRowPinned() != isPinned) {
entry.setRowPinned(isPinned);
@@ -292,10 +294,12 @@
mUser = user;
}
+ /** Returns the ID of the current user. */
public int getUser() {
return mUser;
}
+ @Override
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("HeadsUpManager state:");
dumpInternal(pw, args);
@@ -309,9 +313,9 @@
for (AlertEntry entry: mAlertEntries.values()) {
pw.print(" HeadsUpEntry="); pw.println(entry.mEntry);
}
- int N = mSnoozedPackages.size();
- pw.println(" snoozed packages: " + N);
- for (int i = 0; i < N; i++) {
+ int n = mSnoozedPackages.size();
+ pw.println(" snoozed packages: " + n);
+ for (int i = 0; i < n; i++) {
pw.print(" "); pw.print(mSnoozedPackages.valueAt(i));
pw.print(", "); pw.println(mSnoozedPackages.keyAt(i));
}
@@ -399,20 +403,20 @@
*
* @param entry the entry that might be indirectly removed by the user's action
*
- * @see com.android.systemui.statusbar.notification.collection.coordinator.HeadsUpCoordinator#mActionPressListener
+ * @see HeadsUpCoordinator#mActionPressListener
* @see #canRemoveImmediately(String)
*/
public void setUserActionMayIndirectlyRemove(@NonNull NotificationEntry entry) {
HeadsUpEntry headsUpEntry = getHeadsUpEntry(entry.getKey());
if (headsUpEntry != null) {
- headsUpEntry.userActionMayIndirectlyRemove = true;
+ headsUpEntry.mUserActionMayIndirectlyRemove = true;
}
}
@Override
public boolean canRemoveImmediately(@NonNull String key) {
HeadsUpEntry headsUpEntry = getHeadsUpEntry(key);
- if (headsUpEntry != null && headsUpEntry.userActionMayIndirectlyRemove) {
+ if (headsUpEntry != null && headsUpEntry.mUserActionMayIndirectlyRemove) {
return true;
}
return super.canRemoveImmediately(key);
@@ -424,9 +428,6 @@
return new HeadsUpEntry();
}
- public void onDensityOrFontScaleChanged() {
- }
-
/**
* Determines if the notification is for a critical call that must display on top of an active
* input notification.
@@ -445,16 +446,16 @@
* lifecycle automatically when created.
*/
protected class HeadsUpEntry extends AlertEntry {
- public boolean remoteInputActive;
- public boolean userActionMayIndirectlyRemove;
+ public boolean mRemoteInputActive;
+ public boolean mUserActionMayIndirectlyRemove;
- protected boolean expanded;
- protected boolean wasUnpinned;
+ protected boolean mExpanded;
+ protected boolean mWasUnpinned;
@Override
public boolean isSticky() {
- return (mEntry.isRowPinned() && expanded)
- || remoteInputActive
+ return (mEntry.isRowPinned() && mExpanded)
+ || mRemoteInputActive
|| hasFullScreenIntent(mEntry);
}
@@ -490,9 +491,9 @@
return 1;
}
- if (remoteInputActive && !headsUpEntry.remoteInputActive) {
+ if (mRemoteInputActive && !headsUpEntry.mRemoteInputActive) {
return -1;
- } else if (!remoteInputActive && headsUpEntry.remoteInputActive) {
+ } else if (!mRemoteInputActive && headsUpEntry.mRemoteInputActive) {
return 1;
}
@@ -500,14 +501,14 @@
}
public void setExpanded(boolean expanded) {
- this.expanded = expanded;
+ this.mExpanded = expanded;
}
@Override
public void reset() {
super.reset();
- expanded = false;
- remoteInputActive = false;
+ mExpanded = false;
+ mRemoteInputActive = false;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt
new file mode 100644
index 0000000..d9527fe
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.kt
@@ -0,0 +1,245 @@
+package com.android.systemui.statusbar.policy
+
+import android.graphics.Region
+import com.android.systemui.Dumpable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import dagger.Binds
+import dagger.Module
+import java.io.PrintWriter
+import java.util.stream.Stream
+import javax.inject.Inject
+
+/**
+ * A manager which handles heads up notifications which is a special mode where they simply peek
+ * from the top of the screen.
+ */
+interface HeadsUpManager : Dumpable {
+ /** The stream of all current notifications managed by this manager. */
+ val allEntries: Stream<NotificationEntry>
+
+ /** Add a listener to receive callbacks onHeadsUpGoingAway. */
+ fun addHeadsUpPhoneListener(listener: OnHeadsUpPhoneListenerChange)
+
+ /** Adds an OnHeadUpChangedListener to observe events. */
+ fun addListener(listener: OnHeadsUpChangedListener)
+
+ fun addSwipedOutNotification(key: String)
+
+ /**
+ * Whether or not the alert can be removed currently. If it hasn't been on screen long enough it
+ * should not be removed unless forced
+ *
+ * @param key the key to check if removable
+ * @return true if the alert entry can be removed
+ */
+ fun canRemoveImmediately(key: String): Boolean
+
+ /**
+ * Compare two entries and decide how they should be ranked.
+ *
+ * @return -1 if the first argument should be ranked higher than the second, 1 if the second one
+ * should be ranked higher and 0 if they are equal.
+ */
+ fun compare(a: NotificationEntry?, b: NotificationEntry?): Int
+ /**
+ * Extends the lifetime of the currently showing pulsing notification so that the pulse lasts
+ * longer.
+ */
+ fun extendHeadsUp()
+
+ /** Returns when a HUN entry should be removed in milliseconds from now. */
+ fun getEarliestRemovalTime(key: String?): Long
+
+ /** Returns the top Heads Up Notification, which appears to show at first. */
+ fun getTopEntry(): NotificationEntry?
+
+ /**
+ * Gets the touchable region needed for heads up notifications. Returns null if no touchable
+ * region is required (ie: no heads up notification currently exists).
+ */
+ fun getTouchableRegion(): Region?
+
+ /**
+ * Whether or not there are any active alerting notifications.
+ *
+ * @return true if there is an alert, false otherwise
+ */
+ fun hasNotifications(): Boolean = false
+
+ /** Returns whether there are any pinned Heads Up Notifications or not. */
+ fun hasPinnedHeadsUp(): Boolean
+
+ /** Returns whether or not the given notification is alerting and managed by this manager. */
+ fun isAlerting(key: String): Boolean
+
+ fun isHeadsUpGoingAway(): Boolean
+
+ /** Returns if the given notification is snoozed or not. */
+ fun isSnoozed(packageName: String): Boolean
+
+ /** Returns whether the entry is (pinned and expanded) or (has an active remote input). */
+ fun isSticky(key: String?): Boolean
+
+ fun isTrackingHeadsUp(): Boolean
+
+ fun onExpandingFinished()
+
+ /** Removes the OnHeadUpChangedListener from the observer list. */
+ fun removeListener(listener: OnHeadsUpChangedListener)
+
+ /**
+ * Try to remove the notification. May not succeed if the notification has not been shown long
+ * enough and needs to be kept around.
+ *
+ * @param key the key of the notification to remove
+ * @param releaseImmediately force a remove regardless of earliest removal time
+ * @return true if notification is removed, false otherwise
+ */
+ fun removeNotification(key: String, releaseImmediately: Boolean): Boolean
+
+ /**
+ * Try to remove the notification. May not succeed if the notification has not been shown long
+ * enough and needs to be kept around.
+ *
+ * @param key the key of the notification to remove
+ * @param releaseImmediately force a remove regardless of earliest removal time
+ * @param animate if true, animate the removal
+ * @return true if notification is removed, false otherwise
+ */
+ fun removeNotification(key: String, releaseImmediately: Boolean, animate: Boolean): Boolean
+
+ /** Clears all managed notifications. */
+ fun releaseAllImmediately()
+
+ fun setAnimationStateHandler(handler: AnimationStateHandler)
+
+ /**
+ * Set an entry to be expanded and therefore stick in the heads up area if it's pinned until
+ * it's collapsed again.
+ */
+ fun setExpanded(entry: NotificationEntry, expanded: Boolean)
+
+ /**
+ * Sets whether an entry's guts are exposed and therefore it should stick in the heads up area
+ * if it's pinned until it's hidden again.
+ */
+ fun setGutsShown(entry: NotificationEntry, gutsShown: Boolean)
+
+ /**
+ * Set that we are exiting the headsUp pinned mode, but some notifications might still be
+ * animating out. This is used to keep the touchable regions in a reasonable state.
+ */
+ fun setHeadsUpGoingAway(headsUpGoingAway: Boolean)
+
+ /**
+ * Notifies that a remote input textbox in notification gets active or inactive.
+ *
+ * @param entry The entry of the target notification.
+ * @param remoteInputActive True to notify active, False to notify inactive.
+ */
+ fun setRemoteInputActive(entry: NotificationEntry, remoteInputActive: Boolean)
+
+ fun setTrackingHeadsUp(tracking: Boolean)
+
+ /** Sets the current user. */
+ fun setUser(user: Int)
+
+ /**
+ * Notes that the user took an action on an entry that might indirectly cause the system or the
+ * app to remove the notification.
+ *
+ * @param entry the entry that might be indirectly removed by the user's action
+ * @see
+ * com.android.systemui.statusbar.notification.collection.coordinator.HeadsUpCoordinator.mActionPressListener
+ * @see .canRemoveImmediately
+ */
+ fun setUserActionMayIndirectlyRemove(entry: NotificationEntry)
+
+ /**
+ * Decides whether a click is invalid for a notification, i.e. it has not been shown long enough
+ * that a user might have consciously clicked on it.
+ *
+ * @param key the key of the touched notification
+ * @return whether the touch is invalid and should be discarded
+ */
+ fun shouldSwallowClick(key: String): Boolean
+
+ /**
+ * Called when posting a new notification that should alert the user and appear on screen. Adds
+ * the notification to be managed.
+ *
+ * @param entry entry to show
+ */
+ fun showNotification(entry: NotificationEntry)
+
+ fun snooze()
+
+ /**
+ * Unpins all pinned Heads Up Notifications.
+ *
+ * @param userUnPinned The unpinned action is trigger by user real operation.
+ */
+ fun unpinAll(userUnPinned: Boolean)
+
+ fun updateNotification(key: String, alert: Boolean)
+}
+
+/** Sets the animation state of the HeadsUpManager. */
+interface AnimationStateHandler {
+ fun setHeadsUpGoingAwayAnimationsAllowed(allowed: Boolean)
+}
+
+/** Listener to register for HeadsUpNotification Phone changes. */
+interface OnHeadsUpPhoneListenerChange {
+ /**
+ * Called when a heads up notification is 'going away' or no longer 'going away'. See
+ * [HeadsUpManager.setHeadsUpGoingAway].
+ */
+ fun onHeadsUpGoingAwayStateChanged(headsUpGoingAway: Boolean)
+}
+
+/* No op impl of HeadsUpManager. */
+class HeadsUpManagerEmptyImpl @Inject constructor() : HeadsUpManager {
+ override val allEntries = Stream.empty<NotificationEntry>()
+ override fun addHeadsUpPhoneListener(listener: OnHeadsUpPhoneListenerChange) {}
+ override fun addListener(listener: OnHeadsUpChangedListener) {}
+ override fun addSwipedOutNotification(key: String) {}
+ override fun canRemoveImmediately(key: String) = false
+ override fun compare(a: NotificationEntry?, b: NotificationEntry?) = 0
+ override fun dump(pw: PrintWriter, args: Array<out String>) {}
+ override fun extendHeadsUp() {}
+ override fun getEarliestRemovalTime(key: String?) = 0L
+ override fun getTouchableRegion(): Region? = null
+ override fun getTopEntry() = null
+ override fun hasPinnedHeadsUp() = false
+ override fun isAlerting(key: String) = false
+ override fun isHeadsUpGoingAway() = false
+ override fun isSnoozed(packageName: String) = false
+ override fun isSticky(key: String?) = false
+ override fun isTrackingHeadsUp() = false
+ override fun onExpandingFinished() {}
+ override fun releaseAllImmediately() {}
+ override fun removeListener(listener: OnHeadsUpChangedListener) {}
+ override fun removeNotification(key: String, releaseImmediately: Boolean) = false
+ override fun removeNotification(key: String, releaseImmediately: Boolean, animate: Boolean) =
+ false
+ override fun setAnimationStateHandler(handler: AnimationStateHandler) {}
+ override fun setExpanded(entry: NotificationEntry, expanded: Boolean) {}
+ override fun setGutsShown(entry: NotificationEntry, gutsShown: Boolean) {}
+ override fun setHeadsUpGoingAway(headsUpGoingAway: Boolean) {}
+ override fun setRemoteInputActive(entry: NotificationEntry, remoteInputActive: Boolean) {}
+ override fun setTrackingHeadsUp(tracking: Boolean) {}
+ override fun setUser(user: Int) {}
+ override fun setUserActionMayIndirectlyRemove(entry: NotificationEntry) {}
+ override fun shouldSwallowClick(key: String): Boolean = false
+ override fun showNotification(entry: NotificationEntry) {}
+ override fun snooze() {}
+ override fun unpinAll(userUnPinned: Boolean) {}
+ override fun updateNotification(key: String, alert: Boolean) {}
+}
+
+@Module
+interface HeadsUpEmptyImplModule {
+ @Binds @SysUISingleton fun bindsHeadsUpManager(noOpHum: HeadsUpManagerEmptyImpl): HeadsUpManager
+}
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
index ce9d6fd..dbc3bf3 100644
--- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/UserInteractor.kt
@@ -325,6 +325,7 @@
addAction(Intent.ACTION_USER_SWITCHED)
addAction(Intent.ACTION_USER_STOPPED)
addAction(Intent.ACTION_USER_UNLOCKED)
+ addAction(Intent.ACTION_LOCALE_CHANGED)
},
user = UserHandle.SYSTEM,
map = { intent, _ -> intent },
@@ -615,6 +616,7 @@
) {
val shouldRefreshAllUsers =
when (intent.action) {
+ Intent.ACTION_LOCALE_CHANGED -> true
Intent.ACTION_USER_SWITCHED -> {
dismissDialog()
val selectedUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1)
@@ -644,6 +646,11 @@
}
private fun restartSecondaryService(@UserIdInt userId: Int) {
+ // Do not start service for user that is marked for deletion.
+ if (!manager.aliveUsers.map { it.id }.contains(userId)) {
+ return
+ }
+
val intent = Intent(applicationContext, SystemUISecondaryUserService::class.java)
// Disconnect from the old secondary user's service
val secondaryUserId = repository.secondaryUserId
@@ -657,6 +664,7 @@
// Connect to the new secondary user's service (purely to ensure that a persistent
// SystemUI application is created for that user)
+
if (userId != Process.myUserHandle().identifier) {
applicationContext.startServiceAsUser(
intent,
diff --git a/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt b/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt
index d3f83b1..20f0fa8c 100644
--- a/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModel.kt
@@ -68,6 +68,7 @@
private val hasCancelButtonBeenClicked = MutableStateFlow(false)
private val isFinishRequiredDueToExecutedAction = MutableStateFlow(false)
+ private val userSwitched = MutableStateFlow(false)
/**
* Whether the observer should finish the experience. Once consumed, [onFinished] must be called
@@ -89,6 +90,7 @@
fun onFinished() {
hasCancelButtonBeenClicked.value = false
isFinishRequiredDueToExecutedAction.value = false
+ userSwitched.value = false
}
/** Notifies that the user has clicked the "open menu" button. */
@@ -121,8 +123,9 @@
hasCancelButtonBeenClicked,
// If an executed action told us to finish, we should finish,
isFinishRequiredDueToExecutedAction,
- ) { cancelButtonClicked, executedActionFinish ->
- cancelButtonClicked || executedActionFinish
+ userSwitched,
+ ) { cancelButtonClicked, executedActionFinish, userSwitched ->
+ cancelButtonClicked || executedActionFinish || userSwitched
}
private fun toViewModel(
@@ -191,7 +194,10 @@
return if (!model.isSelectable) {
null
} else {
- { userInteractor.selectUser(model.id) }
+ {
+ userInteractor.selectUser(model.id)
+ userSwitched.value = true
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/ReferenceExt.kt b/packages/SystemUI/src/com/android/systemui/util/ReferenceExt.kt
new file mode 100644
index 0000000..ac04d31
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/ReferenceExt.kt
@@ -0,0 +1,50 @@
+package com.android.systemui.util
+
+import java.lang.ref.SoftReference
+import java.lang.ref.WeakReference
+import kotlin.properties.ReadWriteProperty
+import kotlin.reflect.KProperty
+
+/**
+ * Creates a Kotlin idiomatic weak reference.
+ *
+ * Usage:
+ * ```
+ * var weakReferenceObj: Object? by weakReference(null)
+ * weakReferenceObj = Object()
+ * ```
+ */
+fun <T> weakReference(obj: T? = null): ReadWriteProperty<Any?, T?> {
+ return object : ReadWriteProperty<Any?, T?> {
+ var weakRef = WeakReference<T?>(obj)
+ override fun getValue(thisRef: Any?, property: KProperty<*>): T? {
+ return weakRef.get()
+ }
+
+ override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
+ weakRef = WeakReference(value)
+ }
+ }
+}
+
+/**
+ * Creates a Kotlin idiomatic soft reference.
+ *
+ * Usage:
+ * ```
+ * var softReferenceObj: Object? by softReference(null)
+ * softReferenceObj = Object()
+ * ```
+ */
+fun <T> softReference(obj: T? = null): ReadWriteProperty<Any?, T?> {
+ return object : ReadWriteProperty<Any?, T?> {
+ var softRef = SoftReference<T?>(obj)
+ override fun getValue(thisRef: Any?, property: KProperty<*>): T? {
+ return softRef.get()
+ }
+
+ override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
+ softRef = SoftReference(value)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
index 750b6f9..2132904 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java
@@ -40,12 +40,13 @@
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.settingslib.Utils;
-import com.android.systemui.res.R;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.res.R;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -68,6 +69,7 @@
private final Executor mExecutor;
private final Handler mHandler;
private final FalsingManager mFalsingManager;
+ private final KeyguardFaceAuthInteractor mKeyguardFaceAuthInteractor;
private FalsingCollector mFalsingCollector;
private final UserTracker mUserTracker;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -91,7 +93,8 @@
UserTracker userTracker,
KeyguardUpdateMonitor keyguardUpdateMonitor,
StatusBarKeyguardViewManager keyguardViewManager,
- UiEventLogger uiEventLogger) {
+ UiEventLogger uiEventLogger,
+ KeyguardFaceAuthInteractor keyguardFaceAuthInteractor) {
mKeyguardStateController = keyguardStateController;
mKeyguardDismissUtil = keyguardDismissUtil;
mActivityStarter = activityStarter;
@@ -103,6 +106,7 @@
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mKeyguardViewManager = keyguardViewManager;
mUiEventLogger = uiEventLogger;
+ mKeyguardFaceAuthInteractor = keyguardFaceAuthInteractor;
}
@Override
@@ -209,6 +213,7 @@
true,
Utils.getColorAttrDefaultColor(
this, com.android.internal.R.attr.colorAccentPrimary));
+ mKeyguardFaceAuthInteractor.onWalletLaunched();
mKeyguardViewManager.requestFace(true);
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
index f943acd..d8a2c5f 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
@@ -25,7 +25,6 @@
import com.android.internal.util.LatencyTracker
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.flags.FakeFeatureFlags
@@ -47,7 +46,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class KeyguardPasswordViewControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
index e090093..dc1618d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
@@ -25,7 +25,6 @@
import com.android.internal.util.LatencyTracker
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.classifier.FalsingCollectorFake
@@ -53,7 +52,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class KeyguardPatternViewControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
index 8322b37..4a24e4a 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java
@@ -31,14 +31,13 @@
import com.android.internal.util.LatencyTracker;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.systemui.res.R;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.classifier.SingleTapClassifier;
import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.flags.Flags;
+import com.android.systemui.res.R;
import org.junit.Before;
import org.junit.Test;
@@ -47,7 +46,6 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4.class)
@RunWithLooper
public class KeyguardPinBasedInputViewControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
index 2f08804..9df4dd4 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt
@@ -26,7 +26,6 @@
import com.android.internal.widget.LockPatternUtils
import com.android.keyguard.KeyguardSecurityModel.SecurityMode
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.classifier.FalsingCollectorFake
@@ -53,7 +52,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class KeyguardPinViewControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
index d54843d3..62f9a9d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
@@ -36,7 +36,6 @@
import com.android.internal.widget.LockPatternUtils
import com.android.keyguard.KeyguardSecurityContainer.UserSwitcherViewMode.UserSwitcherCallback
import com.android.keyguard.KeyguardSecurityModel.SecurityMode
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.FaceAuthAccessibilityDelegate
import com.android.systemui.biometrics.SideFpsController
@@ -100,7 +99,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@RunWithLooper
class KeyguardSecurityContainerControllerTest : SysuiTestCase() {
@@ -812,6 +810,7 @@
SceneKey.Bouncer,
flowOf(.5f),
false,
+ isUserInputOngoing = flowOf(false),
)
runCurrent()
sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer, null), "reason")
@@ -827,7 +826,8 @@
SceneKey.Bouncer,
SceneKey.Gone,
flowOf(.5f),
- false
+ false,
+ isUserInputOngoing = flowOf(false),
)
runCurrent()
sceneInteractor.onSceneChanged(SceneModel(SceneKey.Gone, null), "reason")
@@ -844,7 +844,8 @@
SceneKey.Gone,
SceneKey.Bouncer,
flowOf(.5f),
- false
+ false,
+ isUserInputOngoing = flowOf(false),
)
runCurrent()
sceneInteractor.onSceneChanged(SceneModel(SceneKey.Bouncer, null), "reason")
@@ -862,7 +863,8 @@
SceneKey.Bouncer,
SceneKey.Gone,
flowOf(.5f),
- false
+ false,
+ isUserInputOngoing = flowOf(false),
)
runCurrent()
sceneInteractor.onSceneChanged(SceneModel(SceneKey.Gone, null), "reason")
@@ -878,6 +880,7 @@
SceneKey.Lockscreen,
flowOf(.5f),
false,
+ isUserInputOngoing = flowOf(false),
)
runCurrent()
sceneInteractor.onSceneChanged(SceneModel(SceneKey.Lockscreen, null), "reason")
@@ -895,6 +898,7 @@
SceneKey.Gone,
flowOf(.5f),
false,
+ isUserInputOngoing = flowOf(false),
)
runCurrent()
sceneInteractor.onSceneChanged(SceneModel(SceneKey.Gone, null), "reason")
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
index aad11d9..156e068 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
@@ -56,11 +56,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.systemui.res.R;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingA11yDelegate;
import com.android.systemui.plugins.FalsingManager;
+import com.android.systemui.res.R;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.user.data.source.UserRecord;
import com.android.systemui.util.settings.GlobalSettings;
@@ -76,7 +75,6 @@
import java.util.ArrayList;
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper()
public class KeyguardSecurityContainerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
index b02b1f9..7bb6ef1 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java
@@ -35,10 +35,9 @@
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import com.android.systemui.res.R;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.res.R;
import org.junit.Before;
import org.junit.Rule;
@@ -50,7 +49,6 @@
import org.mockito.junit.MockitoRule;
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper()
public class KeyguardSecurityViewFlipperControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
index d0bb5a9..4290b8b 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
@@ -25,7 +25,6 @@
import com.android.internal.util.LatencyTracker
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.flags.FakeFeatureFlags
@@ -44,7 +43,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class KeyguardSimPinViewControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
index 59cd26c..31ee641 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
@@ -25,7 +25,6 @@
import com.android.internal.util.LatencyTracker
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.flags.FakeFeatureFlags
@@ -40,7 +39,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class KeyguardSimPukViewControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
index e4e2b0a..9a908d7 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java
@@ -29,9 +29,9 @@
import android.testing.TestableLooper;
import android.view.View;
-import com.android.systemui.res.R;
import com.android.systemui.plugins.ClockConfig;
import com.android.systemui.plugins.ClockController;
+import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
@@ -81,7 +81,7 @@
public void updatePosition_primaryClockAnimation() {
ClockController mockClock = mock(ClockController.class);
when(mKeyguardClockSwitchController.getClock()).thenReturn(mockClock);
- when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", false, true));
+ when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", "", "", false, true));
mController.updatePosition(10, 15, 20f, true);
@@ -96,7 +96,7 @@
public void updatePosition_alternateClockAnimation() {
ClockController mockClock = mock(ClockController.class);
when(mKeyguardClockSwitchController.getClock()).thenReturn(mockClock);
- when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", true, true));
+ when(mockClock.getConfig()).thenReturn(new ClockConfig("MOCK", "", "", true, true));
mController.updatePosition(10, 15, 20f, true);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
index 21a2822..d61ca69 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java
@@ -39,10 +39,10 @@
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
-import com.android.systemui.res.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.AuthRippleController;
+import com.android.systemui.bouncer.domain.interactor.BouncerInteractor;
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor;
import com.android.systemui.doze.util.BurnInHelperKt;
import com.android.systemui.dump.DumpManager;
@@ -51,6 +51,8 @@
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.res.R;
+import com.android.systemui.scene.SceneTestUtils;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -75,6 +77,8 @@
protected MockitoSession mStaticMockSession;
+ protected final SceneTestUtils mSceneTestUtils = new SceneTestUtils(this);
+ protected @Mock BouncerInteractor mBouncerInteractor;
protected @Mock LockIconView mLockIconView;
protected @Mock AnimatedStateListDrawable mIconDrawable;
protected @Mock Context mContext;
@@ -93,6 +97,7 @@
protected @Mock AuthRippleController mAuthRippleController;
protected FakeExecutor mDelayableExecutor = new FakeExecutor(new FakeSystemClock());
protected FakeFeatureFlags mFeatureFlags;
+
protected @Mock PrimaryBouncerInteractor mPrimaryBouncerInteractor;
protected LockIconViewController mUnderTest;
@@ -148,6 +153,7 @@
mFeatureFlags.set(MIGRATE_LOCK_ICON, false);
mFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
mFeatureFlags.set(LOCKSCREEN_ENABLE_LANDSCAPE, false);
+
mUnderTest = new LockIconViewController(
mStatusBarStateController,
mKeyguardUpdateMonitor,
@@ -168,7 +174,9 @@
KeyguardInteractorFactory.create(mFeatureFlags).getKeyguardInteractor(),
mFeatureFlags,
mPrimaryBouncerInteractor,
- mContext
+ mContext,
+ () -> mBouncerInteractor,
+ mSceneTestUtils.getSceneContainerFlags()
);
}
@@ -227,8 +235,8 @@
setupLockIconViewMocks();
}
- protected void init(boolean useMigrationFlag) {
- mFeatureFlags.set(DOZING_MIGRATION_1, useMigrationFlag);
+ protected void init(boolean useDozeMigrationFlag) {
+ mFeatureFlags.set(DOZING_MIGRATION_1, useDozeMigrationFlag);
mUnderTest.setLockIconView(mLockIconView);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
index 7b920939..4bacc3d 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java
@@ -26,6 +26,7 @@
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -404,6 +405,49 @@
// THEN uses perform haptic feedback
verify(mVibrator).performHapticFeedback(any(), eq(UdfpsController.LONG_PRESS));
+ }
+ @Test
+ public void longPress_showBouncer_sceneContainerNotEnabled() {
+ init(/* useMigrationFlag= */ false);
+ mSceneTestUtils.getSceneContainerFlags().setEnabled(false);
+ mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
+ when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(false);
+
+ // WHEN longPress
+ mUnderTest.onLongPress();
+
+ // THEN show primary bouncer via keyguard view controller, not scene container
+ verify(mKeyguardViewController).showPrimaryBouncer(anyBoolean());
+ verify(mBouncerInteractor, never()).showOrUnlockDevice(any());
+ }
+
+ @Test
+ public void longPress_showBouncer() {
+ init(/* useMigrationFlag= */ false);
+ mSceneTestUtils.getSceneContainerFlags().setEnabled(true);
+ mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
+ when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(false);
+
+ // WHEN longPress
+ mUnderTest.onLongPress();
+
+ // THEN show primary bouncer
+ verify(mKeyguardViewController, never()).showPrimaryBouncer(anyBoolean());
+ verify(mBouncerInteractor).showOrUnlockDevice(any());
+ }
+
+ @Test
+ public void longPress_falsingTriggered_doesNotShowBouncer() {
+ init(/* useMigrationFlag= */ false);
+ mSceneTestUtils.getSceneContainerFlags().setEnabled(true);
+ mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);
+ when(mFalsingManager.isFalseLongTap(anyInt())).thenReturn(true);
+
+ // WHEN longPress
+ mUnderTest.onLongPress();
+
+ // THEN don't show primary bouncer
+ verify(mBouncerInteractor, never()).showOrUnlockDevice(any());
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
index 59c7e76..8faf715 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt
@@ -166,6 +166,9 @@
waitForIdleSync()
verify(controller).onLaunchAnimationCancelled()
verify(controller, never()).onLaunchAnimationStart(anyBoolean())
+ verify(listener).onLaunchAnimationCancelled()
+ verify(listener, never()).onLaunchAnimationStart()
+ assertNull(runner.delegate)
}
@Test
@@ -176,6 +179,9 @@
waitForIdleSync()
verify(controller).onLaunchAnimationCancelled()
verify(controller, never()).onLaunchAnimationStart(anyBoolean())
+ verify(listener).onLaunchAnimationCancelled()
+ verify(listener, never()).onLaunchAnimationStart()
+ assertNull(runner.delegate)
}
@Test
@@ -194,6 +200,15 @@
}
}
+ @Test
+ fun disposeRunner_delegateDereferenced() {
+ val runner = activityLaunchAnimator.createRunner(controller)
+ assertNotNull(runner.delegate)
+ runner.dispose()
+ waitForIdleSync()
+ assertNull(runner.delegate)
+ }
+
private fun fakeWindow(): RemoteAnimationTarget {
val bounds = Rect(10 /* left */, 20 /* top */, 30 /* right */, 40 /* bottom */)
val taskInfo = ActivityManager.RunningTaskInfo()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
index 2bc0171..885abcb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthControllerTest.java
@@ -17,12 +17,15 @@
package com.android.systemui.biometrics;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
+
import static com.google.common.truth.Truth.assertThat;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotSame;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
@@ -79,7 +82,6 @@
import com.android.internal.R;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.widget.LockPatternUtils;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.domain.interactor.LogContextInteractor;
import com.android.systemui.biometrics.domain.interactor.PromptCredentialInteractor;
@@ -114,7 +116,6 @@
@RunWith(AndroidJUnit4.class)
@RunWithLooper
@SmallTest
-@RoboPilotTest
public class AuthControllerTest extends SysuiTestCase {
private static final long REQUEST_ID = 22;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java
index 8547fa3..714461b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricDisplayListenerTest.java
@@ -38,7 +38,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import kotlin.Unit;
@@ -53,7 +52,6 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4.class)
@RunWithLooper(setAsMainLooper = true)
public class BiometricDisplayListenerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt
index ab5d8bea5..39f0d57 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/FaceHelpMessageDeferralTest.kt
@@ -19,7 +19,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.keyguard.logging.BiometricMessageDeferralLogger
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import org.junit.Assert.assertEquals
@@ -34,7 +33,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class FaceHelpMessageDeferralTest : SysuiTestCase() {
val threshold = .75f
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
index 57cf834..ef06e0e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
@@ -53,7 +53,6 @@
import com.airbnb.lottie.LottieAnimationView
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestableContext
import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository
@@ -98,7 +97,6 @@
private const val REAR_DISPLAY_MODE_DEVICE_STATE = 3
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class SideFpsControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt
index 469f65a..e2aa984 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsBpViewControllerTest.kt
@@ -19,7 +19,6 @@
import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.dump.DumpManager
@@ -35,7 +34,6 @@
import org.mockito.junit.MockitoJUnit
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class UdfpsBpViewControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
index 21e614f..e9e9624 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
@@ -38,7 +38,6 @@
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
@@ -83,7 +82,6 @@
@ExperimentalCoroutinesApi
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@RunWithLooper(setAsMainLooper = true)
class UdfpsControllerOverlayTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index ee3bd0d..a36f4e9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -20,12 +20,15 @@
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_UP;
+
import static com.android.internal.util.FunctionalUtils.ThrowingConsumer;
import static com.android.systemui.classifier.Classifier.UDFPS_AUTHENTICATION;
import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyFloat;
@@ -74,8 +77,6 @@
import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.res.R;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams;
@@ -94,6 +95,7 @@
import com.android.systemui.log.SessionTracker;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.res.R;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -125,7 +127,6 @@
import javax.inject.Provider;
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4.class)
@RunWithLooper(setAsMainLooper = true)
public class UdfpsControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
index 280bfdf..cd9189b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDialogMeasureAdapterTest.java
@@ -27,7 +27,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import org.junit.Test;
@@ -38,7 +37,6 @@
@RunWith(AndroidJUnit4.class)
@SmallTest
-@RoboPilotTest
public class UdfpsDialogMeasureAdapterTest extends SysuiTestCase {
@Test
public void testUdfpsBottomSpacerHeightForPortrait() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java
index 1afb223..5239966 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsDisplayModeTest.java
@@ -30,7 +30,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.util.concurrency.FakeExecution;
@@ -41,7 +40,6 @@
import org.mockito.MockitoAnnotations;
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4.class)
@RunWithLooper(setAsMainLooper = true)
public class UdfpsDisplayModeTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java
index 8508f45..b018a3e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerTest.java
@@ -31,14 +31,12 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.statusbar.StatusBarState;
import org.junit.Test;
import org.junit.runner.RunWith;
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
index 17f435b..da4548b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewLegacyControllerWithCoroutinesTest.kt
@@ -21,7 +21,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardSecurityModel
-import com.android.systemui.RoboPilotTest
import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository
import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepositoryImpl
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
@@ -58,7 +57,6 @@
@RunWith(AndroidJUnit4::class)
@SmallTest
-@RoboPilotTest
@TestableLooper.RunWithLooper
@kotlinx.coroutines.ExperimentalCoroutinesApi
class UdfpsKeyguardViewLegacyControllerWithCoroutinesTest :
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt
index 6d55254..8b374ae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsShellTest.kt
@@ -21,7 +21,6 @@
import android.view.MotionEvent
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.UdfpsController.UdfpsOverlayController
import com.android.systemui.statusbar.commandline.CommandRegistry
@@ -40,7 +39,6 @@
import org.mockito.junit.MockitoJUnit
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class UdfpsShellTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
index ebadfc7..0c8e7a5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
@@ -26,7 +26,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
import com.android.systemui.util.mockito.any
@@ -50,7 +49,6 @@
private const val SENSOR_RADIUS = 10
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class UdfpsViewTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
index 0d17270..2d8adca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractorTest.kt
@@ -19,7 +19,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository
import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepositoryImpl
@@ -43,7 +42,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class AlternateBouncerInteractorTest : SysuiTestCase() {
private lateinit var underTest: AlternateBouncerInteractor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
index a81ca86..4aea4f3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerCallbackInteractorTest.kt
@@ -19,7 +19,6 @@
import android.view.View
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import org.junit.Before
import org.junit.Test
@@ -29,7 +28,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class PrimaryBouncerCallbackInteractorTest : SysuiTestCase() {
private val mPrimaryBouncerCallbackInteractor = PrimaryBouncerCallbackInteractor()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
index cb0b74f..2018e61 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/domain/interactor/PrimaryBouncerInteractorWithCoroutinesTest.kt
@@ -21,7 +21,6 @@
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardSecurityModel
import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.bouncer.ui.BouncerView
@@ -43,7 +42,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class PrimaryBouncerInteractorWithCoroutinesTest : SysuiTestCase() {
private lateinit var repository: FakeKeyguardBouncerRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt
index 333bd21..802f8e6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bouncer/ui/viewmodel/KeyguardBouncerViewModelTest.kt
@@ -21,7 +21,6 @@
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardSecurityModel
import com.android.keyguard.KeyguardUpdateMonitor
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor
@@ -50,7 +49,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@kotlinx.coroutines.ExperimentalCoroutinesApi
class KeyguardBouncerViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
index 7fa828f..3df9cbb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/communal/data/repository/CommunalWidgetRepositoryImplTest.kt
@@ -9,7 +9,6 @@
import android.os.UserManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.coroutines.collectLastValue
@@ -40,7 +39,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class CommunalWidgetRepositoryImplTest : SysuiTestCase() {
@Mock private lateinit var appWidgetManager: AppWidgetManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
index ddf788e..cdc42e0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/communal/domain/interactor/CommunalInteractorTest.kt
@@ -19,7 +19,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.data.repository.FakeCommunalRepository
import com.android.systemui.communal.data.repository.FakeCommunalWidgetRepository
@@ -37,7 +36,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidJUnit4::class)
class CommunalInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt b/packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt
index a10eb29..41a8be9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/communal/ui/view/layout/blueprints/DefaultCommunalBlueprintTest.kt
@@ -5,7 +5,6 @@
import androidx.constraintlayout.widget.ConstraintSet
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.ui.view.layout.sections.DefaultCommunalWidgetSection
import org.junit.Before
@@ -15,7 +14,6 @@
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
index 781ad6b..8a35ef1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayAnimationsControllerTest.kt
@@ -6,7 +6,6 @@
import android.view.View
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.complication.ComplicationHostViewController
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel
@@ -30,7 +29,6 @@
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4::class)
class DreamOverlayAnimationsControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt
index 21192fa..2c6c793 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayCallbackControllerTest.kt
@@ -17,7 +17,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -30,7 +29,6 @@
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4::class)
class DreamOverlayCallbackControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
index 7c36642..2af6566 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
@@ -38,7 +38,6 @@
import com.android.dream.lowlight.LowLightTransitionCoordinator;
import com.android.keyguard.BouncerPanelExpansionCalculator;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor;
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback;
@@ -53,7 +52,6 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4.class)
public class DreamOverlayContainerViewControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java
index be7638e..d379dc6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayNotificationCountProviderTest.java
@@ -26,7 +26,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
@@ -38,7 +37,6 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4.class)
public class DreamOverlayNotificationCountProviderTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
index 8379f73..e5f9972 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
@@ -49,7 +49,6 @@
import com.android.internal.logging.UiEventLogger;
import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.complication.ComplicationLayoutEngine;
import com.android.systemui.dreams.complication.HideComplicationTouchHandler;
@@ -72,7 +71,6 @@
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4.class)
public class DreamOverlayServiceTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
index 2ef227c..365f67b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStateControllerTest.java
@@ -29,7 +29,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.complication.Complication;
import com.android.systemui.flags.FeatureFlags;
@@ -48,7 +47,6 @@
import java.util.Collection;
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4.class)
public class DreamOverlayStateControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java
index 12cb332..7ff345c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarItemsProviderTest.java
@@ -24,7 +24,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import org.junit.Before;
@@ -36,7 +35,6 @@
import java.util.List;
import java.util.concurrent.Executor;
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4.class)
public class DreamOverlayStatusBarItemsProviderTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
index 9566e81..39db2be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayStatusBarViewControllerTest.java
@@ -46,11 +46,10 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.systemui.res.R;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.log.LogBuffer;
import com.android.systemui.log.core.FakeLogBuffer;
+import com.android.systemui.res.R;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController;
import com.android.systemui.statusbar.policy.NextAlarmController;
@@ -72,7 +71,6 @@
import java.util.Optional;
import java.util.concurrent.Executor;
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4.class)
public class DreamOverlayStatusBarViewControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java
index d32788d..315a24b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/HideComplicationTouchHandlerTest.java
@@ -30,7 +30,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.complication.Complication;
import com.android.systemui.dreams.DreamOverlayStateController;
@@ -49,7 +48,6 @@
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4.class)
public class HideComplicationTouchHandlerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java
index 4a7700f..e0c6ab2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java
@@ -26,7 +26,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.assist.AssistManager.VisualQueryAttentionListener;
@@ -41,7 +40,6 @@
import kotlinx.coroutines.CoroutineScope;
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4.class)
public class AssistantAttentionConditionTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
index cd2efde..480754c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
@@ -31,7 +31,6 @@
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.shared.condition.Condition;
@@ -44,7 +43,6 @@
import kotlinx.coroutines.CoroutineScope;
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4.class)
public class DreamConditionTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
index ffcaeee..3d1efa5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java
@@ -17,6 +17,7 @@
package com.android.systemui.dreams.touch;
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.eq;
@@ -40,7 +41,6 @@
import com.android.internal.logging.UiEventLogger;
import com.android.internal.widget.LockPatternUtils;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants;
import com.android.systemui.dreams.touch.scrim.ScrimController;
@@ -64,7 +64,6 @@
import java.util.Collections;
import java.util.Optional;
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4.class)
public class BouncerSwipeTouchHandlerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java
index ff6d97d..6aa821f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/ShadeTouchHandlerTest.java
@@ -27,7 +27,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.shared.system.InputChannelCompat;
@@ -43,7 +42,6 @@
import java.util.Optional;
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4.class)
public class ShadeTouchHandlerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java
index da39381..017fdbe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java
@@ -26,7 +26,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.shade.ShadeExpansionChangeEvent;
import com.android.systemui.util.concurrency.FakeExecutor;
@@ -38,7 +37,6 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4.class)
public class BouncerlessScrimControllerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java
index 81f6fe3..4ee4a60 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java
@@ -25,7 +25,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
-import com.android.systemui.RoboPilotTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.FakeExecutor;
@@ -38,7 +37,6 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4.class)
public class ScrimManagerTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 291dda20..a646823 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -16,7 +16,6 @@
package com.android.systemui.keyguard;
-import static android.os.PowerManager.WAKE_REASON_WAKE_MOTION;
import static android.provider.Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT;
import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY;
import static android.view.WindowManagerPolicyConstants.OFF_BECAUSE_OF_TIMEOUT;
@@ -635,29 +634,6 @@
}
@Test
- public void lockAfterSpecifiedAfterDreamStarted() {
- int currentUserId = 99;
- int userSpecificTimeout = 5999;
- KeyguardUpdateMonitor.setCurrentUser(currentUserId);
-
- // set mDeviceInteractive to true
- mViewMediator.onStartedWakingUp(WAKE_REASON_WAKE_MOTION, false);
- mFeatureFlags.set(Flags.LOCKSCREEN_WITHOUT_SECURE_LOCK_WHEN_DREAMING, false);
- when(mLockPatternUtils.isSecure(currentUserId)).thenReturn(true);
- when(mDevicePolicyManager.getMaximumTimeToLock(null, currentUserId)).thenReturn(0L);
- when(mSecureSettings.getIntForUser(LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
- KEYGUARD_LOCK_AFTER_DELAY_DEFAULT, currentUserId)).thenReturn(userSpecificTimeout);
- mSystemClock.setElapsedRealtime(0L);
- ArgumentCaptor<PendingIntent> pendingIntent = ArgumentCaptor.forClass(PendingIntent.class);
-
- mViewMediator.onDreamingStarted();
-
- verify(mAlarmManager).setExactAndAllowWhileIdle(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
- eq(Long.valueOf(userSpecificTimeout)), pendingIntent.capture());
- assertEquals(DELAYED_KEYGUARD_ACTION, pendingIntent.getValue().getIntent().getAction());
- }
-
- @Test
public void testHideSurfaceBehindKeyguardMarksKeyguardNotGoingAway() {
mViewMediator.hideSurfaceBehindKeyguard();
@@ -1023,7 +999,6 @@
mViewMediator.setShowingLocked(false);
when(mKeyguardStateController.isShowing()).thenReturn(false);
- mFeatureFlags.set(Flags.LOCKSCREEN_WITHOUT_SECURE_LOCK_WHEN_DREAMING, false);
mViewMediator.onDreamingStarted();
assertFalse(mViewMediator.isShowingAndNotOccluded());
}
@@ -1034,7 +1009,6 @@
mViewMediator.setShowingLocked(true);
when(mKeyguardStateController.isShowing()).thenReturn(true);
- mFeatureFlags.set(Flags.LOCKSCREEN_WITHOUT_SECURE_LOCK_WHEN_DREAMING, true);
mViewMediator.onDreamingStarted();
assertTrue(mViewMediator.isShowingAndNotOccluded());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt
index cfee3b8..e20d3af 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/CameraQuickAffordanceConfigTest.kt
@@ -23,7 +23,6 @@
import android.content.pm.PackageManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.camera.CameraGestureHelper
import com.android.systemui.settings.UserTracker
@@ -43,7 +42,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class CameraQuickAffordanceConfigTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
index 49168d0..faf9751 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/DoNotDisturbQuickAffordanceConfigTest.kt
@@ -26,7 +26,6 @@
import androidx.test.filters.SmallTest
import com.android.settingslib.notification.EnableZenModeDialog
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.ContentDescription
@@ -61,7 +60,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class DoNotDisturbQuickAffordanceConfigTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
index c85c7f6..548b564 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FakeKeyguardQuickAffordanceConfig.kt
@@ -17,7 +17,6 @@
package com.android.systemui.keyguard.data.quickaffordance
-import com.android.systemui.RoboPilotTest
import com.android.systemui.animation.Expandable
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult
import kotlinx.coroutines.flow.Flow
@@ -25,7 +24,6 @@
import kotlinx.coroutines.yield
/** Fake implementation of a quick affordance data source. */
-@RoboPilotTest
class FakeKeyguardQuickAffordanceConfig(
override val key: String,
private val pickerName: String = key,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
index c3e28ae..4ae144c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/FlashlightQuickAffordanceConfigTest.kt
@@ -21,7 +21,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.keyguard.shared.quickaffordance.ActivationState
import com.android.systemui.statusbar.policy.FlashlightController
@@ -42,7 +41,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class FlashlightQuickAffordanceConfigTest : LeakCheckedTest() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
index ef56a98..7d68cc0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/HomeControlsKeyguardQuickAffordanceConfigTest.kt
@@ -20,7 +20,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Expandable
import com.android.systemui.controls.controller.ControlsController
@@ -41,7 +40,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class HomeControlsKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
index 4f071bd..1e80fb6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLegacySettingSyncerTest.kt
@@ -23,7 +23,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
@@ -49,7 +48,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class KeyguardQuickAffordanceLegacySettingSyncerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
index bd0b71d..99a0185 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceLocalUserSelectionManagerTest.kt
@@ -23,7 +23,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.backup.BackupHelper
import com.android.systemui.settings.FakeUserTracker
@@ -53,7 +52,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class KeyguardQuickAffordanceLocalUserSelectionManagerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
index 0797d07..a1c9f87 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceRemoteUserSelectionManagerTest.kt
@@ -21,7 +21,6 @@
import android.os.UserHandle
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
@@ -44,7 +43,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class KeyguardQuickAffordanceRemoteUserSelectionManagerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
index d8c0341..b15352b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/MuteQuickAffordanceConfigTest.kt
@@ -21,7 +21,6 @@
import android.media.AudioManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker
@@ -46,7 +45,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class MuteQuickAffordanceConfigTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
index 9d983b8..521dea3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QrCodeScannerKeyguardQuickAffordanceConfigTest.kt
@@ -20,7 +20,6 @@
import android.content.Intent
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnTriggeredResult
import com.android.systemui.qrcodescanner.controller.QRCodeScannerController
@@ -40,7 +39,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class QrCodeScannerKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
index 613c4ce..02db0d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/QuickAccessWalletKeyguardQuickAffordanceConfigTest.kt
@@ -24,7 +24,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.animation.Expandable
@@ -51,7 +50,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class QuickAccessWalletKeyguardQuickAffordanceConfigTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
index 1414bac..a9b9c90 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/quickaffordance/VideoCameraQuickAffordanceConfigTest.kt
@@ -21,7 +21,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.ActivityIntentHelper
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.camera.CameraIntentsWrapper
import com.android.systemui.coroutines.collectLastValue
@@ -45,7 +44,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class VideoCameraQuickAffordanceConfigTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
index 944b059..d8cdf29 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/BiometricSettingsRepositoryTest.kt
@@ -32,7 +32,6 @@
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.AuthController
import com.android.systemui.biometrics.data.repository.FaceSensorInfo
@@ -79,7 +78,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@RunWith(AndroidJUnit4::class)
class BiometricSettingsRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
index 307204da..819d08a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFaceAuthRepositoryTest.kt
@@ -44,7 +44,6 @@
import com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.data.repository.FakeDisplayStateRepository
import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository
@@ -122,7 +121,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
private lateinit var underTest: DeviceEntryFaceAuthRepositoryImpl
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
index def016a..a58bc52 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DeviceEntryFingerprintAuthRepositoryTest.kt
@@ -22,7 +22,6 @@
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.AuthController
import com.android.systemui.coroutines.collectLastValue
@@ -49,7 +48,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class DeviceEntryFingerprintAuthRepositoryTest : SysuiTestCase() {
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
index 7eb8a26..9be5558 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/DevicePostureRepositoryTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.shared.model.DevicePosture
@@ -39,7 +38,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class DevicePostureRepositoryTest : SysuiTestCase() {
private lateinit var underTest: DevicePostureRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
index 126b841..567e0a9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceRepositoryTest.kt
@@ -22,7 +22,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceConfig
@@ -56,7 +55,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class KeyguardQuickAffordanceRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
index 7983e30..b9119e1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardRepositoryImplTest.kt
@@ -22,7 +22,6 @@
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitorCallback
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.biometrics.AuthController
import com.android.systemui.common.shared.model.Position
@@ -64,7 +63,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class KeyguardRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
index 4942cf8..799bd5a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/LightRevealScrimRepositoryTest.kt
@@ -20,7 +20,6 @@
import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.AnimatorTestRule
import com.android.systemui.coroutines.collectLastValue
@@ -46,7 +45,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidJUnit4::class)
class LightRevealScrimRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
index 7f784d8..ee47c58f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/TrustRepositoryTest.kt
@@ -21,7 +21,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.keyguard.logging.TrustRepositoryLogger
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.FlowValue
import com.android.systemui.coroutines.collectLastValue
@@ -46,7 +45,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class TrustRepositoryTest : SysuiTestCase() {
@Mock private lateinit var trustManager: TrustManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
index 181cc88..d6e19cb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt
@@ -19,7 +19,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
@@ -43,7 +42,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class KeyguardDismissActionInteractorTest : SysuiTestCase() {
private lateinit var keyguardRepository: FakeKeyguardRepository
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorTest.kt
index c407b14..a5cfbbf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissInteractorTest.kt
@@ -22,7 +22,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.keyguard.TrustGrantFlags
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.keyguard.shared.model.DismissAction
@@ -40,7 +39,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class KeyguardDismissInteractorTest : SysuiTestCase() {
private lateinit var dispatcher: TestDispatcher
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
index b527510..06eb0dd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardFaceAuthInteractorTest.kt
@@ -28,8 +28,10 @@
import com.android.keyguard.KeyguardSecurityModel
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.SysuiTestCase
+import com.android.systemui.biometrics.data.repository.FaceSensorInfo
import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository
import com.android.systemui.biometrics.shared.model.LockoutMode
+import com.android.systemui.biometrics.shared.model.SensorStrength
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor
@@ -156,7 +158,6 @@
fakeDeviceEntryFingerprintAuthRepository,
fakeUserRepository,
facePropertyRepository,
- fakeKeyguardRepository,
faceWakeUpTriggersConfig,
powerInteractor,
)
@@ -440,6 +441,43 @@
}
@Test
+ fun faceAuthIsRequestedWhenWalletIsLaunchedAndIfFaceAuthIsStrong() =
+ testScope.runTest {
+ underTest.start()
+ facePropertyRepository.setSensorInfo(FaceSensorInfo(1, SensorStrength.STRONG))
+
+ underTest.onWalletLaunched()
+
+ runCurrent()
+ assertThat(faceAuthRepository.runningAuthRequest.value)
+ .isEqualTo(Pair(FaceAuthUiEvent.FACE_AUTH_TRIGGERED_OCCLUDING_APP_REQUESTED, true))
+ }
+
+ @Test
+ fun faceAuthIsNotTriggeredIfFaceAuthIsWeak() =
+ testScope.runTest {
+ underTest.start()
+ facePropertyRepository.setSensorInfo(FaceSensorInfo(1, SensorStrength.WEAK))
+
+ underTest.onWalletLaunched()
+
+ runCurrent()
+ assertThat(faceAuthRepository.runningAuthRequest.value).isNull()
+ }
+
+ @Test
+ fun faceAuthIsNotTriggeredIfFaceAuthIsConvenience() =
+ testScope.runTest {
+ underTest.start()
+ facePropertyRepository.setSensorInfo(FaceSensorInfo(1, SensorStrength.CONVENIENCE))
+
+ underTest.onWalletLaunched()
+
+ runCurrent()
+ assertThat(faceAuthRepository.runningAuthRequest.value).isNull()
+ }
+
+ @Test
fun faceUnlockIsDisabledWhenFpIsLockedOut() =
testScope.runTest {
underTest.start()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
index ca52cdb..9ee22c8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractorTest.kt
@@ -20,7 +20,6 @@
import android.app.StatusBarManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
@@ -47,7 +46,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class KeyguardInteractorTest : SysuiTestCase() {
@@ -206,7 +204,8 @@
fromScene = SceneKey.Gone,
toScene = SceneKey.Lockscreen,
progress = flowOf(0f),
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
runCurrent()
assertThat(isAnimate).isFalse()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
index 13025a0..0c74a38 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardLongPressInteractorTest.kt
@@ -22,7 +22,6 @@
import androidx.test.filters.SmallTest
import com.android.internal.logging.UiEventLogger
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.FakeFeatureFlags
@@ -51,7 +50,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class KeyguardLongPressInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
index 8c13bb4..347d580 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractorTest.kt
@@ -23,7 +23,6 @@
import androidx.test.filters.SmallTest
import com.android.internal.widget.LockPatternUtils
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.common.shared.model.ContentDescription
@@ -73,7 +72,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
index fdcc66b..71fcf6f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardSurfaceBehindInteractorTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectValues
import com.android.systemui.keyguard.data.repository.FakeKeyguardSurfaceBehindRepository
@@ -41,7 +40,6 @@
import org.mockito.MockitoAnnotations.initMocks
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@kotlinx.coroutines.ExperimentalCoroutinesApi
class KeyguardSurfaceBehindInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
index fa93253..29b546b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractorTest.kt
@@ -19,7 +19,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectValues
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -42,7 +41,6 @@
import org.junit.runner.RunWith
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@kotlinx.coroutines.ExperimentalCoroutinesApi
class KeyguardTransitionInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt
index 906d948..c02add1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractorTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.FakeLightRevealScrimRepository
@@ -45,7 +44,6 @@
import org.mockito.Spy
@SmallTest
-@RoboPilotTest
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidJUnit4::class)
class LightRevealScrimInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
index 73ecae5..16f2fa2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/WindowManagerLockscreenVisibilityInteractorTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectValues
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
@@ -38,7 +37,6 @@
import org.mockito.MockitoAnnotations.initMocks
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@kotlinx.coroutines.ExperimentalCoroutinesApi
class WindowManagerLockscreenVisibilityInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt
index a22f603..5b29a86 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/KeyguardSurfaceBehindParamsApplierTest.kt
@@ -20,7 +20,6 @@
import android.view.RemoteAnimationTarget
import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardViewController
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.AnimatorTestRule
import com.android.systemui.keyguard.domain.interactor.KeyguardSurfaceBehindInteractor
@@ -41,7 +40,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWithLooper(setAsMainLooper = true)
@kotlinx.coroutines.ExperimentalCoroutinesApi
class KeyguardSurfaceBehindParamsApplierTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt
index 7a17435..9b2db3e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/binder/WindowManagerLockscreenVisibilityManagerTest.kt
@@ -19,7 +19,6 @@
import android.app.IActivityTaskManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.WindowManagerLockscreenVisibilityManager
import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -35,7 +34,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@kotlinx.coroutines.ExperimentalCoroutinesApi
class WindowManagerLockscreenVisibilityManagerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt
new file mode 100644
index 0000000..1768f8c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerViewModelTest.kt
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2023 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.keyguard.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.coroutines.collectValues
+import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
+import com.android.systemui.keyguard.shared.model.KeyguardState
+import com.android.systemui.keyguard.shared.model.TransitionState
+import com.android.systemui.keyguard.shared.model.TransitionStep
+import com.android.systemui.plugins.FalsingManager
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
+import com.google.common.collect.Range
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@ExperimentalCoroutinesApi
+@RunWith(JUnit4::class)
+@SmallTest
+class AlternateBouncerViewModelTest : SysuiTestCase() {
+
+ private lateinit var testScope: TestScope
+
+ @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
+ @Mock private lateinit var falsingManager: FalsingManager
+
+ private lateinit var transitionRepository: FakeKeyguardTransitionRepository
+ private lateinit var transitionInteractor: KeyguardTransitionInteractor
+ private lateinit var underTest: AlternateBouncerViewModel
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ testScope = TestScope()
+
+ val transitionInteractorWithDependencies =
+ KeyguardTransitionInteractorFactory.create(testScope.backgroundScope)
+ transitionInteractor = transitionInteractorWithDependencies.keyguardTransitionInteractor
+ transitionRepository = transitionInteractorWithDependencies.repository
+ underTest =
+ AlternateBouncerViewModel(
+ statusBarKeyguardViewManager,
+ transitionInteractor,
+ falsingManager,
+ )
+ }
+
+ @Test
+ fun transitionToAlternateBouncer_scrimAlphaUpdate() =
+ runTest(UnconfinedTestDispatcher()) {
+ val scrimAlphas by collectValues(underTest.scrimAlpha)
+
+ transitionRepository.sendTransitionStep(
+ stepToAlternateBouncer(0f, TransitionState.STARTED)
+ )
+ transitionRepository.sendTransitionStep(stepToAlternateBouncer(.4f))
+ transitionRepository.sendTransitionStep(stepToAlternateBouncer(.6f))
+ transitionRepository.sendTransitionStep(stepToAlternateBouncer(1f))
+
+ assertThat(scrimAlphas.size).isEqualTo(4)
+ scrimAlphas.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
+ }
+
+ @Test
+ fun transitionFromAlternateBouncer_scrimAlphaUpdate() =
+ runTest(UnconfinedTestDispatcher()) {
+ val scrimAlphas by collectValues(underTest.scrimAlpha)
+
+ transitionRepository.sendTransitionStep(
+ stepFromAlternateBouncer(0f, TransitionState.STARTED)
+ )
+ transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.4f))
+ transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.6f))
+ transitionRepository.sendTransitionStep(stepFromAlternateBouncer(1f))
+
+ assertThat(scrimAlphas.size).isEqualTo(4)
+ scrimAlphas.forEach { assertThat(it).isIn(Range.closed(0f, 1f)) }
+ }
+
+ @Test
+ fun clickListenerUpdate() =
+ runTest(UnconfinedTestDispatcher()) {
+ val clickListener by collectLastValue(underTest.onClickListener)
+
+ // keyguard state => ALTERNATE_BOUNCER
+ transitionRepository.sendTransitionStep(
+ stepToAlternateBouncer(0f, TransitionState.STARTED)
+ )
+ assertThat(clickListener).isNull()
+ transitionRepository.sendTransitionStep(stepToAlternateBouncer(.3f))
+ assertThat(clickListener).isNull()
+ transitionRepository.sendTransitionStep(stepToAlternateBouncer(.6f))
+ assertThat(clickListener).isNull()
+ transitionRepository.sendTransitionStep(stepToAlternateBouncer(1f))
+ assertThat(clickListener).isNotNull()
+
+ // ALTERNATE_BOUNCER -> keyguard state
+ transitionRepository.sendTransitionStep(
+ stepFromAlternateBouncer(0f, TransitionState.STARTED)
+ )
+ assertThat(clickListener).isNotNull()
+ transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.3f))
+ assertThat(clickListener).isNull()
+ transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.6f))
+ assertThat(clickListener).isNull()
+ transitionRepository.sendTransitionStep(stepFromAlternateBouncer(1f))
+ assertThat(clickListener).isNull()
+ }
+
+ @Test
+ fun forcePluginOpen() =
+ runTest(UnconfinedTestDispatcher()) {
+ val forcePluginOpen by collectLastValue(underTest.forcePluginOpen)
+ transitionRepository.sendTransitionStep(
+ stepToAlternateBouncer(0f, TransitionState.STARTED)
+ )
+ transitionRepository.sendTransitionStep(stepToAlternateBouncer(.3f))
+ transitionRepository.sendTransitionStep(stepToAlternateBouncer(.6f))
+ transitionRepository.sendTransitionStep(stepToAlternateBouncer(1f))
+ assertThat(forcePluginOpen).isTrue()
+
+ transitionRepository.sendTransitionStep(
+ stepFromAlternateBouncer(0f, TransitionState.STARTED)
+ )
+ transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.3f))
+ transitionRepository.sendTransitionStep(stepFromAlternateBouncer(.6f))
+ transitionRepository.sendTransitionStep(stepFromAlternateBouncer(1f))
+ assertThat(forcePluginOpen).isFalse()
+ }
+
+ private fun stepToAlternateBouncer(
+ value: Float,
+ state: TransitionState = TransitionState.RUNNING
+ ): TransitionStep {
+ return step(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.ALTERNATE_BOUNCER,
+ value = value,
+ transitionState = state,
+ )
+ }
+
+ private fun stepFromAlternateBouncer(
+ value: Float,
+ state: TransitionState = TransitionState.RUNNING
+ ): TransitionStep {
+ return step(
+ from = KeyguardState.ALTERNATE_BOUNCER,
+ to = KeyguardState.LOCKSCREEN,
+ value = value,
+ transitionState = state,
+ )
+ }
+
+ private fun step(
+ from: KeyguardState,
+ to: KeyguardState,
+ value: Float,
+ transitionState: TransitionState
+ ): TransitionStep {
+ return TransitionStep(
+ from = from,
+ to = to,
+ value = value,
+ transitionState = transitionState,
+ ownerName = "AlternateBouncerViewModelTest"
+ )
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
index bfc6f31..6d47aed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
@@ -46,7 +45,6 @@
import org.junit.runner.RunWith
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() {
private lateinit var underTest: DreamingToLockscreenTransitionViewModel
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
index 75c8bff..cf20129 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToDreamingTransitionViewModelTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
@@ -37,7 +36,6 @@
import org.junit.runner.RunWith
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class GoneToDreamingTransitionViewModelTest : SysuiTestCase() {
private lateinit var underTest: GoneToDreamingTransitionViewModel
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
index 12fe07f..89a1d2b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToDreamingTransitionViewModelTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
@@ -37,7 +36,6 @@
import org.junit.runner.RunWith
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class LockscreenToDreamingTransitionViewModelTest : SysuiTestCase() {
private lateinit var underTest: LockscreenToDreamingTransitionViewModel
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
index 83ae631..41f8856 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToOccludedTransitionViewModelTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
@@ -37,7 +36,6 @@
import org.junit.runner.RunWith
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class LockscreenToOccludedTransitionViewModelTest : SysuiTestCase() {
private lateinit var underTest: LockscreenToOccludedTransitionViewModel
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
index 8860399..ec95cb8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/OccludedToLockscreenTransitionViewModelTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory
@@ -37,7 +36,6 @@
import org.junit.runner.RunWith
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class OccludedToLockscreenTransitionViewModelTest : SysuiTestCase() {
private lateinit var underTest: OccludedToLockscreenTransitionViewModel
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
index da372ea..9364097 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.coroutines.collectValues
@@ -46,7 +45,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class PrimaryBouncerToGoneTransitionViewModelTest : SysuiTestCase() {
private lateinit var underTest: PrimaryBouncerToGoneTransitionViewModel
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt
index 9ab9b3d..32acefe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/UdfpsAodViewModelTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.KeyguardBouncerRepository
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
@@ -46,7 +45,6 @@
@ExperimentalCoroutinesApi
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class UdfpsAodViewModelTest : SysuiTestCase() {
private val defaultPadding = 12
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSImplTest.java
index d57765c..c8c134a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSImplTest.java
@@ -16,6 +16,8 @@
package com.android.systemui.qs;
+import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
+
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import static com.android.systemui.statusbar.StatusBarState.SHADE;
@@ -41,6 +43,7 @@
import android.os.Bundle;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
+import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -49,7 +52,6 @@
import androidx.test.filters.SmallTest;
import com.android.keyguard.BouncerPanelExpansionCalculator;
-import com.android.systemui.res.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlagsClassic;
@@ -60,6 +62,7 @@
import com.android.systemui.qs.footer.ui.binder.FooterActionsViewBinder;
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel;
import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.res.R;
import com.android.systemui.settings.FakeDisplayTracker;
import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
import com.android.systemui.statusbar.CommandQueue;
@@ -110,6 +113,9 @@
@Mock private FeatureFlagsClassic mFeatureFlags;
private View mQsView;
+ private final CommandQueue mCommandQueue =
+ new CommandQueue(mContext, new FakeDisplayTracker(mContext));
+
private QSImpl mUnderTest;
@@ -120,6 +126,16 @@
mUnderTest.onComponentCreated(mQsComponent, null);
}
+ /*
+ * Regression test for b/303180152.
+ */
+ @Test
+ public void testDisableCallbackOnDisabledQuickSettingsUponCreationDoesntCrash() {
+ QSImpl other = instantiate();
+ mCommandQueue.disable(Display.DEFAULT_DISPLAY, 0, DISABLE2_QUICK_SETTINGS);
+
+ other.onComponentCreated(mQsComponent, null);
+ }
@Test
public void testSaveState() {
@@ -473,7 +489,6 @@
private QSImpl instantiate() {
MockitoAnnotations.initMocks(this);
- CommandQueue commandQueue = new CommandQueue(mContext, new FakeDisplayTracker(mContext));
setupQsComponent();
setUpViews();
@@ -484,11 +499,11 @@
return new QSImpl(
new RemoteInputQuickSettingsDisabler(
mContext,
- commandQueue,
+ mCommandQueue,
new ResourcesSplitShadeStateController(),
mock(ConfigurationController.class)),
mStatusBarStateController,
- commandQueue,
+ mCommandQueue,
mQSMediaHost,
mQQSMediaHost,
mBypassController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
index e2ac7bc..b825c08 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerBaseTest.java
@@ -23,6 +23,7 @@
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -42,7 +43,6 @@
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.logging.testing.UiEventLoggerFake;
-import com.android.systemui.res.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.media.controls.ui.MediaHost;
@@ -50,6 +50,7 @@
import com.android.systemui.qs.customize.QSCustomizerController;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
+import com.android.systemui.res.R;
import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController;
import com.android.systemui.util.animation.DisappearParameters;
@@ -341,11 +342,92 @@
}
@Test
- public void onViewDetached_removesJustTheAssociatedCallback() {
+ public void onDestroy_removesJustTheAssociatedCallback() {
+ QSPanelControllerBase.TileRecord record = mController.mRecords.get(0);
+
+ mController.destroy();
+ verify(mQSTile).removeCallback(record.callback);
+ verify(mQSTile, never()).removeCallbacks();
+
+ assertThat(mController.mRecords).isEmpty();
+ }
+
+ @Test
+ public void onViewDettached_callbackNotRemoved() {
QSPanelControllerBase.TileRecord record = mController.mRecords.get(0);
mController.onViewDetached();
- verify(mQSTile).removeCallback(record.callback);
+ verify(mQSTile, never()).removeCallback(record.callback);
verify(mQSTile, never()).removeCallbacks();
}
+
+ @Test
+ public void onInit_qsHostCallbackAdded() {
+ verify(mQSHost).addCallback(any());
+ }
+
+ @Test
+ public void onViewDettached_qsHostCallbackNotRemoved() {
+ mController.onViewDetached();
+ verify(mQSHost, never()).removeCallback(any());
+ }
+
+ @Test
+ public void onDestroy_qsHostCallbackRemoved() {
+ mController.destroy();
+ verify(mQSHost).removeCallback(any());
+ }
+
+ @Test
+ public void setTiles_sameTiles_doesntRemoveAndReaddViews() {
+ when(mQSHost.getTiles()).thenReturn(List.of(mQSTile, mOtherTile));
+ mController.setTiles();
+
+ clearInvocations(mQSPanel);
+
+ mController.setTiles();
+ verify(mQSPanel, never()).removeTile(any());
+ verify(mQSPanel, never()).addTile(any());
+ }
+
+ @Test
+ public void setTiles_differentTiles_allTilesRemovedAndNewTilesAdded() {
+ when(mQSHost.getTiles()).thenReturn(List.of(mQSTile, mOtherTile));
+ mController.setTiles();
+
+ clearInvocations(mQSPanel);
+
+ when(mQSHost.getTiles()).thenReturn(List.of(mQSTile));
+ mController.setTiles();
+
+ verify(mQSPanel, times(2)).removeTile(any());
+ verify(mQSPanel).addTile(any());
+ }
+
+ @Test
+ public void detachAndReattach_sameTiles_doesntRemoveAndReAddViews() {
+ when(mQSHost.getTiles()).thenReturn(List.of(mQSTile, mOtherTile));
+ mController.setTiles();
+
+ clearInvocations(mQSPanel);
+
+ mController.onViewDetached();
+ mController.onViewAttached();
+ verify(mQSPanel, never()).removeTile(any());
+ verify(mQSPanel, never()).addTile(any());
+ }
+
+ @Test
+ public void setTiles_sameTilesDifferentOrder_removesAndReadds() {
+ when(mQSHost.getTiles()).thenReturn(List.of(mQSTile, mOtherTile));
+ mController.setTiles();
+
+ clearInvocations(mQSPanel);
+
+ when(mQSHost.getTiles()).thenReturn(List.of(mOtherTile, mQSTile));
+ mController.setTiles();
+
+ verify(mQSPanel, times(2)).removeTile(any());
+ verify(mQSPanel, times(2)).addTile(any());
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt
index 9a55f72..d277fca 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/AutoAddSettingsRepositoryTest.kt
@@ -19,7 +19,6 @@
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.qs.pipeline.shared.TileSpec
@@ -39,7 +38,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class AutoAddSettingsRepositoryTest : SysuiTestCase() {
private val secureSettings = FakeSettings()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt
index 30f5811..3db676d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/CustomTileAddedSharedPreferencesRepositoryTest.kt
@@ -20,7 +20,6 @@
import android.content.SharedPreferences
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.settings.UserFileManager
import com.android.systemui.util.FakeSharedPreferences
@@ -30,7 +29,6 @@
import org.junit.runner.RunWith
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class CustomTileAddedSharedPreferencesRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt
index 995de66..070e07a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/InstalledTilesComponentRepositoryImplTest.kt
@@ -32,7 +32,6 @@
import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.util.mockito.any
@@ -62,7 +61,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
@OptIn(ExperimentalCoroutinesApi::class)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt
index dc09a33..ff8a9bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/QSSettingsRestoredBroadcastRepositoryTest.kt
@@ -4,7 +4,6 @@
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.broadcast.FakeBroadcastDispatcher
import com.android.systemui.coroutines.collectLastValue
@@ -24,7 +23,6 @@
@SmallTest
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidJUnit4::class)
-@RoboPilotTest
class QSSettingsRestoredBroadcastRepositoryTest : SysuiTestCase() {
private val dispatcher = StandardTestDispatcher()
private val testScope = TestScope(dispatcher)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt
index 08adebb..f7c3b21 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TileSpecSettingsRepositoryTest.kt
@@ -20,7 +20,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.qs.pipeline.shared.TileSpec
@@ -40,7 +39,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@OptIn(ExperimentalCoroutinesApi::class)
class TileSpecSettingsRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt
index 2087623..9516c21 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/TilesSettingConverterTest.kt
@@ -2,14 +2,12 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4::class)
class TilesSettingConverterTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt
index 81fd72b..36e860e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserAutoAddRepositoryTest.kt
@@ -3,7 +3,6 @@
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.qs.pipeline.data.model.RestoreData
@@ -24,7 +23,6 @@
import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
-@RoboPilotTest
@SmallTest
@RunWith(AndroidJUnit4::class)
class UserAutoAddRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt
index 389580c1..d4a9fab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/data/repository/UserTileSpecRepositoryTest.kt
@@ -3,7 +3,6 @@
import android.provider.Settings
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.qs.pipeline.data.model.RestoreData
@@ -23,7 +22,6 @@
import org.mockito.Mock
import org.mockito.MockitoAnnotations
-@RoboPilotTest
@SmallTest
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidJUnit4::class)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt
index 15e401d..4454a3c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingListTest.kt
@@ -20,7 +20,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.qs.pipeline.shared.TileSpec
import com.android.systemui.util.mockito.mock
@@ -29,7 +28,6 @@
import org.junit.runner.RunWith
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class AutoAddableSettingListTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt
index 7c6dd24..d153e9d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/AutoAddableSettingTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
@@ -36,7 +35,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class AutoAddableSettingTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt
index 469eee3..ec139e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CallbackControllerAutoAddableTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal
@@ -36,7 +35,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class CallbackControllerAutoAddableTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt
index b6eaa39..4fae532 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/CastAutoAddableTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal
@@ -42,7 +41,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class CastAutoAddableTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt
index a755fbb..9e2d1f8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DataSaverAutoAddableTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal
@@ -41,7 +40,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class DataSaverAutoAddableTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt
index daacca51..0116bd9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/DeviceControlsAutoAddableTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal
@@ -44,7 +43,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class DeviceControlsAutoAddableTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt
index 4b5f7f6..e7ea9a6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/HotspotAutoAddableTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal
@@ -41,7 +40,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class HotspotAutoAddableTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt
index 32d9db2..20fd360 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/NightDisplayAutoAddableTest.kt
@@ -19,7 +19,6 @@
import android.hardware.display.NightDisplayListener
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.dagger.NightDisplayListenerModule
@@ -50,7 +49,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class NightDisplayAutoAddableTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt
index fb513a6..19ac63c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/ReduceBrightColorsAutoAddableTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.qs.ReduceBrightColorsController
@@ -44,7 +43,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class ReduceBrightColorsAutoAddableTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt
index 5ce15fa..d645ee3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/SafetyCenterAutoAddableTest.kt
@@ -21,7 +21,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.coroutines.collectValues
@@ -52,7 +51,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class SafetyCenterAutoAddableTest : SysuiTestCase() {
private val testDispatcher = StandardTestDispatcher()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt
index 1c8cb54..83ff35d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WalletAutoAddableTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal
@@ -38,7 +37,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class WalletAutoAddableTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt
index de1d29fd..adccc84 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt
@@ -23,7 +23,6 @@
import android.content.pm.UserInfo.FLAG_PROFILE
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal
@@ -41,7 +40,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class WorkTileAutoAddableTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt
index bb18115..41a7ec0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/AutoAddInteractorTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.dump.DumpManager
@@ -47,7 +46,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@OptIn(ExperimentalCoroutinesApi::class)
class AutoAddInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
index a750524..a89338a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
@@ -24,7 +24,6 @@
import android.service.quicksettings.Tile
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.dump.nano.SystemUIProtoDump
@@ -71,7 +70,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@OptIn(ExperimentalCoroutinesApi::class)
class CurrentTilesInteractorImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt
index 151b256..0d97115 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt
@@ -17,7 +17,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.shade.ShadeController
import org.junit.Before
@@ -27,7 +26,6 @@
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@SmallTest
class PanelInteractorImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt
index 2e6b50b..f73cab8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/RestoreReconciliationInteractorTest.kt
@@ -2,7 +2,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.qs.pipeline.data.model.RestoreData
@@ -20,7 +19,6 @@
import org.junit.runner.RunWith
import org.mockito.MockitoAnnotations
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@SmallTest
class RestoreReconciliationInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
index 34c4c98..558e769 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/shared/TileSpecTest.kt
@@ -19,14 +19,12 @@
import android.content.ComponentName
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class TileSpecTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserActionHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserActionHandlerTest.kt
index 06b7a9f..5659f01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserActionHandlerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserActionHandlerTest.kt
@@ -19,7 +19,6 @@
import android.content.Intent
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.plugins.ActivityStarter
import org.junit.Before
@@ -32,7 +31,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class QSTileIntentUserActionHandlerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt
index 2c4e10e..9861606 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt
@@ -20,7 +20,6 @@
import androidx.test.filters.SmallTest
import com.android.internal.logging.InstanceId
import com.android.internal.logging.UiEventLogger
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.qs.QSEvent
import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder
@@ -34,7 +33,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class QSTileAnalyticsTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt
index 4f25d12..a6199c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt
@@ -24,7 +24,6 @@
import androidx.test.filters.SmallTest
import com.android.settingslib.RestrictedLockUtils
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.util.mockito.any
@@ -46,7 +45,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class DisabledByPolicyInteractorTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
index 4401e0d..f1fcee3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
@@ -39,7 +38,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class QSTileLoggerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelInterfaceComplianceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelInterfaceComplianceTest.kt
index 4760dfa..2084aeb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelInterfaceComplianceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelInterfaceComplianceTest.kt
@@ -20,7 +20,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.android.internal.logging.InstanceId
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingManagerFake
import com.android.systemui.common.shared.model.ContentDescription
@@ -49,7 +48,6 @@
// TODO(b/299909368): Add more tests
@MediumTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
class QSTileViewModelInterfaceComplianceTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
index 61dd69a..2e16577 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/SceneFrameworkIntegrationTest.kt
@@ -52,6 +52,7 @@
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
@@ -462,7 +463,8 @@
fromScene = getCurrentSceneInUi(),
toScene = to.key,
progress = progressFlow,
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
runCurrent()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
index 432bd0f..740c6d9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/data/repository/SceneContainerRepositoryTest.kt
@@ -29,6 +29,7 @@
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
import org.junit.Test
import org.junit.runner.RunWith
@@ -119,7 +120,8 @@
fromScene = SceneKey.Lockscreen,
toScene = SceneKey.Shade,
progress = progress,
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
assertThat(reflectedTransitionState).isEqualTo(transitionState.value)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
index 8b23d18..31d26c0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/interactor/SceneInteractorTest.kt
@@ -83,7 +83,8 @@
fromScene = SceneKey.Lockscreen,
toScene = SceneKey.Shade,
progress = progress,
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
assertThat(reflectedTransitionState).isEqualTo(transitionState.value)
@@ -121,7 +122,8 @@
fromScene = underTest.desiredScene.value.key,
toScene = SceneKey.Shade,
progress = progress,
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
assertThat(transitionTo).isEqualTo(SceneKey.Shade)
@@ -158,7 +160,8 @@
fromScene = SceneKey.Gone,
toScene = SceneKey.Lockscreen,
progress = flowOf(0.5f),
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
)
val transitioning by
@@ -177,7 +180,8 @@
fromScene = SceneKey.Shade,
toScene = SceneKey.QuickSettings,
progress = flowOf(0.5f),
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
)
underTest.setTransitionState(transitionState)
@@ -194,7 +198,8 @@
fromScene = SceneKey.Shade,
toScene = SceneKey.Lockscreen,
progress = flowOf(0.5f),
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
)
val transitioning by
@@ -222,7 +227,8 @@
fromScene = SceneKey.Shade,
toScene = SceneKey.Lockscreen,
progress = flowOf(0.5f),
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
assertThat(transitioning).isTrue()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
index 7b13de6..3b9621e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/scene/domain/startable/SceneContainerStartableTest.kt
@@ -109,7 +109,8 @@
fromScene = SceneKey.Gone,
toScene = SceneKey.Shade,
progress = flowOf(0.5f),
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
assertThat(isVisible).isTrue()
sceneInteractor.onSceneChanged(SceneModel(SceneKey.Shade), "reason")
@@ -122,7 +123,8 @@
fromScene = SceneKey.Shade,
toScene = SceneKey.Gone,
progress = flowOf(0.5f),
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
assertThat(isVisible).isTrue()
sceneInteractor.onSceneChanged(SceneModel(SceneKey.Gone), "reason")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplReceiveTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplReceiveTest.kt
index 1bb2ff8..263b001 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplReceiveTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplReceiveTest.kt
@@ -42,6 +42,7 @@
@Parameterized.Parameters
fun data(): Iterable<String> =
listOf(
+ Intent.ACTION_LOCALE_CHANGED,
Intent.ACTION_USER_INFO_CHANGED,
Intent.ACTION_MANAGED_PROFILE_AVAILABLE,
Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
index 52b25f8..c32d259 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
@@ -177,7 +177,8 @@
verify(context)
.registerReceiverForAllUsers(eq(tracker), capture(captor), isNull(), eq(handler))
with(captor.value) {
- assertThat(countActions()).isEqualTo(6)
+ assertThat(countActions()).isEqualTo(7)
+ assertThat(hasAction(Intent.ACTION_LOCALE_CHANGED)).isTrue()
assertThat(hasAction(Intent.ACTION_USER_INFO_CHANGED)).isTrue()
assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)).isTrue()
assertThat(hasAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)).isTrue()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
index dd77da3..8d8c70e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java
@@ -79,7 +79,6 @@
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
import com.android.keyguard.logging.KeyguardLogger;
-import com.android.systemui.res.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
@@ -120,6 +119,7 @@
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.power.domain.interactor.PowerInteractor;
import com.android.systemui.qs.QSFragmentLegacy;
+import com.android.systemui.res.R;
import com.android.systemui.screenrecord.RecordingController;
import com.android.systemui.shade.data.repository.FakeShadeRepository;
import com.android.systemui.shade.data.repository.ShadeRepository;
@@ -153,7 +153,6 @@
import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
import com.android.systemui.statusbar.phone.KeyguardBottomAreaViewController;
@@ -170,6 +169,7 @@
import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardQsUserSwitchController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.KeyguardUserSwitcherController;
@@ -182,6 +182,8 @@
import com.android.systemui.util.time.SystemClock;
import com.android.wm.shell.animation.FlingAnimationUtils;
+import dagger.Lazy;
+
import org.junit.After;
import org.junit.Before;
import org.mockito.ArgumentCaptor;
@@ -193,7 +195,6 @@
import java.util.List;
import java.util.Optional;
-import dagger.Lazy;
import kotlinx.coroutines.CoroutineDispatcher;
public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
@@ -208,7 +209,7 @@
@Mock protected KeyguardBottomAreaViewController mKeyguardBottomAreaViewController;
@Mock protected ViewPropertyAnimator mViewPropertyAnimator;
@Mock protected KeyguardBottomAreaView mQsFrame;
- @Mock protected HeadsUpManagerPhone mHeadsUpManager;
+ @Mock protected HeadsUpManager mHeadsUpManager;
@Mock protected NotificationShelfController mNotificationShelfController;
@Mock protected NotificationGutsManager mGutsManager;
@Mock protected KeyguardStatusBarView mKeyguardStatusBar;
@@ -527,7 +528,7 @@
NotificationWakeUpCoordinator coordinator =
new NotificationWakeUpCoordinator(
mDumpManager,
- mock(HeadsUpManagerPhone.class),
+ mock(HeadsUpManager.class),
new StatusBarStateControllerImpl(new UiEventLoggerFake(), mDumpManager,
mInteractionJankMonitor, mShadeExpansionStateManager),
mKeyguardBypassController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
index 9651072..b4f9e8d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -34,6 +34,7 @@
import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository
import com.android.systemui.bouncer.data.repository.BouncerMessageRepositoryImpl
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
+import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor
import com.android.systemui.bouncer.domain.interactor.CountDownTimerUtil
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor
@@ -83,7 +84,6 @@
import com.android.systemui.util.mockito.any
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
-import java.util.Optional
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.test.TestScope
@@ -97,8 +97,9 @@
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
+import java.util.Optional
+import org.mockito.Mockito.`when` as whenever
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@@ -144,6 +145,8 @@
@Mock
lateinit var primaryBouncerToGoneTransitionViewModel: PrimaryBouncerToGoneTransitionViewModel
@Mock lateinit var keyEventInteractor: KeyEventInteractor
+ @Mock lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
+ @Mock lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
private val notificationExpansionRepository = NotificationExpansionRepository()
private lateinit var fakeClock: FakeSystemClock
@@ -176,6 +179,7 @@
featureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true)
featureFlags.set(Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false)
featureFlags.set(Flags.MIGRATE_NSSL, false)
+ featureFlags.set(Flags.ALTERNATE_BOUNCER_VIEW, false)
testScope = TestScope()
fakeClock = FakeSystemClock()
@@ -248,6 +252,8 @@
),
BouncerLogger(logcatLogBuffer("BouncerLog")),
keyEventInteractor,
+ primaryBouncerInteractor,
+ alternateBouncerInteractor,
)
underTest.setupExpandedStatusBar()
underTest.setDragDownHelper(dragDownHelper)
@@ -425,29 +431,37 @@
}
@Test
- fun shouldInterceptTouchEvent_notificationPanelViewControllerShouldIntercept() {
- // GIVEN not dozing
- whenever(sysuiStatusBarStateController.isDozing()).thenReturn(false)
+ fun shouldInterceptTouchEvent_dozing_touchInLockIconArea_touchNotIntercepted() {
+ // GIVEN dozing
+ whenever(sysuiStatusBarStateController.isDozing).thenReturn(true)
// AND alternate bouncer doesn't want the touch
whenever(statusBarKeyguardViewManager.shouldInterceptTouchEvent(DOWN_EVENT))
.thenReturn(false)
- // AND the lock icon doesn't want the touch
- whenever(lockIconViewController.onInterceptTouchEvent(DOWN_EVENT)).thenReturn(false)
- // AND the notification panel can accept touches
- whenever(notificationPanelViewController.isFullyExpanded()).thenReturn(true)
- whenever(dragDownHelper.isDragDownEnabled).thenReturn(true)
- whenever(centralSurfaces.isBouncerShowing()).thenReturn(false)
-
- // AND the drag down helper doesn't want the touch (to pull the shade down)
- whenever(dragDownHelper.onInterceptTouchEvent(DOWN_EVENT)).thenReturn(false)
+ // AND the lock icon wants the touch
+ whenever(lockIconViewController.willHandleTouchWhileDozing(DOWN_EVENT))
+ .thenReturn(true)
featureFlags.set(Flags.MIGRATE_NSSL, true)
- // WHEN asked if should intercept touch
- interactionEventHandler.shouldInterceptTouchEvent(DOWN_EVENT)
+ // THEN touch should NOT be intercepted by NotificationShade
+ assertThat(interactionEventHandler.shouldInterceptTouchEvent(DOWN_EVENT)).isFalse()
+ }
- // Verify that NPVC gets a chance to use the touch
- verify(notificationPanelViewController).handleExternalInterceptTouch(DOWN_EVENT)
+ @Test
+ fun shouldInterceptTouchEvent_dozing_touchNotInLockIconArea_touchIntercepted() {
+ // GIVEN dozing
+ whenever(sysuiStatusBarStateController.isDozing).thenReturn(true)
+ // AND alternate bouncer doesn't want the touch
+ whenever(statusBarKeyguardViewManager.shouldInterceptTouchEvent(DOWN_EVENT))
+ .thenReturn(false)
+ // AND the lock icon does NOT want the touch
+ whenever(lockIconViewController.willHandleTouchWhileDozing(DOWN_EVENT))
+ .thenReturn(false)
+
+ featureFlags.set(Flags.MIGRATE_NSSL, true)
+
+ // THEN touch should NOT be intercepted by NotificationShade
+ assertThat(interactionEventHandler.shouldInterceptTouchEvent(DOWN_EVENT)).isTrue()
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
index 0023020..189c9e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
@@ -33,6 +33,7 @@
import com.android.systemui.biometrics.data.repository.FakeFacePropertyRepository
import com.android.systemui.bouncer.data.repository.BouncerMessageRepositoryImpl
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
+import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor
import com.android.systemui.bouncer.domain.interactor.CountDownTimerUtil
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerCallbackInteractor
@@ -141,6 +142,8 @@
Optional<UnfoldTransitionProgressProvider>
@Mock private lateinit var notificationInsetsController: NotificationInsetsController
@Mock private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
+ @Mock lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
+ @Mock lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
@Mock
private lateinit var primaryBouncerToGoneTransitionViewModel:
PrimaryBouncerToGoneTransitionViewModel
@@ -180,6 +183,7 @@
featureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true)
featureFlags.set(Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false)
featureFlags.set(Flags.MIGRATE_NSSL, false)
+ featureFlags.set(Flags.ALTERNATE_BOUNCER_VIEW, false)
testScope = TestScope()
controller =
NotificationShadeWindowViewController(
@@ -250,6 +254,8 @@
),
BouncerLogger(logcatLogBuffer("BouncerLog")),
Mockito.mock(KeyEventInteractor::class.java),
+ primaryBouncerInteractor,
+ alternateBouncerInteractor,
)
controller.setupExpandedStatusBar()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
index b5841a9..215f8b1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
@@ -17,6 +17,7 @@
package com.android.systemui.shade
import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
import android.view.Display
import android.view.WindowManager
import androidx.test.filters.SmallTest
@@ -54,6 +55,7 @@
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
@SmallTest
class ShadeControllerImplTest : SysuiTestCase() {
private val executor = FakeExecutor(FakeSystemClock())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt
index 81382a4..bcb060d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeInteractorTest.kt
@@ -60,6 +60,7 @@
import dagger.Component
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
@@ -594,7 +595,8 @@
fromScene = SceneKey.Lockscreen,
toScene = key,
progress = progress,
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
)
sceneInteractor.setTransitionState(transitionState)
@@ -631,7 +633,8 @@
fromScene = key,
toScene = SceneKey.Lockscreen,
progress = progress,
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
)
sceneInteractor.setTransitionState(transitionState)
@@ -667,7 +670,8 @@
fromScene = SceneKey.Lockscreen,
toScene = SceneKey.Shade,
progress = progress,
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
)
sceneInteractor.setTransitionState(transitionState)
@@ -943,7 +947,8 @@
fromScene = SceneKey.Lockscreen,
toScene = key,
progress = progress,
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
)
sceneInteractor.setTransitionState(transitionState)
@@ -980,7 +985,8 @@
fromScene = SceneKey.Lockscreen,
toScene = key,
progress = progress,
- isUserInputDriven = true,
+ isInitiatedByUserInput = true,
+ isUserInputOngoing = flowOf(false),
)
)
sceneInteractor.setTransitionState(transitionState)
@@ -1017,7 +1023,8 @@
fromScene = key,
toScene = SceneKey.Lockscreen,
progress = progress,
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
)
sceneInteractor.setTransitionState(transitionState)
@@ -1054,7 +1061,8 @@
fromScene = key,
toScene = SceneKey.Lockscreen,
progress = progress,
- isUserInputDriven = true,
+ isInitiatedByUserInput = true,
+ isUserInputOngoing = flowOf(false),
)
)
sceneInteractor.setTransitionState(transitionState)
@@ -1089,8 +1097,9 @@
ObservableTransitionState.Transition(
fromScene = SceneKey.Lockscreen,
toScene = SceneKey.QuickSettings,
- progress = progress,
- isUserInputDriven = true,
+ progress = MutableStateFlow(0f),
+ isInitiatedByUserInput = true,
+ isUserInputOngoing = flowOf(false),
)
)
sceneInteractor.setTransitionState(transitionState)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
index 7463e65..6eeafefd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/data/repository/ShadeRepositoryImplTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.shade.ShadeExpansionChangeEvent
import com.android.systemui.shade.ShadeExpansionStateManager
@@ -43,7 +42,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class ShadeRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt
index 607cdab..bb20d94 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/ui/viewmodel/ShadeHeaderViewModelTest.kt
@@ -17,6 +17,7 @@
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
@@ -84,7 +85,8 @@
fromScene = SceneKey.Shade,
toScene = SceneKey.QuickSettings,
progress = MutableStateFlow(0.5f),
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
)
)
@@ -102,7 +104,8 @@
fromScene = SceneKey.QuickSettings,
toScene = SceneKey.Shade,
progress = MutableStateFlow(0.5f),
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
)
)
@@ -120,7 +123,8 @@
fromScene = SceneKey.Gone,
toScene = SceneKey.Shade,
progress = MutableStateFlow(0.5f),
- isUserInputDriven = false,
+ isInitiatedByUserInput = false,
+ isUserInputOngoing = flowOf(false),
)
)
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
index e714736..ae659f4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
@@ -131,11 +131,10 @@
fun addClock(
id: ClockId,
- name: String,
create: (ClockId) -> ClockController = ::failFactory,
getThumbnail: (ClockId) -> Drawable? = ::failThumbnail
): FakeClockPlugin {
- metadata.add(ClockMetadata(id, name))
+ metadata.add(ClockMetadata(id))
createCallbacks[id] = create
thumbnailCallbacks[id] = getThumbnail
return this
@@ -149,7 +148,7 @@
scope = TestScope(dispatcher)
fakeDefaultProvider = FakeClockPlugin()
- .addClock(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME, { mockDefaultClock }, { mockThumbnail })
+ .addClock(DEFAULT_CLOCK_ID, { mockDefaultClock }, { mockThumbnail })
whenever(mockContext.contentResolver).thenReturn(mockContentResolver)
val captor = argumentCaptor<PluginListener<ClockProviderPlugin>>()
@@ -183,13 +182,13 @@
@Test
fun pluginRegistration_CorrectState() {
val plugin1 = FakeClockPlugin()
- .addClock("clock_1", "clock 1")
- .addClock("clock_2", "clock 2")
+ .addClock("clock_1")
+ .addClock("clock_2")
val lifecycle1 = FakeLifecycle("1", plugin1)
val plugin2 = FakeClockPlugin()
- .addClock("clock_3", "clock 3")
- .addClock("clock_4", "clock 4")
+ .addClock("clock_3")
+ .addClock("clock_4")
val lifecycle2 = FakeLifecycle("2", plugin2)
pluginListener.onPluginLoaded(plugin1, mockContext, lifecycle1)
@@ -198,11 +197,11 @@
assertEquals(
list.toSet(),
setOf(
- ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
- ClockMetadata("clock_1", "clock 1"),
- ClockMetadata("clock_2", "clock 2"),
- ClockMetadata("clock_3", "clock 3"),
- ClockMetadata("clock_4", "clock 4")
+ ClockMetadata(DEFAULT_CLOCK_ID),
+ ClockMetadata("clock_1"),
+ ClockMetadata("clock_2"),
+ ClockMetadata("clock_3"),
+ ClockMetadata("clock_4")
)
)
}
@@ -216,13 +215,13 @@
@Test
fun clockIdConflict_ErrorWithoutCrash_unloadDuplicate() {
val plugin1 = FakeClockPlugin()
- .addClock("clock_1", "clock 1", { mockClock }, { mockThumbnail })
- .addClock("clock_2", "clock 2", { mockClock }, { mockThumbnail })
+ .addClock("clock_1", { mockClock }, { mockThumbnail })
+ .addClock("clock_2", { mockClock }, { mockThumbnail })
val lifecycle1 = spy(FakeLifecycle("1", plugin1))
val plugin2 = FakeClockPlugin()
- .addClock("clock_1", "clock 1")
- .addClock("clock_2", "clock 2")
+ .addClock("clock_1")
+ .addClock("clock_2")
val lifecycle2 = spy(FakeLifecycle("2", plugin2))
pluginListener.onPluginLoaded(plugin1, mockContext, lifecycle1)
@@ -231,9 +230,9 @@
assertEquals(
list.toSet(),
setOf(
- ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
- ClockMetadata("clock_1", "clock 1"),
- ClockMetadata("clock_2", "clock 2")
+ ClockMetadata(DEFAULT_CLOCK_ID),
+ ClockMetadata("clock_1"),
+ ClockMetadata("clock_2")
)
)
@@ -248,13 +247,13 @@
@Test
fun createCurrentClock_pluginConnected() {
val plugin1 = FakeClockPlugin()
- .addClock("clock_1", "clock 1")
- .addClock("clock_2", "clock 2")
+ .addClock("clock_1")
+ .addClock("clock_2")
val lifecycle1 = spy(FakeLifecycle("1", plugin1))
val plugin2 = FakeClockPlugin()
- .addClock("clock_3", "clock 3", { mockClock })
- .addClock("clock_4", "clock 4")
+ .addClock("clock_3", { mockClock })
+ .addClock("clock_4")
val lifecycle2 = spy(FakeLifecycle("2", plugin2))
registry.applySettings(ClockSettings("clock_3", null))
@@ -268,13 +267,13 @@
@Test
fun activeClockId_changeAfterPluginConnected() {
val plugin1 = FakeClockPlugin()
- .addClock("clock_1", "clock 1")
- .addClock("clock_2", "clock 2")
+ .addClock("clock_1")
+ .addClock("clock_2")
val lifecycle1 = spy(FakeLifecycle("1", plugin1))
val plugin2 = FakeClockPlugin()
- .addClock("clock_3", "clock 3", { mockClock })
- .addClock("clock_4", "clock 4")
+ .addClock("clock_3", { mockClock })
+ .addClock("clock_4")
val lifecycle2 = spy(FakeLifecycle("2", plugin2))
registry.applySettings(ClockSettings("clock_3", null))
@@ -289,13 +288,13 @@
@Test
fun createDefaultClock_pluginDisconnected() {
val plugin1 = FakeClockPlugin()
- .addClock("clock_1", "clock 1")
- .addClock("clock_2", "clock 2")
+ .addClock("clock_1")
+ .addClock("clock_2")
val lifecycle1 = spy(FakeLifecycle("1", plugin1))
val plugin2 = FakeClockPlugin()
- .addClock("clock_3", "clock 3")
- .addClock("clock_4", "clock 4")
+ .addClock("clock_3")
+ .addClock("clock_4")
val lifecycle2 = spy(FakeLifecycle("2", plugin2))
registry.applySettings(ClockSettings("clock_3", null))
@@ -310,13 +309,13 @@
@Test
fun pluginRemoved_clockAndListChanged() {
val plugin1 = FakeClockPlugin()
- .addClock("clock_1", "clock 1")
- .addClock("clock_2", "clock 2")
+ .addClock("clock_1")
+ .addClock("clock_2")
val lifecycle1 = spy(FakeLifecycle("1", plugin1))
val plugin2 = FakeClockPlugin()
- .addClock("clock_3", "clock 3", { mockClock })
- .addClock("clock_4", "clock 4")
+ .addClock("clock_3", { mockClock })
+ .addClock("clock_4")
val lifecycle2 = spy(FakeLifecycle("2", plugin2))
var changeCallCount = 0
@@ -415,13 +414,13 @@
@Test
fun pluginAddRemove_concurrentModification() {
- val plugin1 = FakeClockPlugin().addClock("clock_1", "clock 1")
+ val plugin1 = FakeClockPlugin().addClock("clock_1")
val lifecycle1 = FakeLifecycle("1", plugin1)
- val plugin2 = FakeClockPlugin().addClock("clock_2", "clock 2")
+ val plugin2 = FakeClockPlugin().addClock("clock_2")
val lifecycle2 = FakeLifecycle("2", plugin2)
- val plugin3 = FakeClockPlugin().addClock("clock_3", "clock 3")
+ val plugin3 = FakeClockPlugin().addClock("clock_3")
val lifecycle3 = FakeLifecycle("3", plugin3)
- val plugin4 = FakeClockPlugin().addClock("clock_4", "clock 4")
+ val plugin4 = FakeClockPlugin().addClock("clock_4")
val lifecycle4 = FakeLifecycle("4", plugin4)
// Set the current clock to the final clock to load
@@ -450,10 +449,10 @@
// Verify all plugins were correctly loaded into the registry
assertEquals(registry.getClocks().toSet(), setOf(
- ClockMetadata("DEFAULT", "Default Clock"),
- ClockMetadata("clock_2", "clock 2"),
- ClockMetadata("clock_3", "clock 3"),
- ClockMetadata("clock_4", "clock 4")
+ ClockMetadata("DEFAULT"),
+ ClockMetadata("clock_2"),
+ ClockMetadata("clock_3"),
+ ClockMetadata("clock_4")
))
}
@@ -527,8 +526,8 @@
featureFlags.set(TRANSIT_CLOCK, flag)
registry.isTransitClockEnabled = featureFlags.isEnabled(TRANSIT_CLOCK)
val plugin = FakeClockPlugin()
- .addClock("clock_1", "clock 1")
- .addClock("DIGITAL_CLOCK_METRO", "metro clock")
+ .addClock("clock_1")
+ .addClock("DIGITAL_CLOCK_METRO")
val lifecycle = FakeLifecycle("metro", plugin)
pluginListener.onPluginLoaded(plugin, mockContext, lifecycle)
@@ -536,17 +535,17 @@
if (flag) {
assertEquals(
setOf(
- ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
- ClockMetadata("clock_1", "clock 1"),
- ClockMetadata("DIGITAL_CLOCK_METRO", "metro clock")
+ ClockMetadata(DEFAULT_CLOCK_ID),
+ ClockMetadata("clock_1"),
+ ClockMetadata("DIGITAL_CLOCK_METRO")
),
list.toSet()
)
} else {
assertEquals(
setOf(
- ClockMetadata(DEFAULT_CLOCK_ID, DEFAULT_CLOCK_NAME),
- ClockMetadata("clock_1", "clock 1")
+ ClockMetadata(DEFAULT_CLOCK_ID),
+ ClockMetadata("clock_1")
),
list.toSet()
)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt
index 7a2d122..b8fe2f9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/BcSmartspaceConfigProviderTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
@@ -33,7 +32,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class BcSmartspaceConfigProviderTest : SysuiTestCase() {
@Mock private lateinit var featureFlags: FeatureFlags
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
index f1c181f..e093859 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
@@ -26,7 +26,6 @@
import android.widget.FrameLayout
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dreams.smartspace.DreamSmartspaceController
import com.android.systemui.plugins.BcSmartspaceConfigPlugin
@@ -53,7 +52,6 @@
import org.mockito.Spy
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class DreamSmartspaceControllerTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt
index 7af29ba..886c61a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt
@@ -25,7 +25,6 @@
import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.settings.UserTracker
import com.android.systemui.smartspace.filters.LockscreenAndDreamTargetFilter
@@ -52,7 +51,6 @@
@SmallTest
@TestableLooper.RunWithLooper
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class LockscreenAndDreamTargetFilterTest : SysuiTestCase() {
@Mock
diff --git a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
index a7c223d..0b5aea7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
@@ -19,7 +19,6 @@
import android.testing.TestableLooper
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.smartspace.preconditions.LockscreenPrecondition
import com.android.systemui.statusbar.policy.DeviceProvisionedController
@@ -36,7 +35,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
@TestableLooper.RunWithLooper
class LockscreenPreconditionTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
index fbb8ebf..20e5c43 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/PulseExpansionHandlerTest.kt
@@ -29,9 +29,9 @@
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
import com.android.systemui.statusbar.notification.row.ExpandableView
import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.ConfigurationController
+import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.util.mockito.mock
import org.junit.Before
import org.junit.Test
@@ -52,7 +52,7 @@
private val collapsedHeight = 300
private val wakeUpCoordinator: NotificationWakeUpCoordinator = mock()
private val bypassController: KeyguardBypassController = mock()
- private val headsUpManager: HeadsUpManagerPhone = mock()
+ private val headsUpManager: HeadsUpManager = mock()
private val roundnessManager: NotificationRoundnessManager = mock()
private val configurationController: ConfigurationController = mock()
private val statusBarStateController: StatusBarStateController = mock()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
index d86f8bb..235ac5c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
@@ -8,15 +8,15 @@
import com.android.internal.jank.InteractionJankMonitor
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.res.R
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.NotificationTestHelper
import com.android.systemui.statusbar.notification.stack.NotificationListContainer
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
+import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.statusbar.policy.HeadsUpUtil
-import com.android.systemui.res.R
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
import kotlinx.coroutines.test.TestScope
@@ -37,7 +37,7 @@
@RunWithLooper
class NotificationLaunchAnimatorControllerTest : SysuiTestCase() {
@Mock lateinit var notificationListContainer: NotificationListContainer
- @Mock lateinit var headsUpManager: HeadsUpManagerPhone
+ @Mock lateinit var headsUpManager: HeadsUpManager
@Mock lateinit var jankMonitor: InteractionJankMonitor
@Mock lateinit var onFinishAnimationCallback: Runnable
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
index 257cc5b..4f1581c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
@@ -43,8 +43,8 @@
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderWrapper.FullScreenIntentDecisionImpl
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider
import com.android.systemui.statusbar.notification.row.NotifBindPipeline.BindCallback
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
import com.android.systemui.statusbar.phone.NotificationGroupTestHelper
-import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
@@ -87,7 +87,7 @@
private val notifPipeline: NotifPipeline = mock()
private val logger = HeadsUpCoordinatorLogger(logcatLogBuffer(), verbose = true)
- private val headsUpManager: HeadsUpManager = mock()
+ private val headsUpManager: HeadsUpManagerPhone = mock()
private val headsUpViewBinder: HeadsUpViewBinder = mock()
private val visualInterruptionDecisionProvider: VisualInterruptionDecisionProvider = mock()
private val remoteInputManager: NotificationRemoteInputManager = mock()
@@ -435,7 +435,7 @@
private fun addHUN(entry: NotificationEntry) {
huns.add(entry)
- whenever(headsUpManager.topEntry).thenReturn(entry)
+ whenever(headsUpManager.getTopEntry()).thenReturn(entry)
onHeadsUpChangedListener.onHeadsUpStateChanged(entry, true)
notifLifetimeExtender.cancelLifetimeExtension(entry)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
index fbd61f4..546abd4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
@@ -23,7 +23,6 @@
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.advanceTimeBy
import com.android.systemui.dump.DumpManager
import com.android.systemui.dump.logcatLogBuffer
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
@@ -40,10 +39,10 @@
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
-import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProvider
-import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
+import com.android.systemui.statusbar.notification.stack.data.repository.NotificationListRepository
+import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationListInteractor
import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
import com.android.systemui.util.mockito.any
@@ -247,7 +246,7 @@
unseenFilter.onCleanup()
// THEN: The SeenNotificationProvider has been updated to reflect the suppression
- assertThat(seenNotificationsProvider.hasFilteredOutSeenNotifications).isTrue()
+ assertThat(notificationListInteractor.hasFilteredOutSeenNotifications.value).isTrue()
}
}
@@ -598,7 +597,7 @@
FakeSettings().apply {
putInt(Settings.Secure.LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS, 1)
}
- val seenNotificationsProvider = SeenNotificationsProviderImpl()
+ val notificationListInteractor = NotificationListInteractor(NotificationListRepository())
val keyguardCoordinator =
KeyguardCoordinator(
testDispatcher,
@@ -611,7 +610,7 @@
testScope.backgroundScope,
sectionHeaderVisibilityProvider,
fakeSettings,
- seenNotificationsProvider,
+ notificationListInteractor,
statusBarStateController,
)
keyguardCoordinator.attach(notifPipeline)
@@ -619,7 +618,7 @@
KeyguardCoordinatorTestScope(
keyguardCoordinator,
testScope,
- seenNotificationsProvider,
+ notificationListInteractor,
fakeSettings,
)
.testBlock()
@@ -629,7 +628,7 @@
private inner class KeyguardCoordinatorTestScope(
private val keyguardCoordinator: KeyguardCoordinator,
private val scope: TestScope,
- val seenNotificationsProvider: SeenNotificationsProvider,
+ val notificationListInteractor: NotificationListInteractor,
private val fakeSettings: FakeSettings,
) : CoroutineScope by scope {
val testScheduler: TestCoroutineScheduler
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java
index c9b77c5..9c20e54 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/FeedbackInfoTest.java
@@ -54,9 +54,9 @@
import android.widget.TextView;
import com.android.internal.statusbar.IStatusBarService;
-import com.android.systemui.res.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+import com.android.systemui.res.R;
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
@@ -132,7 +132,8 @@
public void testBindNotification_SetsTextApplicationName() {
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(),
- mMockNotificationRow, mAssistantFeedbackController);
+ mMockNotificationRow, mAssistantFeedbackController, mStatusBarService,
+ mNotificationGutsManager);
final TextView textView = mFeedbackInfo.findViewById(R.id.pkg_name);
assertTrue(textView.getText().toString().contains("App Name"));
}
@@ -143,7 +144,8 @@
when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
.thenReturn(iconDrawable);
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(),
- mMockNotificationRow, mAssistantFeedbackController);
+ mMockNotificationRow, mAssistantFeedbackController, mStatusBarService,
+ mNotificationGutsManager);
final ImageView iconView = mFeedbackInfo.findViewById(R.id.pkg_icon);
assertEquals(iconDrawable, iconView.getDrawable());
}
@@ -153,7 +155,7 @@
when(mAssistantFeedbackController.getFeedbackStatus(any(NotificationEntry.class)))
.thenReturn(STATUS_SILENCED);
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(), mMockNotificationRow,
- mAssistantFeedbackController);
+ mAssistantFeedbackController, mStatusBarService, mNotificationGutsManager);
TextView prompt = mFeedbackInfo.findViewById(R.id.prompt);
assertEquals("This notification was automatically demoted to Silent by the system. "
+ "Let the developer know your feedback. Was this correct?",
@@ -165,7 +167,7 @@
when(mAssistantFeedbackController.getFeedbackStatus(any(NotificationEntry.class)))
.thenReturn(STATUS_PROMOTED);
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(), mMockNotificationRow,
- mAssistantFeedbackController);
+ mAssistantFeedbackController, mStatusBarService, mNotificationGutsManager);
TextView prompt = mFeedbackInfo.findViewById(R.id.prompt);
assertEquals("This notification was automatically ranked higher in your shade. "
+ "Let the developer know your feedback. Was this correct?",
@@ -177,7 +179,7 @@
when(mAssistantFeedbackController.getFeedbackStatus(any(NotificationEntry.class)))
.thenReturn(STATUS_ALERTED);
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(), mMockNotificationRow,
- mAssistantFeedbackController);
+ mAssistantFeedbackController, mStatusBarService, mNotificationGutsManager);
TextView prompt = mFeedbackInfo.findViewById(R.id.prompt);
assertEquals("This notification was automatically promoted to Default by the system. "
+ "Let the developer know your feedback. Was this correct?",
@@ -189,7 +191,7 @@
when(mAssistantFeedbackController.getFeedbackStatus(any(NotificationEntry.class)))
.thenReturn(STATUS_DEMOTED);
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(), mMockNotificationRow,
- mAssistantFeedbackController);
+ mAssistantFeedbackController, mStatusBarService, mNotificationGutsManager);
TextView prompt = mFeedbackInfo.findViewById(R.id.prompt);
assertEquals("This notification was automatically ranked lower in your shade. "
+ "Let the developer know your feedback. Was this correct?",
@@ -199,7 +201,7 @@
@Test
public void testPositiveFeedback() {
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(), mMockNotificationRow,
- mAssistantFeedbackController);
+ mAssistantFeedbackController, mStatusBarService, mNotificationGutsManager);
final View yes = mFeedbackInfo.findViewById(R.id.yes);
yes.performClick();
@@ -216,7 +218,7 @@
.thenReturn(true);
mFeedbackInfo.bindGuts(mMockPackageManager, mSbn, getEntry(), mMockNotificationRow,
- mAssistantFeedbackController);
+ mAssistantFeedbackController, mStatusBarService, mNotificationGutsManager);
final View no = mFeedbackInfo.findViewById(R.id.no);
no.performClick();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index 9f2afdf..8a730cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -33,7 +33,6 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anySet;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
@@ -89,8 +88,8 @@
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.kotlin.JavaAdapter;
import com.android.systemui.util.time.FakeSystemClock;
@@ -152,7 +151,7 @@
@Mock private AssistantFeedbackController mAssistantFeedbackController;
@Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager;
@Mock private StatusBarStateController mStatusBarStateController;
- @Mock private HeadsUpManagerPhone mHeadsUpManagerPhone;
+ @Mock private HeadsUpManager mHeadsUpManager;
@Mock private ActivityStarter mActivityStarter;
@Mock private UserManager mUserManager;
@@ -171,7 +170,7 @@
mTestScope.getBackgroundScope(),
new WindowRootViewVisibilityRepository(mBarService, mExecutor),
new FakeKeyguardRepository(),
- mHeadsUpManagerPhone,
+ mHeadsUpManager,
PowerInteractorFactory.create().getPowerInteractor());
mGutsManager = new NotificationGutsManager(
@@ -196,9 +195,10 @@
mWindowRootViewVisibilityInteractor,
mNotificationLockscreenUserManager,
mStatusBarStateController,
+ mBarService,
mDeviceProvisionedController,
mMetricsLogger,
- mHeadsUpManagerPhone,
+ mHeadsUpManager,
mActivityStarter);
mGutsManager.setUpWithPresenter(mPresenter, mNotificationListContainer,
mOnSettingsClickListener);
@@ -239,7 +239,7 @@
anyInt(),
anyBoolean(),
any(Runnable.class));
- verify(mHeadsUpManagerPhone).setGutsShown(realRow.getEntry(), true);
+ verify(mHeadsUpManager).setGutsShown(realRow.getEntry(), true);
assertEquals(View.VISIBLE, guts.getVisibility());
mGutsManager.closeAndSaveGuts(false, false, true, 0, 0, false);
@@ -247,7 +247,7 @@
verify(guts).closeControls(anyBoolean(), anyBoolean(), anyInt(), anyInt(), anyBoolean());
verify(row, times(1)).setGutsView(any());
mTestableLooper.processAllMessages();
- verify(mHeadsUpManagerPhone).setGutsShown(realRow.getEntry(), false);
+ verify(mHeadsUpManager).setGutsShown(realRow.getEntry(), false);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index ac680e6..cb73108 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -61,6 +61,7 @@
import com.android.systemui.media.controls.util.MediaFeatureFlag;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.res.R;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -81,14 +82,13 @@
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow.OnExpandClickListener;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.InflatedSmartReplyState;
import com.android.systemui.statusbar.policy.InflatedSmartReplyViewHolder;
import com.android.systemui.statusbar.policy.SmartReplyConstants;
import com.android.systemui.statusbar.policy.SmartReplyStateInflater;
import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
-import com.android.systemui.res.R;
import com.android.systemui.wmshell.BubblesManager;
import com.android.systemui.wmshell.BubblesTestActivity;
@@ -123,7 +123,7 @@
private final GroupMembershipManager mGroupMembershipManager;
private final GroupExpansionManager mGroupExpansionManager;
private ExpandableNotificationRow mRow;
- private final HeadsUpManagerPhone mHeadsUpManager;
+ private final HeadsUpManager mHeadsUpManager;
private final NotifBindPipeline mBindPipeline;
private final NotifCollectionListener mBindPipelineEntryListener;
private final RowContentBindStage mBindStage;
@@ -161,7 +161,7 @@
mKeyguardBypassController = mock(KeyguardBypassController.class);
mGroupMembershipManager = mock(GroupMembershipManager.class);
mGroupExpansionManager = mock(GroupExpansionManager.class);
- mHeadsUpManager = mock(HeadsUpManagerPhone.class);
+ mHeadsUpManager = mock(HeadsUpManager.class);
mIconManager = new IconManager(
mock(CommonNotifCollection.class),
mock(LauncherApps.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
index ffe312b..20197e3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutControllerTest.java
@@ -77,7 +77,6 @@
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
-import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl;
import com.android.systemui.statusbar.notification.collection.provider.VisibilityLocationProviderDelegator;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.NotifStats;
@@ -88,13 +87,15 @@
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController.NotificationPanelEvent;
import com.android.systemui.statusbar.notification.stack.NotificationSwipeHelper.NotificationCallback;
+import com.android.systemui.statusbar.notification.stack.data.repository.NotificationListRepository;
+import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationListInteractor;
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationListViewModel;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.tuner.TunerService;
@@ -124,7 +125,7 @@
@Mock private NotificationGutsManager mNotificationGutsManager;
@Mock private NotificationsController mNotificationsController;
@Mock private NotificationVisibilityProvider mVisibilityProvider;
- @Mock private HeadsUpManagerPhone mHeadsUpManager;
+ @Mock private HeadsUpManager mHeadsUpManager;
@Mock private NotificationRoundnessManager mNotificationRoundnessManager;
@Mock private TunerService mTunerService;
@Mock private DeviceProvisionedController mDeviceProvisionedController;
@@ -170,8 +171,8 @@
@Captor
private ArgumentCaptor<StatusBarStateController.StateListener> mStateListenerArgumentCaptor;
- private final SeenNotificationsProviderImpl mSeenNotificationsProvider =
- new SeenNotificationsProviderImpl();
+ private final NotificationListInteractor mNotificationListInteractor =
+ new NotificationListInteractor(new NotificationListRepository());
private NotificationStackScrollLayoutController mController;
@@ -503,7 +504,7 @@
@Test
public void testSetNotifStats_updatesHasFilteredOutSeenNotifications() {
initController(/* viewIsAttached= */ true);
- mSeenNotificationsProvider.setHasFilteredOutSeenNotifications(true);
+ mNotificationListInteractor.setHasFilteredOutSeenNotifications(true);
mController.getNotifStackController().setNotifStats(NotifStats.getEmpty());
verify(mNotificationStackScrollLayout).setHasFilteredOutSeenNotifications(true);
verify(mNotificationStackScrollLayout).updateFooter();
@@ -703,7 +704,7 @@
mUiEventLogger,
mRemoteInputManager,
mVisibilityLocationProviderDelegator,
- mSeenNotificationsProvider,
+ mNotificationListInteractor,
mShadeController,
mJankMonitor,
mStackLogger,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
index a5d3484..e7dad6a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacksTest.java
@@ -57,6 +57,7 @@
import com.android.systemui.statusbar.disableflags.DisableFlagsLogger;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
@@ -85,7 +86,7 @@
private final MetricsLogger mMetricsLogger = new FakeMetricsLogger();
@Mock private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock private KeyguardStateController mKeyguardStateController;
- @Mock private HeadsUpManagerPhone mHeadsUpManager;
+ @Mock private HeadsUpManager mHeadsUpManager;
@Mock private WakefulnessLifecycle mWakefulnessLifecycle;
@Mock private DeviceProvisionedController mDeviceProvisionedController;
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index e2efd25..f18af61 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -85,7 +85,6 @@
import com.android.keyguard.TestScopeProvider;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.InitController;
-import com.android.systemui.res.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuController;
import com.android.systemui.animation.ActivityLaunchAnimator;
@@ -117,6 +116,7 @@
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.power.domain.interactor.PowerInteractor;
+import com.android.systemui.res.R;
import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.settings.brightness.BrightnessSliderController;
@@ -219,7 +219,7 @@
@Mock private KeyguardIndicationController mKeyguardIndicationController;
@Mock private NotificationStackScrollLayout mStackScroller;
@Mock private NotificationStackScrollLayoutController mStackScrollerController;
- @Mock private HeadsUpManagerPhone mHeadsUpManager;
+ @Mock private HeadsUpManager mHeadsUpManager;
@Mock private NotificationPanelViewController mNotificationPanelViewController;
@Mock private ShadeLogger mShadeLogger;
@Mock private NotificationPanelView mNotificationPanelView;
@@ -344,6 +344,7 @@
mFeatureFlags.set(Flags.LIGHT_REVEAL_MIGRATION, true);
// Turn AOD on and toggle feature flag for jank fixes
mFeatureFlags.set(Flags.ZJ_285570694_LOCKSCREEN_TRANSITION_FROM_AOD, true);
+ mFeatureFlags.set(Flags.ALTERNATE_BOUNCER_VIEW, false);
when(mDozeParameters.getAlwaysOn()).thenReturn(true);
IThermalService thermalService = mock(IThermalService.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index ff6f40d5..593c587 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -53,6 +53,7 @@
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import org.junit.Before;
import org.junit.Test;
@@ -72,7 +73,7 @@
private DozeServiceHost mDozeServiceHost;
- @Mock private HeadsUpManagerPhone mHeadsUpManager;
+ @Mock private HeadsUpManager mHeadsUpManager;
@Mock private ScrimController mScrimController;
@Mock private DozeScrimController mDozeScrimController;
@Mock private StatusBarStateControllerImpl mStatusBarStateController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
index ec6286b..d84bb72 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
@@ -47,6 +47,7 @@
import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.policy.Clock;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Assert;
@@ -72,7 +73,7 @@
private ExpandableNotificationRow mRow;
private NotificationEntry mEntry;
private HeadsUpStatusBarView mHeadsUpStatusBarView;
- private HeadsUpManagerPhone mHeadsUpManager;
+ private HeadsUpManager mHeadsUpManager;
private View mOperatorNameView;
private StatusBarStateController mStatusbarStateController;
private PhoneStatusBarTransitions mPhoneStatusBarTransitions;
@@ -93,7 +94,7 @@
mEntry = mRow.getEntry();
mHeadsUpStatusBarView = new HeadsUpStatusBarView(mContext, mock(View.class),
mock(TextView.class));
- mHeadsUpManager = mock(HeadsUpManagerPhone.class);
+ mHeadsUpManager = mock(HeadsUpManager.class);
mOperatorNameView = new View(mContext);
mStatusbarStateController = mock(StatusBarStateController.class);
mPhoneStatusBarTransitions = mock(PhoneStatusBarTransitions.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index 1bc522d..cda2a74 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -32,8 +32,8 @@
import androidx.test.filters.SmallTest;
import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.res.R;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.res.R;
import com.android.systemui.shade.ShadeExpansionStateManager;
import com.android.systemui.statusbar.AlertingNotificationManager;
import com.android.systemui.statusbar.AlertingNotificationManagerTest;
@@ -43,6 +43,7 @@
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.HeadsUpManagerLogger;
import org.junit.After;
@@ -71,7 +72,6 @@
@Mock private AccessibilityManagerWrapper mAccessibilityManagerWrapper;
@Mock private ShadeExpansionStateManager mShadeExpansionStateManager;
@Mock private UiEventLogger mUiEventLogger;
- private boolean mLivesPastNormalTime;
private static final class TestableHeadsUpManagerPhone extends HeadsUpManagerPhone {
TestableHeadsUpManagerPhone(
@@ -149,7 +149,7 @@
@Test
public void testSnooze() {
- final HeadsUpManagerPhone hmp = createHeadsUpManagerPhone();
+ final HeadsUpManager hmp = createHeadsUpManagerPhone();
final NotificationEntry entry = createEntry(/* id = */ 0);
hmp.showNotification(entry);
@@ -160,7 +160,7 @@
@Test
public void testSwipedOutNotification() {
- final HeadsUpManagerPhone hmp = createHeadsUpManagerPhone();
+ final HeadsUpManager hmp = createHeadsUpManagerPhone();
final NotificationEntry entry = createEntry(/* id = */ 0);
hmp.showNotification(entry);
@@ -176,7 +176,7 @@
@Test
public void testCanRemoveImmediately_swipedOut() {
- final HeadsUpManagerPhone hmp = createHeadsUpManagerPhone();
+ final HeadsUpManager hmp = createHeadsUpManagerPhone();
final NotificationEntry entry = createEntry(/* id = */ 0);
hmp.showNotification(entry);
@@ -189,7 +189,7 @@
@Ignore("b/141538055")
@Test
public void testCanRemoveImmediately_notTopEntry() {
- final HeadsUpManagerPhone hmp = createHeadsUpManagerPhone();
+ final HeadsUpManager hmp = createHeadsUpManagerPhone();
final NotificationEntry earlierEntry = createEntry(/* id = */ 0);
final NotificationEntry laterEntry = createEntry(/* id = */ 1);
laterEntry.setRow(mRow);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index bac8579..b36d09d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -18,6 +18,9 @@
import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.EXPANSION_HIDDEN;
import static com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants.EXPANSION_VISIBLE;
+
+import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher;
+
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -33,7 +36,6 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import static kotlinx.coroutines.test.TestCoroutineDispatchersKt.StandardTestDispatcher;
import android.service.trust.TrustAgentService;
import android.testing.AndroidTestingRunner;
@@ -175,6 +177,7 @@
mFeatureFlags.set(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT, false);
mFeatureFlags.set(Flags.UDFPS_NEW_TOUCH_DETECTION, true);
mFeatureFlags.set(Flags.KEYGUARD_WM_STATE_REFACTOR, false);
+ mFeatureFlags.set(Flags.ALTERNATE_BOUNCER_VIEW, false);
when(mNotificationShadeWindowController.getWindowRootView())
.thenReturn(mNotificationShadeWindowView);
@@ -761,6 +764,30 @@
}
@Test
+ public void handleDispatchTouchEvent_alternateBouncerViewFlagEnabled() {
+ mStatusBarKeyguardViewManager.addCallback(mCallback);
+
+ // GIVEN alternate bouncer view flag enabled & the alternate bouncer is visible
+ mFeatureFlags.set(Flags.ALTERNATE_BOUNCER_VIEW, true);
+ when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
+
+ // THEN the touch is not acted upon
+ verify(mCallback, never()).onTouch(any());
+ }
+
+ @Test
+ public void onInterceptTouch_alternateBouncerViewFlagEnabled() {
+ // GIVEN alternate bouncer view flag enabled & the alternate bouncer is visible
+ mFeatureFlags.set(Flags.ALTERNATE_BOUNCER_VIEW, true);
+ when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
+
+ // THEN the touch is not intercepted
+ assertFalse(mStatusBarKeyguardViewManager.shouldInterceptTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+ ));
+ }
+
+ @Test
public void handleDispatchTouchEvent_alternateBouncerNotVisible() {
mStatusBarKeyguardViewManager.addCallback(mCallback);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index 8013e5e..beac995 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -92,6 +92,7 @@
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
@@ -218,7 +219,7 @@
mScreenOffAnimationController,
mStatusBarStateController).getPowerInteractor();
- HeadsUpManagerPhone headsUpManager = mock(HeadsUpManagerPhone.class);
+ HeadsUpManager headsUpManager = mock(HeadsUpManager.class);
NotificationLaunchAnimatorControllerProvider notificationAnimationProvider =
new NotificationLaunchAnimatorControllerProvider(
new NotificationExpansionRepository(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
index 233f407..ee4f208 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
@@ -15,6 +15,7 @@
package com.android.systemui.statusbar.phone;
import static android.view.Display.DEFAULT_DISPLAY;
+
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
@@ -59,6 +60,7 @@
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
@@ -106,7 +108,7 @@
mContext,
shadeViewController,
mock(QuickSettingsController.class),
- mock(HeadsUpManagerPhone.class),
+ mock(HeadsUpManager.class),
notificationShadeWindowView,
mock(ActivityStarter.class),
stackScrollLayoutController,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
index dbaa29b..d06a6e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositorySwitcherTest.kt
@@ -20,7 +20,6 @@
import android.net.wifi.WifiManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.demomode.DemoMode
import com.android.systemui.demomode.DemoModeController
@@ -53,7 +52,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class WifiRepositorySwitcherTest : SysuiTestCase() {
private lateinit var underTest: WifiRepositorySwitcher
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt
index 206ac1d..ce00250 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/DisabledWifiRepositoryTest.kt
@@ -18,7 +18,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
@@ -28,7 +27,6 @@
import org.junit.runner.RunWith
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class DisabledWifiRepositoryTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
index c2e75aa..cf20ba8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImplTest.kt
@@ -35,7 +35,6 @@
import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.log.table.TableLogBuffer
@@ -73,7 +72,6 @@
@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class WifiRepositoryImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
index 1db8065..7fbbfc7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorImplTest.kt
@@ -19,7 +19,6 @@
import android.net.wifi.WifiManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
@@ -43,7 +42,6 @@
@OptIn(ExperimentalCoroutinesApi::class)
@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class WifiInteractorImplTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
index 49a2648..2d1a27f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
@@ -19,7 +19,6 @@
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.settingslib.AccessibilityContentDescriptions.WIFI_OTHER_DEVICE_CONNECTION
-import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
import com.android.systemui.coroutines.collectLastValue
@@ -53,7 +52,6 @@
import org.mockito.MockitoAnnotations
@SmallTest
-@RoboPilotTest
@RunWith(AndroidJUnit4::class)
class WifiViewModelTest : SysuiTestCase() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
index 64ebcd9..4f3f564 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
@@ -41,10 +41,13 @@
import android.app.Person;
import android.content.Context;
import android.content.Intent;
+import android.graphics.Region;
import android.os.Handler;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.test.filters.SmallTest;
import com.android.internal.logging.UiEventLogger;
@@ -73,7 +76,7 @@
private final HeadsUpManagerLogger mLogger = spy(new HeadsUpManagerLogger(logcatLogBuffer()));
@Mock private AccessibilityManagerWrapper mAccessibilityMgr;
- private final class TestableHeadsUpManager extends HeadsUpManager {
+ private final class TestableHeadsUpManager extends BaseHeadsUpManager {
TestableHeadsUpManager(Context context,
HeadsUpManagerLogger logger,
Handler handler,
@@ -85,9 +88,78 @@
mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
mStickyDisplayTime = TEST_STICKY_AUTO_DISMISS_TIME;
}
+
+ // The following are only implemented by HeadsUpManagerPhone. If you need them, use that.
+ @Override
+ public void addHeadsUpPhoneListener(@NonNull OnHeadsUpPhoneListenerChange listener) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void addSwipedOutNotification(@NonNull String key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void extendHeadsUp() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Nullable
+ @Override
+ public Region getTouchableRegion() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isHeadsUpGoingAway() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void onExpandingFinished() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean removeNotification(@NonNull String key, boolean releaseImmediately,
+ boolean animate) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setAnimationStateHandler(@NonNull AnimationStateHandler handler) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setGutsShown(@NonNull NotificationEntry entry, boolean gutsShown) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setHeadsUpGoingAway(boolean headsUpGoingAway) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setRemoteInputActive(@NonNull NotificationEntry entry,
+ boolean remoteInputActive) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setTrackingHeadsUp(boolean tracking) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean shouldSwallowClick(@NonNull String key) {
+ throw new UnsupportedOperationException();
+ }
}
- private HeadsUpManager createHeadsUpManager() {
+ private BaseHeadsUpManager createHeadsUpManager() {
return new TestableHeadsUpManager(mContext, mLogger, mTestHandler, mAccessibilityMgr,
mUiEventLoggerFake);
}
@@ -165,9 +237,10 @@
@Test
public void testHunRemovedLogging() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry notifEntry = createEntry(/* id = */ 0);
- final HeadsUpManager.HeadsUpEntry headsUpEntry = mock(HeadsUpManager.HeadsUpEntry.class);
+ final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = mock(
+ BaseHeadsUpManager.HeadsUpEntry.class);
headsUpEntry.mEntry = notifEntry;
hum.onAlertEntryRemoved(headsUpEntry);
@@ -177,35 +250,37 @@
@Test
public void testShouldHeadsUpBecomePinned_hasFSI_notUnpinned_true() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry notifEntry = createFullScreenIntentEntry(/* id = */ 0);
// Add notifEntry to ANM mAlertEntries map and make it NOT unpinned
hum.showNotification(notifEntry);
- final HeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(notifEntry.getKey());
- headsUpEntry.wasUnpinned = false;
+ final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(
+ notifEntry.getKey());
+ headsUpEntry.mWasUnpinned = false;
assertTrue(hum.shouldHeadsUpBecomePinned(notifEntry));
}
@Test
public void testShouldHeadsUpBecomePinned_wasUnpinned_false() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry notifEntry = createFullScreenIntentEntry(/* id = */ 0);
// Add notifEntry to ANM mAlertEntries map and make it unpinned
hum.showNotification(notifEntry);
- final HeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(notifEntry.getKey());
- headsUpEntry.wasUnpinned = true;
+ final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(
+ notifEntry.getKey());
+ headsUpEntry.mWasUnpinned = true;
assertFalse(hum.shouldHeadsUpBecomePinned(notifEntry));
}
@Test
public void testShouldHeadsUpBecomePinned_noFSI_false() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry entry = createEntry(/* id = */ 0);
assertFalse(hum.shouldHeadsUpBecomePinned(entry));
@@ -214,7 +289,7 @@
@Test
public void testShowNotification_autoDismissesIncludingTouchAcceptanceDelay() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry entry = createEntry(/* id = */ 0);
useAccessibilityTimeout(false);
@@ -228,7 +303,7 @@
@Test
public void testShowNotification_autoDismissesWithDefaultTimeout() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry entry = createEntry(/* id = */ 0);
useAccessibilityTimeout(false);
@@ -242,7 +317,7 @@
@Test
public void testShowNotification_stickyForSomeTime_autoDismissesWithStickyTimeout() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry entry = createStickyForSomeTimeEntry(/* id = */ 0);
useAccessibilityTimeout(false);
@@ -256,7 +331,7 @@
@Test
public void testShowNotification_sticky_neverAutoDismisses() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry entry = createStickyEntry(/* id = */ 0);
useAccessibilityTimeout(false);
@@ -278,7 +353,7 @@
@Test
public void testShowNotification_autoDismissesWithAccessibilityTimeout() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry entry = createEntry(/* id = */ 0);
useAccessibilityTimeout(true);
@@ -292,7 +367,7 @@
@Test
public void testShowNotification_stickyForSomeTime_autoDismissesWithAccessibilityTimeout() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry entry = createStickyForSomeTimeEntry(/* id = */ 0);
useAccessibilityTimeout(true);
@@ -306,7 +381,7 @@
@Test
public void testRemoveNotification_beforeMinimumDisplayTime() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry entry = createEntry(/* id = */ 0);
useAccessibilityTimeout(false);
@@ -329,7 +404,7 @@
@Test
public void testRemoveNotification_afterMinimumDisplayTime() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry entry = createEntry(/* id = */ 0);
useAccessibilityTimeout(false);
@@ -366,7 +441,7 @@
@Test
public void testRemoveNotification_releaseImmediately() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry entry = createEntry(/* id = */ 0);
hum.showNotification(entry);
@@ -382,14 +457,15 @@
@Test
public void testIsSticky_rowPinnedAndExpanded_true() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry notifEntry = createEntry(/* id = */ 0);
when(mRow.isPinned()).thenReturn(true);
notifEntry.setRow(mRow);
hum.showNotification(notifEntry);
- final HeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(notifEntry.getKey());
+ final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(
+ notifEntry.getKey());
headsUpEntry.setExpanded(true);
assertTrue(hum.isSticky(notifEntry.getKey()));
@@ -397,20 +473,21 @@
@Test
public void testIsSticky_remoteInputActive_true() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry notifEntry = createEntry(/* id = */ 0);
hum.showNotification(notifEntry);
- final HeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(notifEntry.getKey());
- headsUpEntry.remoteInputActive = true;
+ final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(
+ notifEntry.getKey());
+ headsUpEntry.mRemoteInputActive = true;
assertTrue(hum.isSticky(notifEntry.getKey()));
}
@Test
public void testIsSticky_hasFullScreenIntent_true() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry notifEntry = createFullScreenIntentEntry(/* id = */ 0);
hum.showNotification(notifEntry);
@@ -421,7 +498,7 @@
@Test
public void testIsSticky_stickyForSomeTime_false() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry entry = createStickyForSomeTimeEntry(/* id = */ 0);
hum.showNotification(entry);
@@ -432,21 +509,22 @@
@Test
public void testIsSticky_false() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry notifEntry = createEntry(/* id = */ 0);
hum.showNotification(notifEntry);
- final HeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(notifEntry.getKey());
+ final BaseHeadsUpManager.HeadsUpEntry headsUpEntry = hum.getHeadsUpEntry(
+ notifEntry.getKey());
headsUpEntry.setExpanded(false);
- headsUpEntry.remoteInputActive = false;
+ headsUpEntry.mRemoteInputActive = false;
assertFalse(hum.isSticky(notifEntry.getKey()));
}
@Test
public void testCompareTo_withNullEntries() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry alertEntry = new NotificationEntryBuilder().setTag("alert").build();
hum.showNotification(alertEntry);
@@ -458,7 +536,7 @@
@Test
public void testCompareTo_withNonAlertEntries() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry nonAlertEntry1 = new NotificationEntryBuilder().setTag(
"nae1").build();
@@ -474,9 +552,9 @@
@Test
public void testAlertEntryCompareTo_ongoingCallLessThanActiveRemoteInput() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
- final HeadsUpManager.HeadsUpEntry ongoingCall = hum.new HeadsUpEntry();
+ final BaseHeadsUpManager.HeadsUpEntry ongoingCall = hum.new HeadsUpEntry();
ongoingCall.setEntry(new NotificationEntryBuilder()
.setSbn(createSbn(/* id = */ 0,
new Notification.Builder(mContext, "")
@@ -484,9 +562,9 @@
.setOngoing(true)))
.build());
- final HeadsUpManager.HeadsUpEntry activeRemoteInput = hum.new HeadsUpEntry();
+ final BaseHeadsUpManager.HeadsUpEntry activeRemoteInput = hum.new HeadsUpEntry();
activeRemoteInput.setEntry(createEntry(/* id = */ 1));
- activeRemoteInput.remoteInputActive = true;
+ activeRemoteInput.mRemoteInputActive = true;
assertThat(ongoingCall.compareTo(activeRemoteInput)).isLessThan(0);
assertThat(activeRemoteInput.compareTo(ongoingCall)).isGreaterThan(0);
@@ -494,9 +572,9 @@
@Test
public void testAlertEntryCompareTo_incomingCallLessThanActiveRemoteInput() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
- final HeadsUpManager.HeadsUpEntry incomingCall = hum.new HeadsUpEntry();
+ final BaseHeadsUpManager.HeadsUpEntry incomingCall = hum.new HeadsUpEntry();
final Person person = new Person.Builder().setName("person").build();
final PendingIntent intent = mock(PendingIntent.class);
incomingCall.setEntry(new NotificationEntryBuilder()
@@ -506,9 +584,9 @@
.forIncomingCall(person, intent, intent))))
.build());
- final HeadsUpManager.HeadsUpEntry activeRemoteInput = hum.new HeadsUpEntry();
+ final BaseHeadsUpManager.HeadsUpEntry activeRemoteInput = hum.new HeadsUpEntry();
activeRemoteInput.setEntry(createEntry(/* id = */ 1));
- activeRemoteInput.remoteInputActive = true;
+ activeRemoteInput.mRemoteInputActive = true;
assertThat(incomingCall.compareTo(activeRemoteInput)).isLessThan(0);
assertThat(activeRemoteInput.compareTo(incomingCall)).isGreaterThan(0);
@@ -516,10 +594,10 @@
@Test
public void testPinEntry_logsPeek() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
// Needs full screen intent in order to be pinned
- final HeadsUpManager.HeadsUpEntry entryToPin = hum.new HeadsUpEntry();
+ final BaseHeadsUpManager.HeadsUpEntry entryToPin = hum.new HeadsUpEntry();
entryToPin.setEntry(createFullScreenIntentEntry(/* id = */ 0));
// Note: the standard way to show a notification would be calling showNotification rather
@@ -530,13 +608,13 @@
hum.onAlertEntryAdded(entryToPin);
assertEquals(1, mUiEventLoggerFake.numLogs());
- assertEquals(HeadsUpManager.NotificationPeekEvent.NOTIFICATION_PEEK.getId(),
+ assertEquals(BaseHeadsUpManager.NotificationPeekEvent.NOTIFICATION_PEEK.getId(),
mUiEventLoggerFake.eventId(0));
}
@Test
public void testSetUserActionMayIndirectlyRemove() {
- final HeadsUpManager hum = createHeadsUpManager();
+ final BaseHeadsUpManager hum = createHeadsUpManager();
final NotificationEntry notifEntry = createEntry(/* id = */ 0);
hum.showNotification(notifEntry);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
index af941d0..c56266d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/domain/interactor/UserInteractorTest.kt
@@ -155,6 +155,9 @@
@Test
fun createUserInteractor_nonProcessUser_startsSecondaryService() {
+ val userId = Process.myUserHandle().identifier + 1
+ whenever(manager.aliveUsers).thenReturn(listOf(createUserInfo(userId, "abc")))
+
createUserInteractor(false /* startAsProcessUser */)
verify(spyContext).startServiceAsUser(any(), any())
}
@@ -655,9 +658,10 @@
@Test
fun userSwitchedBroadcast() {
- createUserInteractor()
testScope.runTest {
val userInfos = createUserInfos(count = 2, includeGuest = false)
+ whenever(manager.aliveUsers).thenReturn(userInfos)
+ createUserInteractor()
userRepository.setUserInfos(userInfos)
userRepository.setSelectedUserInfo(userInfos[0])
userRepository.setSettings(UserSwitcherSettingsModel(isUserSwitcherEnabled = true))
@@ -728,6 +732,26 @@
}
@Test
+ fun localeChanged_refreshUsers() {
+ createUserInteractor()
+ testScope.runTest {
+ val userInfos = createUserInfos(count = 2, includeGuest = false)
+ userRepository.setUserInfos(userInfos)
+ userRepository.setSelectedUserInfo(userInfos[0])
+ runCurrent()
+ val refreshUsersCallCount = userRepository.refreshUsersCallCount
+
+ fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+ spyContext,
+ Intent(Intent.ACTION_LOCALE_CHANGED)
+ )
+ runCurrent()
+
+ assertThat(userRepository.refreshUsersCallCount).isEqualTo(refreshUsersCallCount + 1)
+ }
+ }
+
+ @Test
fun nonSystemUserUnlockedBroadcast_doNotRefreshUsers() {
createUserInteractor()
testScope.runTest {
@@ -985,6 +1009,13 @@
}
}
+ @Test
+ fun initWithNoAliveUsers() {
+ whenever(manager.aliveUsers).thenReturn(listOf())
+ createUserInteractor()
+ verify(spyContext, never()).startServiceAsUser(any(), any())
+ }
+
private fun assertUsers(
models: List<UserModel>?,
count: Int,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
index 6932f5e..c236b12 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/user/ui/viewmodel/UserSwitcherViewModelTest.kt
@@ -28,6 +28,7 @@
import com.android.systemui.GuestResumeSessionReceiver
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Text
+import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
@@ -347,6 +348,24 @@
}
@Test
+ fun isFinishRequested_finishesWhenUserButtonIsClicked() =
+ testScope.runTest {
+ setUsers(count = 2)
+ val isFinishRequested = mutableListOf<Boolean>()
+ val job =
+ launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
+
+ val userViewModels = collectLastValue(underTest.users)
+ assertThat(isFinishRequested.last()).isFalse()
+
+ userViewModels.invoke()?.firstOrNull()?.onClicked?.invoke()
+
+ assertThat(isFinishRequested.last()).isTrue()
+
+ job.cancel()
+ }
+
+ @Test
fun guestSelected_nameIsExitGuest() =
testScope.runTest {
val userInfos =
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/RoboPilotTest.java b/packages/SystemUI/tests/utils/src/com/android/systemui/RoboPilotTest.java
deleted file mode 100644
index 3fff136..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/RoboPilotTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2023 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;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Mark as tests for Robolectric pilot projects. The filter can better help grouping test results
- * that runs on CI
- */
-@Target({ElementType.METHOD, ElementType.TYPE})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface RoboPilotTest {
-}
diff --git a/packages/WallpaperBackup/Android.bp b/packages/WallpaperBackup/Android.bp
index 155dc1a..18f78314 100644
--- a/packages/WallpaperBackup/Android.bp
+++ b/packages/WallpaperBackup/Android.bp
@@ -49,7 +49,7 @@
"androidx.test.core",
"androidx.test.rules",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
resource_dirs: ["test/res"],
certificate: "platform",
diff --git a/packages/overlays/tests/Android.bp b/packages/overlays/tests/Android.bp
index b781602..0244c0f 100644
--- a/packages/overlays/tests/Android.bp
+++ b/packages/overlays/tests/Android.bp
@@ -34,7 +34,7 @@
"androidx.test.rules",
"androidx.test.espresso.core",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
dxflags: ["--multi-dex"],
}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 7e09b5e..258820a 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -24,6 +24,7 @@
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -1660,8 +1661,21 @@
synchronized (mLock) {
ensureGroupStateLoadedLocked(userId);
+ final String pkg = componentName.getPackageName();
+ final ProviderId id;
+ if (!mPackageManagerInternal.isSameApp(pkg, callingUid, userId)) {
+ // If the calling process is requesting to pin appwidgets from another process,
+ // check if the calling process has the necessary permission.
+ if (!injectHasAccessWidgetsPermission(Binder.getCallingPid(), callingUid)) {
+ return false;
+ }
+ id = new ProviderId(mPackageManagerInternal.getPackageUid(
+ pkg, 0 /* flags */, userId), componentName);
+ } else {
+ id = new ProviderId(callingUid, componentName);
+ }
// Look for the widget associated with the caller.
- Provider provider = lookupProviderLocked(new ProviderId(callingUid, componentName));
+ Provider provider = lookupProviderLocked(id);
if (provider == null || provider.zombie) {
return false;
}
@@ -1675,6 +1689,14 @@
.requestPinAppWidget(callingPackage, info, extras, resultSender, userId);
}
+ /**
+ * Returns true if the caller has the proper permission to access app widgets.
+ */
+ private boolean injectHasAccessWidgetsPermission(int callingPid, int callingUid) {
+ return mContext.checkPermission(Manifest.permission.CLEAR_APP_USER_DATA,
+ callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
+ }
+
@Override
public ParceledListSlice<AppWidgetProviderInfo> getInstalledProvidersForProfile(int categoryFilter,
int profileId, String packageName) {
@@ -4131,7 +4153,7 @@
return false;
}
- @GuardedBy("mLock")
+ @GuardedBy("AppWidgetServiceImpl.mLock")
public AppWidgetProviderInfo getInfoLocked(Context context) {
if (!mInfoParsed) {
// parse
@@ -4159,18 +4181,18 @@
* be completely parsed and only contain placeHolder information like
* {@link AppWidgetProviderInfo#providerInfo}
*/
- @GuardedBy("mLock")
+ @GuardedBy("AppWidgetServiceImpl.mLock")
public AppWidgetProviderInfo getPartialInfoLocked() {
return info;
}
- @GuardedBy("mLock")
+ @GuardedBy("AppWidgetServiceImpl.mLock")
public void setPartialInfoLocked(AppWidgetProviderInfo info) {
this.info = info;
mInfoParsed = false;
}
- @GuardedBy("mLock")
+ @GuardedBy("AppWidgetServiceImpl.mLock")
public void setInfoLocked(AppWidgetProviderInfo info) {
this.info = info;
mInfoParsed = true;
diff --git a/services/autofill/Android.bp b/services/autofill/Android.bp
index d43a219..eb23f2f 100644
--- a/services/autofill/Android.bp
+++ b/services/autofill/Android.bp
@@ -19,19 +19,4 @@
defaults: ["platform_service_defaults"],
srcs: [":services.autofill-sources"],
libs: ["services.core"],
- static_libs: ["autofill_flags_java_lib"],
-}
-
-aconfig_declarations {
- name: "autofill_flags",
- package: "android.service.autofill",
- srcs: [
- "bugfixes.aconfig",
- "features.aconfig",
- ],
-}
-
-java_aconfig_library {
- name: "autofill_flags_java_lib",
- aconfig_declarations: "autofill_flags",
}
diff --git a/services/autofill/bugfixes.aconfig b/services/autofill/bugfixes.aconfig
index ef23754..123b65c 100644
--- a/services/autofill/bugfixes.aconfig
+++ b/services/autofill/bugfixes.aconfig
@@ -5,4 +5,11 @@
namespace: "autofill"
description: "Test flag "
bug: "297380045"
-}
\ No newline at end of file
+}
+
+flag {
+ name: "relayout"
+ namespace: "autofill"
+ description: "Mitigation for relayout issue"
+ bug: "294330426"
+}
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index 9bab261..93dca2f 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -359,8 +359,10 @@
@Override
public void onChange(boolean selfChange, Uri uri) {
if (userSetupCompleteUri.equals(uri)) {
- sendPinAppMessage(KEY_HOME, ActivityManager.getCurrentUser(),
- true /* force */);
+ if (mConfiguredToPinHome) {
+ sendPinAppMessage(KEY_HOME, ActivityManager.getCurrentUser(),
+ true /* force */);
+ }
}
}
}, UserHandle.USER_ALL);
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 8cc2665..962f38f 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -214,6 +214,9 @@
// external storage service.
public static final int FAILED_MOUNT_RESET_TIMEOUT_SECONDS = 10;
+ /** Extended timeout for the system server watchdog. */
+ private static final int SLOW_OPERATION_WATCHDOG_TIMEOUT_MS = 60 * 1000;
+
@GuardedBy("mLock")
private final Set<Integer> mFuseMountedUser = new ArraySet<>();
@@ -1230,6 +1233,8 @@
private void onUserStopped(int userId) {
Slog.d(TAG, "onUserStopped " + userId);
+ Watchdog.getInstance().setOneOffTimeoutForMonitors(
+ SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#onUserStopped might be slow");
try {
mVold.onUserStopped(userId);
mStoraged.onUserStopped(userId);
@@ -1312,6 +1317,8 @@
unlockedUsers.add(userId);
}
}
+ Watchdog.getInstance().setOneOffTimeoutForMonitors(
+ SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#onUserStopped might be slow");
for (Integer userId : unlockedUsers) {
try {
mVold.onUserStopped(userId);
@@ -3600,6 +3607,8 @@
@Override
public ParcelFileDescriptor open() throws AppFuseMountException {
+ Watchdog.getInstance().setOneOffTimeoutForMonitors(
+ SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#open might be slow");
try {
final FileDescriptor fd = mVold.mountAppFuse(uid, mountId);
mMounted = true;
@@ -3612,6 +3621,8 @@
@Override
public ParcelFileDescriptor openFile(int mountId, int fileId, int flags)
throws AppFuseMountException {
+ Watchdog.getInstance().setOneOffTimeoutForMonitors(
+ SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#openFile might be slow");
try {
return new ParcelFileDescriptor(
mVold.openAppFuseFile(uid, mountId, fileId, flags));
@@ -3622,6 +3633,8 @@
@Override
public void close() throws Exception {
+ Watchdog.getInstance().setOneOffTimeoutForMonitors(
+ SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#close might be slow");
if (mMounted) {
mVold.unmountAppFuse(uid, mountId);
mMounted = false;
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index b05b397..55aa716 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -644,6 +644,16 @@
}
/**
+ * Sets a one-off timeout for the next run of the watchdog for the monitor thread.
+ *
+ * <p>Simiar to {@link setOneOffTimeoutForCurrentThread} but used for monitors added through
+ * {@link #addMonitor}
+ */
+ public void setOneOffTimeoutForMonitors(int oneOffTimeoutMillis, String reason) {
+ mMonitorChecker.setOneOffTimeoutLocked(oneOffTimeoutMillis, reason);
+ }
+
+ /**
* Pauses Watchdog action for the currently running thread. Useful before executing long running
* operations that could falsely trigger the watchdog. Each call to this will require a matching
* call to {@link #resumeWatchingCurrentThread}.
diff --git a/services/core/java/com/android/server/am/AnrTimer.java b/services/core/java/com/android/server/am/AnrTimer.java
index 378a386..9ba49ce 100644
--- a/services/core/java/com/android/server/am/AnrTimer.java
+++ b/services/core/java/com/android/server/am/AnrTimer.java
@@ -108,6 +108,14 @@
private static final boolean ENABLE_TRACING = false;
/**
+ * Return true if the feature is enabled. By default, the value is take from the Flags class
+ * but it can be changed for local testing.
+ */
+ private static boolean anrTimerServiceEnabled() {
+ return Flags.anrTimerServiceEnabled();
+ }
+
+ /**
* The status of an ANR timer. TIMER_INVALID status is returned when an error is detected.
*/
private static final int TIMER_INVALID = 0;
@@ -327,18 +335,33 @@
*/
@VisibleForTesting
static class Injector {
- /**
- * Return a handler for the given Callback.
- */
- Handler getHandler(@NonNull Handler.Callback callback) {
- return null;
- };
+ private final Handler mReferenceHandler;
+
+ Injector(@NonNull Handler handler) {
+ mReferenceHandler = handler;
+ }
/**
- * Return a CpuTracker.
+ * Return a handler for the given Callback, based on the reference handler. The handler
+ * might be mocked, in which case it does not have a valid Looper. In this case, use the
+ * main Looper.
*/
+ @NonNull
+ Handler getHandler(@NonNull Handler.Callback callback) {
+ Looper looper = mReferenceHandler.getLooper();
+ if (looper == null) looper = Looper.getMainLooper();
+ return new Handler(looper, callback);
+ };
+
+ /** Return a CpuTracker. */
+ @NonNull
CpuTracker getTracker() {
- return null;
+ return new CpuTracker();
+ }
+
+ /** Return true if the feature is enabled. */
+ boolean getFeatureEnabled() {
+ return anrTimerServiceEnabled();
}
}
@@ -375,12 +398,6 @@
/** The interface to fetch process statistics that might extend an ANR timeout. */
private final CpuTracker mCpu;
- /** Create a HandlerTimerService based on the input handler. */
- HandlerTimerService(@NonNull Handler handler) {
- mHandler = new Handler(handler.getLooper(), this::expires);
- mCpu = new CpuTracker();
- }
-
/** Create a HandlerTimerService that directly uses the supplied handler and tracker. */
@VisibleForTesting
HandlerTimerService(@NonNull Injector injector) {
@@ -491,38 +508,56 @@
private final boolean mLenientCancel = true;
/**
+ * The top-level switch for the feature enabled or disabled.
+ */
+ private final FeatureSwitch mFeature;
+
+ /**
* The common constructor. A null injector results in a normal, production timer.
*/
@VisibleForTesting
AnrTimer(@NonNull Handler handler, int what, @NonNull String label, boolean extend,
- @Nullable Injector injector) {
+ @NonNull Injector injector) {
mHandler = handler;
mWhat = what;
mLabel = label;
mExtend = extend;
- if (injector == null) {
- mTimerService = new HandlerTimerService(handler);
+ boolean enabled = injector.getFeatureEnabled();
+ if (!enabled) {
+ mFeature = new FeatureDisabled();
+ mTimerService = null;
} else {
+ mFeature = new FeatureEnabled();
mTimerService = new HandlerTimerService(injector);
+
+ synchronized (sAnrTimerList) {
+ sAnrTimerList.add(new WeakReference(this));
+ }
}
- synchronized (sAnrTimerList) {
- sAnrTimerList.add(new WeakReference(this));
- }
- Log.i(TAG, formatSimple("created %s label: \"%s\"", mTimerService.toString(), label));
+ Log.i(TAG, formatSimple("created %s label: \"%s\"", mTimerService, label));
}
/**
* Create one timer instance for production. The client can ask for extensible timeouts.
*/
AnrTimer(@NonNull Handler handler, int what, @NonNull String label, boolean extend) {
- this(handler, what, label, extend, null);
+ this(handler, what, label, extend, new Injector(handler));
}
/**
* Create one timer instance for production. There are no extensible timeouts.
*/
AnrTimer(@NonNull Handler handler, int what, @NonNull String label) {
- this(handler, what, label, false, null);
+ this(handler, what, label, false);
+ }
+
+ /**
+ * Return true if the service is enabled on this instance. Clients should use this method to
+ * decide if the feature is enabled, and not read the flags directly. This method should be
+ * deleted if and when the feature is enabled permanently.
+ */
+ boolean serviceEnabled() {
+ return mFeature.enabled();
}
/**
@@ -613,93 +648,186 @@
Log.i(TAG, msg + " " + timer + " " + Objects.toString(timer.arg));
}
- /**
- * Start a timer.
+ /**
+ * The FeatureSwitch class provides a quick switch between feature-enabled behavior and
+ * feature-disabled behavior.
*/
- boolean start(@NonNull V arg, int pid, int uid, long timeoutMs) {
- final Timer timer = Timer.obtain(pid, uid, arg, timeoutMs, this);
- synchronized (mLock) {
- Timer old = mTimerMap.get(arg);
- if (old != null) {
- // There is an existing timer. This is a protocol error in the client. Record
- // the error and then clean up by canceling running timers and discarding expired
- // timers.
- restartedLocked(old.status, arg);
- if (old.status == TIMER_EXPIRED) {
- discard(arg);
+ private abstract class FeatureSwitch {
+ abstract boolean start(@NonNull V arg, int pid, int uid, long timeoutMs);
+ abstract boolean cancel(@NonNull V arg);
+ abstract boolean accept(@NonNull V arg);
+ abstract boolean discard(@NonNull V arg);
+ abstract boolean enabled();
+ }
+
+ /**
+ * The FeatureDisabled class bypasses almost all AnrTimer logic. It is used when the AnrTimer
+ * service is disabled via Flags.anrTimerServiceEnabled.
+ */
+ private class FeatureDisabled extends FeatureSwitch {
+ /** Start a timer by sending a message to the client's handler. */
+ boolean start(@NonNull V arg, int pid, int uid, long timeoutMs) {
+ final Message msg = mHandler.obtainMessage(mWhat, arg);
+ mHandler.sendMessageDelayed(msg, timeoutMs);
+ return true;
+ }
+
+ /** Cancel a timer by removing the message from the client's handler. */
+ boolean cancel(@NonNull V arg) {
+ mHandler.removeMessages(mWhat, arg);
+ return true;
+ }
+
+ /** accept() is a no-op when the feature is disabled. */
+ boolean accept(@NonNull V arg) {
+ return true;
+ }
+
+ /** discard() is a no-op when the feature is disabled. */
+ boolean discard(@NonNull V arg) {
+ return true;
+ }
+
+ /** The feature is not enabled. */
+ boolean enabled() {
+ return false;
+ }
+ }
+
+ /**
+ * The FeatureEnabled class enables the AnrTimer logic. It is used when the AnrTimer service
+ * is enabled via Flags.anrTimerServiceEnabled.
+ */
+ private class FeatureEnabled extends FeatureSwitch {
+
+ /**
+ * Start a timer.
+ */
+ boolean start(@NonNull V arg, int pid, int uid, long timeoutMs) {
+ final Timer timer = Timer.obtain(pid, uid, arg, timeoutMs, AnrTimer.this);
+ synchronized (mLock) {
+ Timer old = mTimerMap.get(arg);
+ if (old != null) {
+ // There is an existing timer. This is a protocol error in the client.
+ // Record the error and then clean up by canceling running timers and
+ // discarding expired timers.
+ restartedLocked(old.status, arg);
+ if (old.status == TIMER_EXPIRED) {
+ discard(arg);
+ } else {
+ cancel(arg);
+ }
+ }
+ if (mTimerService.start(timer)) {
+ timer.status = TIMER_RUNNING;
+ mTimerMap.put(arg, timer);
+ mTotalStarted++;
+ mMaxStarted = Math.max(mMaxStarted, mTimerMap.size());
+ if (DEBUG) report(timer, "start");
+ return true;
} else {
- cancel(arg);
+ Log.e(TAG, "AnrTimer.start failed");
+ return false;
}
}
- if (mTimerService.start(timer)) {
- timer.status = TIMER_RUNNING;
- mTimerMap.put(arg, timer);
- mTotalStarted++;
- mMaxStarted = Math.max(mMaxStarted, mTimerMap.size());
- if (DEBUG) report(timer, "start");
+ }
+
+ /**
+ * Cancel a timer. Return false if the timer was not found.
+ */
+ boolean cancel(@NonNull V arg) {
+ synchronized (mLock) {
+ Timer timer = removeLocked(arg);
+ if (timer == null) {
+ if (!mLenientCancel) notFoundLocked("cancel", arg);
+ return false;
+ }
+ mTimerService.cancel(timer);
+ // There may be an expiration message in flight. Cancel it.
+ mHandler.removeMessages(mWhat, arg);
+ if (DEBUG) report(timer, "cancel");
+ timer.release();
return true;
- } else {
- Log.e(TAG, "AnrTimer.start failed");
- return false;
}
}
+
+ /**
+ * Accept a timer in the framework-level handler. The timeout has been accepted and the
+ * timeout handler is executing. Return false if the timer was not found.
+ */
+ boolean accept(@NonNull V arg) {
+ synchronized (mLock) {
+ Timer timer = removeLocked(arg);
+ if (timer == null) {
+ notFoundLocked("accept", arg);
+ return false;
+ }
+ mTimerService.accept(timer);
+ traceEnd(timer);
+ if (DEBUG) report(timer, "accept");
+ timer.release();
+ return true;
+ }
+ }
+
+ /**
+ * Discard a timer in the framework-level handler. For whatever reason, the timer is no
+ * longer interesting. No statistics are collected. Return false if the time was not
+ * found.
+ */
+ boolean discard(@NonNull V arg) {
+ synchronized (mLock) {
+ Timer timer = removeLocked(arg);
+ if (timer == null) {
+ notFoundLocked("discard", arg);
+ return false;
+ }
+ mTimerService.discard(timer);
+ traceEnd(timer);
+ if (DEBUG) report(timer, "discard");
+ timer.release();
+ return true;
+ }
+ }
+
+ /** The feature is enabled. */
+ boolean enabled() {
+ return true;
+ }
}
/**
- * Cancel a timer. Return false if the timer was not found.
+ * Start a timer associated with arg. If a timer already exists with the same arg, then that
+ * timer is canceled and a new timer is created. This returns false if the timer cannot be
+ * created.
+ */
+ boolean start(@NonNull V arg, int pid, int uid, long timeoutMs) {
+ return mFeature.start(arg, pid, uid, timeoutMs);
+ }
+
+ /**
+ * Cancel a running timer and remove it from any list. This returns true if the timer was
+ * found and false otherwise. It is not an error to cancel a non-existent timer. It is also
+ * not an error to cancel an expired timer.
*/
boolean cancel(@NonNull V arg) {
- synchronized (mLock) {
- Timer timer = removeLocked(arg);
- if (timer == null) {
- if (!mLenientCancel) notFoundLocked("cancel", arg);
- return false;
- }
- mTimerService.cancel(timer);
- // There may be an expiration message in flight. Cancel it.
- mHandler.removeMessages(mWhat, arg);
- if (DEBUG) report(timer, "cancel");
- timer.release();
- return true;
- }
+ return mFeature.cancel(arg);
}
/**
- * Accept a timer in the framework-level handler. The timeout has been accepted and the
- * timeout handler is executing. Return false if the timer was not found.
+ * Accept an expired timer. This returns false if the timer was not found or if the timer was
+ * not expired.
*/
boolean accept(@NonNull V arg) {
- synchronized (mLock) {
- Timer timer = removeLocked(arg);
- if (timer == null) {
- notFoundLocked("accept", arg);
- return false;
- }
- mTimerService.accept(timer);
- traceEnd(timer);
- if (DEBUG) report(timer, "accept");
- timer.release();
- return true;
- }
+ return mFeature.accept(arg);
}
/**
- * Discard a timer in the framework-level handler. For whatever reason, the timer is no
- * longer interesting. No statistics are collected. Return false if the time was not found.
+ * Discard an expired timer. This returns false if the timer was not found or if the timer was
+ * not expired.
*/
boolean discard(@NonNull V arg) {
- synchronized (mLock) {
- Timer timer = removeLocked(arg);
- if (timer == null) {
- notFoundLocked("discard", arg);
- return false;
- }
- mTimerService.discard(timer);
- traceEnd(timer);
- if (DEBUG) report(timer, "discard");
- timer.release();
- return true;
- }
+ return mFeature.discard(arg);
}
/**
diff --git a/services/core/java/com/android/server/am/AppBatteryTracker.java b/services/core/java/com/android/server/am/AppBatteryTracker.java
index 907069d..147f8d1 100644
--- a/services/core/java/com/android/server/am/AppBatteryTracker.java
+++ b/services/core/java/com/android/server/am/AppBatteryTracker.java
@@ -580,7 +580,11 @@
batteryStatsInternal);
curDuration += curStart - lastUidBatteryUsageStartTs;
try {
- statsCommit.close();
+ if (statsCommit != null) {
+ statsCommit.close();
+ } else {
+ Slog.w(TAG, "Stat was null");
+ }
} catch (IOException e) {
Slog.w(TAG, "Failed to close a stat");
}
@@ -660,7 +664,11 @@
}
}
try {
- stats.close();
+ if (stats != null) {
+ stats.close();
+ } else {
+ Slog.w(TAG, "Stat was null");
+ }
} catch (IOException e) {
Slog.w(TAG, "Failed to close a stat");
}
@@ -684,7 +692,11 @@
final BatteryUsageStats stats = statsList.get(0);
for (int i = 1; i < statsList.size(); i++) {
try {
- statsList.get(i).close();
+ if (statsList.get(i) != null) {
+ statsList.get(i).close();
+ } else {
+ Slog.w(TAG, "Stat was null");
+ }
} catch (IOException e) {
Slog.w(TAG, "Failed to close a stat in BatteryUsageStats List");
}
diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
index 5d31d15..e07c2bc 100644
--- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
@@ -106,6 +106,14 @@
private boolean mTimeoutScheduled;
/**
+ * Snapshotted value of {@link ProcessRecord#getCpuDelayTime()}, typically
+ * used when deciding if we should extend the soft ANR timeout.
+ *
+ * Required when Flags.anrTimerServiceEnabled is false.
+ */
+ long lastCpuDelayTime;
+
+ /**
* Snapshotted value of {@link ProcessStateRecord#getCurProcState()} before
* dispatching the current broadcast to the receiver in this process.
*/
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index eb219a8..a428907 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -258,6 +258,9 @@
private static final int MSG_PROCESS_FREEZABLE_CHANGED = 6;
private static final int MSG_UID_STATE_CHANGED = 7;
+ // Required when Flags.anrTimerServiceEnabled is false.
+ private static final int MSG_DELIVERY_TIMEOUT_SOFT = 8;
+
private void enqueueUpdateRunningList() {
mLocalHandler.removeMessages(MSG_UPDATE_RUNNING_LIST);
mLocalHandler.sendEmptyMessage(MSG_UPDATE_RUNNING_LIST);
@@ -271,6 +274,13 @@
updateRunningList();
return true;
}
+ // Required when Flags.anrTimerServiceEnabled is false.
+ case MSG_DELIVERY_TIMEOUT_SOFT: {
+ synchronized (mService) {
+ deliveryTimeoutSoftLocked((BroadcastProcessQueue) msg.obj, msg.arg1);
+ return true;
+ }
+ }
case MSG_DELIVERY_TIMEOUT: {
deliveryTimeout((BroadcastProcessQueue) msg.obj);
return true;
@@ -1030,7 +1040,7 @@
queue.setTimeoutScheduled(true);
final int softTimeoutMillis = (int) (r.isForeground() ? mFgConstants.TIMEOUT
: mBgConstants.TIMEOUT);
- mAnrTimer.start(queue, softTimeoutMillis);
+ startDeliveryTimeoutLocked(queue, softTimeoutMillis);
} else {
queue.setTimeoutScheduled(false);
}
@@ -1110,7 +1120,7 @@
// If we were trying to deliver a manifest broadcast, throw the error as we need
// to try redelivering the broadcast to this receiver.
if (receiver instanceof ResolveInfo) {
- mAnrTimer.cancel(queue);
+ cancelDeliveryTimeoutLocked(queue);
throw new BroadcastDeliveryFailedException(e);
}
finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_FAILURE,
@@ -1159,6 +1169,41 @@
r.resultTo = null;
}
+ // Required when Flags.anrTimerServiceEnabled is false.
+ private void startDeliveryTimeoutLocked(@NonNull BroadcastProcessQueue queue,
+ int softTimeoutMillis) {
+ if (mAnrTimer.serviceEnabled()) {
+ mAnrTimer.start(queue, softTimeoutMillis);
+ } else {
+ queue.lastCpuDelayTime = queue.app.getCpuDelayTime();
+ mLocalHandler.sendMessageDelayed(Message.obtain(mLocalHandler,
+ MSG_DELIVERY_TIMEOUT_SOFT, softTimeoutMillis, 0, queue), softTimeoutMillis);
+ }
+ }
+
+ // Required when Flags.anrTimerServiceEnabled is false.
+ private void cancelDeliveryTimeoutLocked(@NonNull BroadcastProcessQueue queue) {
+ mAnrTimer.cancel(queue);
+ if (!mAnrTimer.serviceEnabled()) {
+ mLocalHandler.removeMessages(MSG_DELIVERY_TIMEOUT_SOFT, queue);
+ }
+ }
+
+ // Required when Flags.anrTimerServiceEnabled is false.
+ private void deliveryTimeoutSoftLocked(@NonNull BroadcastProcessQueue queue,
+ int softTimeoutMillis) {
+ if (queue.app != null) {
+ // Instead of immediately triggering an ANR, extend the timeout by
+ // the amount of time the process was runnable-but-waiting; we're
+ // only willing to do this once before triggering an hard ANR
+ final long cpuDelayTime = queue.app.getCpuDelayTime() - queue.lastCpuDelayTime;
+ final long hardTimeoutMillis = MathUtils.constrain(cpuDelayTime, 0, softTimeoutMillis);
+ mAnrTimer.start(queue, hardTimeoutMillis);
+ } else {
+ deliveryTimeoutLocked(queue);
+ }
+ }
+
private void deliveryTimeout(@NonNull BroadcastProcessQueue queue) {
synchronized (mService) {
deliveryTimeoutLocked(queue);
@@ -1292,7 +1337,7 @@
mAnrTimer.discard(queue);
}
} else if (queue.timeoutScheduled()) {
- mAnrTimer.cancel(queue);
+ cancelDeliveryTimeoutLocked(queue);
}
// Given that a receiver just finished, check if the "waitingFor" conditions are met.
diff --git a/services/core/java/com/android/server/am/OomConnection.java b/services/core/java/com/android/server/am/OomConnection.java
new file mode 100644
index 0000000..17a4ce5
--- /dev/null
+++ b/services/core/java/com/android/server/am/OomConnection.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2023 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.am;
+
+import android.os.OomKillRecord;
+import android.util.Slog;
+
+/** Connection to the out-of-memory (OOM) events' file */
+public final class OomConnection {
+ private static final String TAG = "OomConnection";
+
+ /** Connection listener interface */
+ public interface OomConnectionListener {
+
+ /**
+ * Callback function to handle the newest OOM kills.
+ *
+ * @param oomKills List of oom kills received from `waitOom()`
+ */
+ void handleOomEvent(OomKillRecord[] oomKills);
+ }
+
+ private final OomConnectionListener mOomListener;
+
+ private final OomConnectionThread mOomConnectionThread;
+
+ private static native OomKillRecord[] waitOom();
+
+ public OomConnection(OomConnectionListener listener) {
+ mOomListener = listener;
+ mOomConnectionThread = new OomConnectionThread();
+ mOomConnectionThread.start();
+ }
+
+ private final class OomConnectionThread extends Thread {
+ public void run() {
+ while (true) {
+ OomKillRecord[] oom_kills = null;
+ try {
+ oom_kills = waitOom();
+ mOomListener.handleOomEvent(oom_kills);
+ } catch (RuntimeException e) {
+ Slog.e(TAG, "failed waiting for OOM events: " + e);
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index a97675f..4572766 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -97,6 +97,7 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.OomKillRecord;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteCallbackList;
@@ -412,6 +413,8 @@
private static LmkdConnection sLmkdConnection = null;
+ private static OomConnection sOomConnection = null;
+
private boolean mOomLevelsSet = false;
private boolean mAppDataIsolationEnabled = false;
@@ -855,6 +858,21 @@
THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
sKillThread.start();
sKillHandler = new KillHandler(sKillThread.getLooper());
+ sOomConnection = new OomConnection(new OomConnection.OomConnectionListener() {
+ @Override
+ public void handleOomEvent(OomKillRecord[] oomKills) {
+ for (OomKillRecord oomKill: oomKills) {
+ synchronized (mProcLock) {
+ noteAppKill(
+ oomKill.getPid(),
+ oomKill.getUid(),
+ ApplicationExitInfo.REASON_LOW_MEMORY,
+ ApplicationExitInfo.SUBREASON_OOM_KILL,
+ "oom");
+ }
+ }
+ }
+ });
sLmkdConnection = new LmkdConnection(sKillThread.getLooper().getQueue(),
new LmkdConnection.LmkdConnectionListener() {
@Override
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 4a0bc4b..1ba1f55 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -131,13 +131,17 @@
"car_telemetry",
"codec_fwk",
"companion",
+ "content_protection",
"context_hub",
"core_experiments_team_internal",
"core_graphics",
"haptics",
"hardware_backed_security_mainline",
+ "input",
"machine_learning",
+ "mainline_sdk",
"media_audio",
+ "media_drm",
"media_solutions",
"nfc",
"pixel_audio_android",
diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig
index b03cc62..26d99d8 100644
--- a/services/core/java/com/android/server/am/flags.aconfig
+++ b/services/core/java/com/android/server/am/flags.aconfig
@@ -6,4 +6,12 @@
description: "Utilize new OomAdjuster implementation"
bug: "298055811"
is_fixed_read_only: true
-}
\ No newline at end of file
+}
+
+flag {
+ name: "anr_timer_service_enabled"
+ namespace: "system_performance"
+ is_fixed_read_only: true
+ description: "Feature flag for the ANR timer service"
+ bug: "282428924"
+}
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index 9805fd3..333f62a 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -1845,7 +1845,7 @@
private void parseListenForTickles(TypedXmlPullParser parser) {
int userId = 0;
try {
- parser.getAttributeInt(null, XML_ATTR_USER);
+ userId = parser.getAttributeInt(null, XML_ATTR_USER);
} catch (XmlPullParserException e) {
Slog.e(TAG, "error parsing the user for listen-for-tickles", e);
}
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 9e92c8d..cfbe0c6 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -60,6 +60,9 @@
import com.android.server.display.config.NitsMap;
import com.android.server.display.config.NonNegativeFloatToFloatPoint;
import com.android.server.display.config.Point;
+import com.android.server.display.config.PowerThrottlingConfig;
+import com.android.server.display.config.PowerThrottlingMap;
+import com.android.server.display.config.PowerThrottlingPoint;
import com.android.server.display.config.PredefinedBrightnessLimitNames;
import com.android.server.display.config.RefreshRateConfigs;
import com.android.server.display.config.RefreshRateRange;
@@ -139,6 +142,30 @@
* </screenBrightnessMap>
*
* <screenBrightnessDefault>0.65</screenBrightnessDefault>
+ * <powerThrottlingConfig>
+ * <brightnessLowestCapAllowed>0.1</brightnessLowestCapAllowed>
+ * <pollingWindowMillis>15</pollingWindowMillis>
+ * <powerThrottlingMap>
+ * <powerThrottlingPoint>
+ * <thermalStatus>severe</thermalStatus>
+ * <powerQuotaMilliWatts>200.6</powerQuotaMilliWatts>
+ * </powerThrottlingPoint>
+ * <powerThrottlingPoint>
+ * <thermalStatus>critical</thermalStatus>
+ * <powerQuotaMilliWatts>300</powerQuotaMilliWatts>
+ * </powerThrottlingPoint>
+ * </powerThrottlingMap>
+ * <powerThrottlingMap id="id_2"> // optional attribute, leave blank for default
+ * <powerThrottlingPoint>
+ * <thermalStatus>moderate</thermalStatus>
+ * <powerQuotaMilliWatts>400</powerQuotaMilliWatts>
+ * </powerThrottlingPoint>
+ * <powerThrottlingPoint>
+ * <thermalStatus>severe</thermalStatus>
+ * <powerQuotaMilliWatts>250</powerQuotaMilliWatts>
+ * </powerThrottlingPoint>
+ * </powerThrottlingMap>
+ * </powerThrottlingConfig>
*
* <thermalThrottling>
* <brightnessThrottlingMap>
@@ -669,6 +696,8 @@
private List<String> mQuirks;
private boolean mIsHighBrightnessModeEnabled = false;
private HighBrightnessModeData mHbmData;
+ @Nullable
+ private PowerThrottlingConfigData mPowerThrottlingConfigData;
private DensityMapping mDensityMapping;
private String mLoadedFrom = null;
private Spline mSdrToHdrRatioSpline;
@@ -781,6 +810,9 @@
private final HashMap<String, ThermalBrightnessThrottlingData>
mThermalBrightnessThrottlingDataMapByThrottlingId = new HashMap<>();
+ private final HashMap<String, PowerThrottlingData>
+ mPowerThrottlingDataMapByThrottlingId = new HashMap<>();
+
private final Map<String, SparseArray<SurfaceControl.RefreshRateRange>>
mRefreshRateThrottlingMap = new HashMap<>();
@@ -1458,6 +1490,14 @@
return hbmData;
}
+ /**
+ * @return Power throttling configuration data for the display.
+ */
+ @Nullable
+ public PowerThrottlingConfigData getPowerThrottlingConfigData() {
+ return mPowerThrottlingConfigData;
+ }
+
@NonNull
public Map<BrightnessLimitMapType, Map<Float, Float>> getLuxThrottlingData() {
return mLuxThrottlingData;
@@ -1491,6 +1531,14 @@
}
/**
+ * @return power throttling configuration data for this display, for each throttling id.
+ **/
+ public HashMap<String, PowerThrottlingData>
+ getPowerThrottlingDataMapByThrottlingId() {
+ return mPowerThrottlingDataMapByThrottlingId;
+ }
+
+ /**
* @return Auto brightness darkening light debounce
*/
public long getAutoBrightnessDarkeningLightDebounce() {
@@ -1702,6 +1750,9 @@
+ ", mThermalBrightnessThrottlingDataMapByThrottlingId="
+ mThermalBrightnessThrottlingDataMapByThrottlingId
+ "\n"
+ + ", mPowerThrottlingDataMapByThrottlingId="
+ + mPowerThrottlingDataMapByThrottlingId
+ + "\n"
+ "mBrightnessRampFastDecrease=" + mBrightnessRampFastDecrease
+ ", mBrightnessRampFastIncrease=" + mBrightnessRampFastIncrease
+ ", mBrightnessRampSlowDecrease=" + mBrightnessRampSlowDecrease
@@ -1853,6 +1904,7 @@
loadBrightnessConstraintsFromConfigXml();
loadBrightnessMap(config);
loadThermalThrottlingConfig(config);
+ loadPowerThrottlingConfigData(config);
loadHighBrightnessModeData(config);
loadLuxThrottling(config);
loadQuirks(config);
@@ -2171,6 +2223,59 @@
}
}
+ private boolean loadPowerThrottlingMaps(PowerThrottlingConfig throttlingConfig) {
+ final List<PowerThrottlingMap> maps = throttlingConfig.getPowerThrottlingMap();
+ if (maps == null || maps.isEmpty()) {
+ Slog.i(TAG, "No power throttling map found");
+ return false;
+ }
+
+ for (PowerThrottlingMap map : maps) {
+ final List<PowerThrottlingPoint> points = map.getPowerThrottlingPoint();
+ // At least 1 point is guaranteed by the display device config schema
+ List<PowerThrottlingData.ThrottlingLevel> throttlingLevels =
+ new ArrayList<>(points.size());
+
+ boolean badConfig = false;
+ for (PowerThrottlingPoint point : points) {
+ ThermalStatus status = point.getThermalStatus();
+ if (!thermalStatusIsValid(status)) {
+ badConfig = true;
+ break;
+ }
+
+ throttlingLevels.add(new PowerThrottlingData.ThrottlingLevel(
+ convertThermalStatus(status),
+ point.getPowerQuotaMilliWatts().floatValue()));
+ }
+
+ if (!badConfig) {
+ String id = map.getId() == null ? DEFAULT_ID : map.getId();
+ if (mPowerThrottlingDataMapByThrottlingId.containsKey(id)) {
+ throw new RuntimeException("Power throttling data with ID " + id
+ + " already exists");
+ }
+ mPowerThrottlingDataMapByThrottlingId.put(id,
+ PowerThrottlingData.create(throttlingLevels));
+ }
+ }
+ return true;
+ }
+
+ private void loadPowerThrottlingConfigData(DisplayConfiguration config) {
+ final PowerThrottlingConfig powerThrottlingCfg = config.getPowerThrottlingConfig();
+ if (powerThrottlingCfg == null) {
+ return;
+ }
+ if (!loadPowerThrottlingMaps(powerThrottlingCfg)) {
+ return;
+ }
+ float lowestBrightnessCap = powerThrottlingCfg.getBrightnessLowestCapAllowed().floatValue();
+ int pollingWindowMillis = powerThrottlingCfg.getPollingWindowMillis().intValue();
+ mPowerThrottlingConfigData = new PowerThrottlingConfigData(lowestBrightnessCap,
+ pollingWindowMillis);
+ }
+
private void loadRefreshRateSetting(DisplayConfiguration config) {
final RefreshRateConfigs refreshRateConfigs =
(config == null) ? null : config.getRefreshRate();
@@ -3379,6 +3484,148 @@
}
/**
+ * Container for Power throttling configuration data.
+ * TODO(b/302814899): extract to separate class.
+ */
+ public static class PowerThrottlingConfigData {
+ /** Lowest brightness cap allowed for this device. */
+ public final float brightnessLowestCapAllowed;
+ /** Time window for polling power in seconds. */
+ public final int pollingWindowMillis;
+ public PowerThrottlingConfigData(float brightnessLowestCapAllowed,
+ int pollingWindowMillis) {
+ this.brightnessLowestCapAllowed = brightnessLowestCapAllowed;
+ this.pollingWindowMillis = pollingWindowMillis;
+ }
+
+ @Override
+ public String toString() {
+ return "PowerThrottlingConfigData{"
+ + "brightnessLowestCapAllowed: "
+ + brightnessLowestCapAllowed
+ + ", pollingWindowMillis: " + pollingWindowMillis
+ + "} ";
+ }
+ }
+
+ /**
+ * Container for power throttling data.
+ * TODO(b/302814899): extract to separate class and unify with ThermalBrightnessThrottlingData.
+ */
+ public static class PowerThrottlingData {
+ public List<ThrottlingLevel> throttlingLevels;
+
+ /**
+ * thermal status to power quota mapping.
+ */
+ public static class ThrottlingLevel {
+ public @PowerManager.ThermalStatus int thermalStatus;
+ public float powerQuotaMilliWatts;
+
+ public ThrottlingLevel(
+ @PowerManager.ThermalStatus int thermalStatus, float powerQuotaMilliWatts) {
+ this.thermalStatus = thermalStatus;
+ this.powerQuotaMilliWatts = powerQuotaMilliWatts;
+ }
+
+ @Override
+ public String toString() {
+ return "[" + thermalStatus + "," + powerQuotaMilliWatts + "]";
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ThrottlingLevel)) {
+ return false;
+ }
+ ThrottlingLevel otherThrottlingLevel = (ThrottlingLevel) obj;
+
+ return otherThrottlingLevel.thermalStatus == this.thermalStatus
+ && otherThrottlingLevel.powerQuotaMilliWatts == this.powerQuotaMilliWatts;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 1;
+ result = 31 * result + thermalStatus;
+ result = 31 * result + Float.hashCode(powerQuotaMilliWatts);
+ return result;
+ }
+ }
+
+
+ /**
+ * Creates multiple temperature based throttling levels of power quota.
+ */
+ public static PowerThrottlingData create(
+ List<ThrottlingLevel> throttlingLevels) {
+ if (throttlingLevels == null || throttlingLevels.size() == 0) {
+ Slog.e(TAG, "PowerThrottlingData received null or empty throttling levels");
+ return null;
+ }
+
+ ThrottlingLevel prevLevel = throttlingLevels.get(0);
+ final int numLevels = throttlingLevels.size();
+ for (int i = 1; i < numLevels; i++) {
+ ThrottlingLevel thisLevel = throttlingLevels.get(i);
+
+ if (thisLevel.thermalStatus <= prevLevel.thermalStatus) {
+ Slog.e(TAG, "powerThrottlingMap must be strictly increasing, ignoring "
+ + "configuration. ThermalStatus " + thisLevel.thermalStatus + " <= "
+ + prevLevel.thermalStatus);
+ return null;
+ }
+
+ if (thisLevel.powerQuotaMilliWatts >= prevLevel.powerQuotaMilliWatts) {
+ Slog.e(TAG, "powerThrottlingMap must be strictly decreasing, ignoring "
+ + "configuration. powerQuotaMilliWatts "
+ + thisLevel.powerQuotaMilliWatts + " >= "
+ + prevLevel.powerQuotaMilliWatts);
+ return null;
+ }
+
+ prevLevel = thisLevel;
+ }
+ return new PowerThrottlingData(throttlingLevels);
+ }
+
+ @Override
+ public String toString() {
+ return "PowerThrottlingData{"
+ + "throttlingLevels:" + throttlingLevels
+ + "} ";
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (!(obj instanceof PowerThrottlingData)) {
+ return false;
+ }
+
+ PowerThrottlingData otherData = (PowerThrottlingData) obj;
+ return throttlingLevels.equals(otherData.throttlingLevels);
+ }
+
+ @Override
+ public int hashCode() {
+ return throttlingLevels.hashCode();
+ }
+
+ @VisibleForTesting
+ PowerThrottlingData(List<ThrottlingLevel> inLevels) {
+ throttlingLevels = new ArrayList<>(inLevels.size());
+ for (ThrottlingLevel level : inLevels) {
+ throttlingLevels.add(new ThrottlingLevel(level.thermalStatus,
+ level.powerQuotaMilliWatts));
+ }
+ }
+ }
+
+ /**
* Container for brightness throttling data.
*/
public static class ThermalBrightnessThrottlingData {
diff --git a/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
index 652e6cf..39f0b13 100644
--- a/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
+++ b/services/core/java/com/android/server/display/brightness/clamper/HdrClamper.java
@@ -105,16 +105,21 @@
public void resetHdrConfig(HdrBrightnessData data, int width, int height,
float minimumHdrPercentOfScreen, IBinder displayToken) {
mHdrBrightnessData = data;
- mHdrListener.mHdrMinPixels = (float) (width * height) * minimumHdrPercentOfScreen;
+ mHdrListener.mHdrMinPixels = minimumHdrPercentOfScreen <= 0 ? -1
+ : (float) (width * height) * minimumHdrPercentOfScreen;
if (displayToken != mRegisteredDisplayToken) { // token changed, resubscribe
if (mRegisteredDisplayToken != null) { // previous token not null, unsubscribe
mHdrListener.unregister(mRegisteredDisplayToken);
mHdrVisible = false;
+ mRegisteredDisplayToken = null;
}
- if (displayToken != null) { // new token not null, subscribe
+ // new token not null and hdr min % of the screen is set, subscribe.
+ // e.g. for virtual display, HBM data will be missing and HdrListener
+ // should not be registered
+ if (displayToken != null && mHdrListener.mHdrMinPixels > 0) {
mHdrListener.register(displayToken);
+ mRegisteredDisplayToken = displayToken;
}
- mRegisteredDisplayToken = displayToken;
}
recalculateBrightnessCap(data, mAmbientLux, mHdrVisible);
}
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index b6273e1..e66fa5b 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -51,22 +51,10 @@
Flags.FLAG_ENABLE_DISPLAY_OFFLOAD,
Flags::enableDisplayOffload);
- private final FlagState mDisplayResolutionRangeVotingState = new FlagState(
- Flags.FLAG_ENABLE_DISPLAY_RESOLUTION_RANGE_VOTING,
- Flags::enableDisplayResolutionRangeVoting);
-
- private final FlagState mUserPreferredModeVoteState = new FlagState(
- Flags.FLAG_ENABLE_USER_PREFERRED_MODE_VOTE,
- Flags::enableUserPreferredModeVote);
-
private final FlagState mExternalDisplayLimitModeState = new FlagState(
Flags.FLAG_ENABLE_MODE_LIMIT_FOR_EXTERNAL_DISPLAY,
Flags::enableModeLimitForExternalDisplay);
- private final FlagState mDisplaysRefreshRatesSynchronizationState = new FlagState(
- Flags.FLAG_ENABLE_DISPLAYS_REFRESH_RATES_SYNCHRONIZATION,
- Flags::enableDisplaysRefreshRatesSynchronization);
-
/** Returns whether connected display management is enabled or not. */
public boolean isConnectedDisplayManagementEnabled() {
return mConnectedDisplayManagementFlagState.isEnabled();
@@ -90,7 +78,7 @@
/** Returns whether resolution range voting feature is enabled or not. */
public boolean isDisplayResolutionRangeVotingEnabled() {
- return mDisplayResolutionRangeVotingState.isEnabled();
+ return isExternalDisplayLimitModeEnabled();
}
/**
@@ -98,7 +86,7 @@
* {@link com.android.server.display.mode.DisplayModeDirector}
*/
public boolean isUserPreferredModeVoteEnabled() {
- return mUserPreferredModeVoteState.isEnabled();
+ return isExternalDisplayLimitModeEnabled();
}
/**
@@ -112,7 +100,7 @@
* @return Whether displays refresh rate synchronization is enabled.
*/
public boolean isDisplaysRefreshRatesSynchronizationEnabled() {
- return mDisplaysRefreshRatesSynchronizationState.isEnabled();
+ return isExternalDisplayLimitModeEnabled();
}
/** Returns whether displayoffload is enabled on not */
@@ -150,19 +138,20 @@
}
private boolean flagOrSystemProperty(Supplier<Boolean> flagFunction, String flagName) {
- // TODO(b/299462337) Remove when the infrastructure is ready.
- if ((Build.IS_ENG || Build.IS_USERDEBUG)
- && SystemProperties.getBoolean("persist.sys." + flagName, false)) {
- return true;
- }
+ boolean flagValue = false;
try {
- return flagFunction.get();
+ flagValue = flagFunction.get();
} catch (Throwable ex) {
if (DEBUG) {
Slog.i(TAG, "Flags not ready yet. Return false for " + flagName, ex);
}
- return false;
}
+ // TODO(b/299462337) Remove when the infrastructure is ready.
+ if (Build.IS_ENG || Build.IS_USERDEBUG) {
+ return SystemProperties.getBoolean("persist.sys." + flagName + "-override",
+ flagValue);
+ }
+ return flagValue;
}
}
}
diff --git a/services/core/java/com/android/server/input/FocusEventDebugView.java b/services/core/java/com/android/server/input/FocusEventDebugView.java
deleted file mode 100644
index 4b8fabde..0000000
--- a/services/core/java/com/android/server/input/FocusEventDebugView.java
+++ /dev/null
@@ -1,848 +0,0 @@
-/*
- * Copyright 2023 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.input;
-
-import static android.util.TypedValue.COMPLEX_UNIT_DIP;
-import static android.util.TypedValue.COMPLEX_UNIT_SP;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-
-import android.animation.LayoutTransition;
-import android.annotation.AnyThread;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Paint;
-import android.graphics.Typeface;
-import android.util.DisplayMetrics;
-import android.util.Pair;
-import android.util.Slog;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.InputDevice;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.RoundedCorner;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.WindowInsets;
-import android.view.animation.AccelerateInterpolator;
-import android.widget.HorizontalScrollView;
-import android.widget.LinearLayout;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
-
-import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
-
-/**
- * Displays focus events, such as physical keyboard KeyEvents and non-pointer MotionEvents on
- * the screen.
- */
-class FocusEventDebugView extends RelativeLayout {
-
- private static final String TAG = FocusEventDebugView.class.getSimpleName();
-
- private static final int KEY_FADEOUT_DURATION_MILLIS = 1000;
- private static final int KEY_TRANSITION_DURATION_MILLIS = 100;
-
- private static final int OUTER_PADDING_DP = 16;
- private static final int KEY_SEPARATION_MARGIN_DP = 16;
- private static final int KEY_VIEW_SIDE_PADDING_DP = 16;
- private static final int KEY_VIEW_VERTICAL_PADDING_DP = 8;
- private static final int KEY_VIEW_MIN_WIDTH_DP = 32;
- private static final int KEY_VIEW_TEXT_SIZE_SP = 12;
- private static final double ROTATY_GRAPH_HEIGHT_FRACTION = 0.5;
-
- private final InputManagerService mService;
- private final int mOuterPadding;
- private final DisplayMetrics mDm;
-
- // Tracks all keys that are currently pressed/down.
- private final Map<Pair<Integer /*deviceId*/, Integer /*scanCode*/>, PressedKeyView>
- mPressedKeys = new HashMap<>();
-
- @Nullable
- private FocusEventDebugGlobalMonitor mFocusEventDebugGlobalMonitor;
- @Nullable
- private PressedKeyContainer mPressedKeyContainer;
- @Nullable
- private PressedKeyContainer mPressedModifierContainer;
- private final Supplier<RotaryInputValueView> mRotaryInputValueViewFactory;
- @Nullable
- private RotaryInputValueView mRotaryInputValueView;
- private final Supplier<RotaryInputGraphView> mRotaryInputGraphViewFactory;
- @Nullable
- private RotaryInputGraphView mRotaryInputGraphView;
-
- @VisibleForTesting
- FocusEventDebugView(Context c, InputManagerService service,
- Supplier<RotaryInputValueView> rotaryInputValueViewFactory,
- Supplier<RotaryInputGraphView> rotaryInputGraphViewFactory) {
- super(c);
- setFocusableInTouchMode(true);
-
- mService = service;
- mRotaryInputValueViewFactory = rotaryInputValueViewFactory;
- mRotaryInputGraphViewFactory = rotaryInputGraphViewFactory;
- mDm = mContext.getResources().getDisplayMetrics();
- mOuterPadding = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, OUTER_PADDING_DP, mDm);
- }
-
- FocusEventDebugView(Context c, InputManagerService service) {
- this(c, service, () -> new RotaryInputValueView(c), () -> new RotaryInputGraphView(c));
- }
-
- @Override
- public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- int paddingBottom = 0;
-
- final RoundedCorner bottomLeft =
- insets.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT);
- if (bottomLeft != null && !insets.isRound()) {
- paddingBottom = bottomLeft.getRadius();
- }
-
- final RoundedCorner bottomRight =
- insets.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT);
- if (bottomRight != null && !insets.isRound()) {
- paddingBottom = Math.max(paddingBottom, bottomRight.getRadius());
- }
-
- if (insets.getDisplayCutout() != null) {
- paddingBottom =
- Math.max(paddingBottom, insets.getDisplayCutout().getSafeInsetBottom());
- }
-
- setPadding(mOuterPadding, mOuterPadding, mOuterPadding, mOuterPadding + paddingBottom);
- setClipToPadding(false);
- invalidate();
- return super.onApplyWindowInsets(insets);
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- handleKeyEvent(event);
- return super.dispatchKeyEvent(event);
- }
-
- @AnyThread
- public void updateShowKeyPresses(boolean enabled) {
- post(() -> handleUpdateShowKeyPresses(enabled));
- }
-
- @AnyThread
- public void updateShowRotaryInput(boolean enabled) {
- post(() -> handleUpdateShowRotaryInput(enabled));
- }
-
- private void handleUpdateShowKeyPresses(boolean enabled) {
- if (enabled == showKeyPresses()) {
- return;
- }
-
- if (!enabled) {
- removeView(mPressedKeyContainer);
- mPressedKeyContainer = null;
- removeView(mPressedModifierContainer);
- mPressedModifierContainer = null;
- return;
- }
-
- mPressedKeyContainer = new PressedKeyContainer(mContext);
- mPressedKeyContainer.setOrientation(LinearLayout.HORIZONTAL);
- mPressedKeyContainer.setGravity(Gravity.RIGHT | Gravity.BOTTOM);
- mPressedKeyContainer.setLayoutDirection(LAYOUT_DIRECTION_LTR);
- final var scroller = new HorizontalScrollView(mContext);
- scroller.addView(mPressedKeyContainer);
- scroller.setHorizontalScrollBarEnabled(false);
- scroller.addOnLayoutChangeListener(
- (view, l, t, r, b, ol, ot, or, ob) -> scroller.fullScroll(View.FOCUS_RIGHT));
- scroller.setHorizontalFadingEdgeEnabled(true);
- LayoutParams scrollerLayoutParams = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
- scrollerLayoutParams.addRule(ALIGN_PARENT_BOTTOM);
- scrollerLayoutParams.addRule(ALIGN_PARENT_RIGHT);
- addView(scroller, scrollerLayoutParams);
-
- mPressedModifierContainer = new PressedKeyContainer(mContext);
- mPressedModifierContainer.setOrientation(LinearLayout.VERTICAL);
- mPressedModifierContainer.setGravity(Gravity.LEFT | Gravity.BOTTOM);
- LayoutParams modifierLayoutParams = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
- modifierLayoutParams.addRule(ALIGN_PARENT_BOTTOM);
- modifierLayoutParams.addRule(ALIGN_PARENT_LEFT);
- modifierLayoutParams.addRule(LEFT_OF, scroller.getId());
- addView(mPressedModifierContainer, modifierLayoutParams);
- }
-
- @VisibleForTesting
- void handleUpdateShowRotaryInput(boolean enabled) {
- if (enabled == showRotaryInput()) {
- return;
- }
-
- if (!enabled) {
- mFocusEventDebugGlobalMonitor.dispose();
- mFocusEventDebugGlobalMonitor = null;
- removeView(mRotaryInputValueView);
- mRotaryInputValueView = null;
- removeView(mRotaryInputGraphView);
- mRotaryInputGraphView = null;
- return;
- }
-
- mFocusEventDebugGlobalMonitor = new FocusEventDebugGlobalMonitor(this, mService);
-
- mRotaryInputValueView = mRotaryInputValueViewFactory.get();
- LayoutParams valueLayoutParams = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
- valueLayoutParams.addRule(CENTER_HORIZONTAL);
- valueLayoutParams.addRule(ALIGN_PARENT_BOTTOM);
- addView(mRotaryInputValueView, valueLayoutParams);
-
- mRotaryInputGraphView = mRotaryInputGraphViewFactory.get();
- LayoutParams graphLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,
- (int) (ROTATY_GRAPH_HEIGHT_FRACTION * mDm.heightPixels));
- graphLayoutParams.addRule(CENTER_IN_PARENT);
- addView(mRotaryInputGraphView, graphLayoutParams);
- }
-
- /** Report a key event to the debug view. */
- @AnyThread
- public void reportKeyEvent(KeyEvent event) {
- post(() -> handleKeyEvent(KeyEvent.obtain((KeyEvent) event)));
- }
-
- /** Report a motion event to the debug view. */
- @AnyThread
- public void reportMotionEvent(MotionEvent event) {
- if (event.getSource() != InputDevice.SOURCE_ROTARY_ENCODER) {
- return;
- }
-
- post(() -> handleRotaryInput(MotionEvent.obtain((MotionEvent) event)));
- }
-
- private void handleKeyEvent(KeyEvent keyEvent) {
- if (!showKeyPresses()) {
- return;
- }
-
- final var identifier = new Pair<>(keyEvent.getDeviceId(), keyEvent.getScanCode());
- final var container = KeyEvent.isModifierKey(keyEvent.getKeyCode())
- ? mPressedModifierContainer
- : mPressedKeyContainer;
- PressedKeyView pressedKeyView = mPressedKeys.get(identifier);
- switch (keyEvent.getAction()) {
- case KeyEvent.ACTION_DOWN: {
- if (pressedKeyView != null) {
- if (keyEvent.getRepeatCount() == 0) {
- Slog.w(TAG, "Got key down for "
- + KeyEvent.keyCodeToString(keyEvent.getKeyCode())
- + " that was already tracked as being down.");
- break;
- }
- container.handleKeyRepeat(pressedKeyView);
- break;
- }
-
- pressedKeyView = new PressedKeyView(mContext, getLabel(keyEvent));
- mPressedKeys.put(identifier, pressedKeyView);
- container.handleKeyPressed(pressedKeyView);
- break;
- }
- case KeyEvent.ACTION_UP: {
- if (pressedKeyView == null) {
- Slog.w(TAG, "Got key up for " + KeyEvent.keyCodeToString(keyEvent.getKeyCode())
- + " that was not tracked as being down.");
- break;
- }
- mPressedKeys.remove(identifier);
- container.handleKeyRelease(pressedKeyView);
- break;
- }
- default:
- break;
- }
- keyEvent.recycle();
- }
-
- @VisibleForTesting
- void handleRotaryInput(MotionEvent motionEvent) {
- if (!showRotaryInput()) {
- return;
- }
-
- float scrollAxisValue = motionEvent.getAxisValue(MotionEvent.AXIS_SCROLL);
- mRotaryInputValueView.updateValue(scrollAxisValue);
- mRotaryInputGraphView.addValue(scrollAxisValue, motionEvent.getEventTime());
-
- motionEvent.recycle();
- }
-
- private static String getLabel(KeyEvent event) {
- switch (event.getKeyCode()) {
- case KeyEvent.KEYCODE_SPACE:
- return "\u2423";
- case KeyEvent.KEYCODE_TAB:
- return "\u21e5";
- case KeyEvent.KEYCODE_ENTER:
- case KeyEvent.KEYCODE_NUMPAD_ENTER:
- return "\u23CE";
- case KeyEvent.KEYCODE_DEL:
- return "\u232B";
- case KeyEvent.KEYCODE_FORWARD_DEL:
- return "\u2326";
- case KeyEvent.KEYCODE_ESCAPE:
- return "ESC";
- case KeyEvent.KEYCODE_DPAD_UP:
- return "\u2191";
- case KeyEvent.KEYCODE_DPAD_DOWN:
- return "\u2193";
- case KeyEvent.KEYCODE_DPAD_LEFT:
- return "\u2190";
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- return "\u2192";
- case KeyEvent.KEYCODE_DPAD_UP_RIGHT:
- return "\u2197";
- case KeyEvent.KEYCODE_DPAD_UP_LEFT:
- return "\u2196";
- case KeyEvent.KEYCODE_DPAD_DOWN_RIGHT:
- return "\u2198";
- case KeyEvent.KEYCODE_DPAD_DOWN_LEFT:
- return "\u2199";
- default:
- break;
- }
-
- final int unicodeChar = event.getUnicodeChar();
- if (unicodeChar != 0) {
- return new String(Character.toChars(unicodeChar));
- }
-
- final var label = KeyEvent.keyCodeToString(event.getKeyCode());
- if (label.startsWith("KEYCODE_")) {
- return label.substring(8);
- }
- return label;
- }
-
- /** Determine whether to show key presses by checking one of the key-related objects. */
- private boolean showKeyPresses() {
- return mPressedKeyContainer != null;
- }
-
- /** Determine whether to show rotary input by checking one of the rotary-related objects. */
- private boolean showRotaryInput() {
- return mRotaryInputValueView != null;
- }
-
- /**
- * Converts a dimension in scaled pixel units to integer display pixels.
- */
- private static int applyDimensionSp(int dimensionSp, DisplayMetrics dm) {
- return (int) TypedValue.applyDimension(COMPLEX_UNIT_SP, dimensionSp, dm);
- }
-
- private static class PressedKeyView extends TextView {
-
- private static final ColorFilter sInvertColors = new ColorMatrixColorFilter(new float[]{
- -1.0f, 0, 0, 0, 255, // red
- 0, -1.0f, 0, 0, 255, // green
- 0, 0, -1.0f, 0, 255, // blue
- 0, 0, 0, 1.0f, 0 // alpha
- });
-
- PressedKeyView(Context c, String label) {
- super(c);
-
- final var dm = c.getResources().getDisplayMetrics();
- final int keyViewSidePadding =
- (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, KEY_VIEW_SIDE_PADDING_DP, dm);
- final int keyViewVerticalPadding =
- (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, KEY_VIEW_VERTICAL_PADDING_DP,
- dm);
- final int keyViewMinWidth =
- (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, KEY_VIEW_MIN_WIDTH_DP, dm);
- final int textSize =
- (int) TypedValue.applyDimension(COMPLEX_UNIT_SP, KEY_VIEW_TEXT_SIZE_SP, dm);
-
- setText(label);
- setGravity(Gravity.CENTER);
- setMinimumWidth(keyViewMinWidth);
- setTextSize(textSize);
- setTypeface(Typeface.SANS_SERIF);
- setBackgroundResource(R.drawable.focus_event_pressed_key_background);
- setPaddingRelative(keyViewSidePadding, keyViewVerticalPadding, keyViewSidePadding,
- keyViewVerticalPadding);
-
- setHighlighted(true);
- }
-
- void setHighlighted(boolean isHighlighted) {
- if (isHighlighted) {
- setTextColor(Color.BLACK);
- getBackground().setColorFilter(sInvertColors);
- } else {
- setTextColor(Color.WHITE);
- getBackground().clearColorFilter();
- }
- invalidate();
- }
- }
-
- private static class PressedKeyContainer extends LinearLayout {
-
- private final MarginLayoutParams mPressedKeyLayoutParams;
-
- PressedKeyContainer(Context c) {
- super(c);
-
- final var dm = c.getResources().getDisplayMetrics();
- final int keySeparationMargin =
- (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, KEY_SEPARATION_MARGIN_DP, dm);
-
- final var transition = new LayoutTransition();
- transition.disableTransitionType(LayoutTransition.APPEARING);
- transition.disableTransitionType(LayoutTransition.DISAPPEARING);
- transition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
- transition.setDuration(KEY_TRANSITION_DURATION_MILLIS);
- setLayoutTransition(transition);
-
- mPressedKeyLayoutParams = new MarginLayoutParams(WRAP_CONTENT, WRAP_CONTENT);
- if (getOrientation() == VERTICAL) {
- mPressedKeyLayoutParams.setMargins(0, keySeparationMargin, 0, 0);
- } else {
- mPressedKeyLayoutParams.setMargins(keySeparationMargin, 0, 0, 0);
- }
- }
-
- public void handleKeyPressed(PressedKeyView pressedKeyView) {
- addView(pressedKeyView, getChildCount(), mPressedKeyLayoutParams);
- invalidate();
- }
-
- public void handleKeyRepeat(PressedKeyView repeatedKeyView) {
- // Do nothing for now.
- }
-
- public void handleKeyRelease(PressedKeyView releasedKeyView) {
- releasedKeyView.setHighlighted(false);
- releasedKeyView.clearAnimation();
- releasedKeyView.animate()
- .alpha(0)
- .setDuration(KEY_FADEOUT_DURATION_MILLIS)
- .setInterpolator(new AccelerateInterpolator())
- .withEndAction(this::cleanUpPressedKeyViews)
- .start();
- }
-
- private void cleanUpPressedKeyViews() {
- int numChildrenToRemove = 0;
- for (int i = 0; i < getChildCount(); i++) {
- final View child = getChildAt(i);
- if (child.getAlpha() != 0) {
- break;
- }
- child.setVisibility(View.GONE);
- child.clearAnimation();
- numChildrenToRemove++;
- }
- removeViews(0, numChildrenToRemove);
- invalidate();
- }
- }
-
- // TODO(b/286086154): move RotaryInputGraphView and RotaryInputValueView to a subpackage.
-
- /** Draws the most recent rotary input value and indicates whether the source is active. */
- @VisibleForTesting
- static class RotaryInputValueView extends TextView {
-
- private static final int INACTIVE_TEXT_COLOR = 0xffff00ff;
- private static final int ACTIVE_TEXT_COLOR = 0xff420f28;
- private static final int TEXT_SIZE_SP = 8;
- private static final int SIDE_PADDING_SP = 4;
- /** Determines how long the active status lasts. */
- private static final int ACTIVE_STATUS_DURATION = 250 /* milliseconds */;
- private static final ColorFilter ACTIVE_BACKGROUND_FILTER =
- new ColorMatrixColorFilter(new float[]{
- 0, 0, 0, 0, 255, // red
- 0, 0, 0, 0, 0, // green
- 0, 0, 0, 0, 255, // blue
- 0, 0, 0, 0, 200 // alpha
- });
-
- private final Runnable mUpdateActivityStatusCallback = () -> updateActivityStatus(false);
- private final float mScaledVerticalScrollFactor;
-
- @VisibleForTesting
- RotaryInputValueView(Context c) {
- super(c);
-
- DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
- mScaledVerticalScrollFactor = ViewConfiguration.get(c).getScaledVerticalScrollFactor();
-
- setText(getFormattedValue(0));
- setTextColor(INACTIVE_TEXT_COLOR);
- setTextSize(applyDimensionSp(TEXT_SIZE_SP, dm));
- setPaddingRelative(applyDimensionSp(SIDE_PADDING_SP, dm), 0,
- applyDimensionSp(SIDE_PADDING_SP, dm), 0);
- setTypeface(null, Typeface.BOLD);
- setBackgroundResource(R.drawable.focus_event_rotary_input_background);
- }
-
- void updateValue(float value) {
- removeCallbacks(mUpdateActivityStatusCallback);
-
- setText(getFormattedValue(value * mScaledVerticalScrollFactor));
-
- updateActivityStatus(true);
- postDelayed(mUpdateActivityStatusCallback, ACTIVE_STATUS_DURATION);
- }
-
- @VisibleForTesting
- void updateActivityStatus(boolean active) {
- if (active) {
- setTextColor(ACTIVE_TEXT_COLOR);
- getBackground().setColorFilter(ACTIVE_BACKGROUND_FILTER);
- } else {
- setTextColor(INACTIVE_TEXT_COLOR);
- getBackground().clearColorFilter();
- }
- }
-
- private static String getFormattedValue(float value) {
- return String.format("%s%.1f", value < 0 ? "-" : "+", Math.abs(value));
- }
- }
-
- /**
- * Shows a graph with the rotary input values as a function of time.
- * The graph gets reset if no action is received for a certain amount of time.
- */
- @VisibleForTesting
- static class RotaryInputGraphView extends View {
-
- private static final int FRAME_COLOR = 0xbf741b47;
- private static final int FRAME_WIDTH_SP = 2;
- private static final int FRAME_BORDER_GAP_SP = 10;
- private static final int FRAME_TEXT_SIZE_SP = 10;
- private static final int FRAME_TEXT_OFFSET_SP = 2;
- private static final int GRAPH_COLOR = 0xffff00ff;
- private static final int GRAPH_LINE_WIDTH_SP = 1;
- private static final int GRAPH_POINT_RADIUS_SP = 4;
- private static final long MAX_SHOWN_TIME_INTERVAL = TimeUnit.SECONDS.toMillis(5);
- private static final float DEFAULT_FRAME_CENTER_POSITION = 0;
- private static final int MAX_GRAPH_VALUES_SIZE = 400;
- /** Maximum time between values so that they are considered part of the same gesture. */
- private static final long MAX_GESTURE_TIME = TimeUnit.SECONDS.toMillis(1);
-
- private final DisplayMetrics mDm;
- /**
- * Distance in position units (amount scrolled in display pixels) from the center to the
- * top/bottom frame lines.
- */
- private final float mFrameCenterToBorderDistance;
- private final float mScaledVerticalScrollFactor;
- private final Locale mDefaultLocale;
- private final Paint mFramePaint = new Paint();
- private final Paint mFrameTextPaint = new Paint();
- private final Paint mGraphLinePaint = new Paint();
- private final Paint mGraphPointPaint = new Paint();
-
- private final CyclicBuffer mGraphValues = new CyclicBuffer(MAX_GRAPH_VALUES_SIZE);
- /** Position at which graph values are placed at the center of the graph. */
- private float mFrameCenterPosition = DEFAULT_FRAME_CENTER_POSITION;
-
- @VisibleForTesting
- RotaryInputGraphView(Context c) {
- super(c);
-
- mDm = mContext.getResources().getDisplayMetrics();
- // This makes the center-to-border distance equivalent to the display height, meaning
- // that the total height of the graph is equivalent to 2x the display height.
- mFrameCenterToBorderDistance = mDm.heightPixels;
- mScaledVerticalScrollFactor = ViewConfiguration.get(c).getScaledVerticalScrollFactor();
- mDefaultLocale = Locale.getDefault();
-
- mFramePaint.setColor(FRAME_COLOR);
- mFramePaint.setStrokeWidth(applyDimensionSp(FRAME_WIDTH_SP, mDm));
-
- mFrameTextPaint.setColor(GRAPH_COLOR);
- mFrameTextPaint.setTextSize(applyDimensionSp(FRAME_TEXT_SIZE_SP, mDm));
-
- mGraphLinePaint.setColor(GRAPH_COLOR);
- mGraphLinePaint.setStrokeWidth(applyDimensionSp(GRAPH_LINE_WIDTH_SP, mDm));
- mGraphLinePaint.setStrokeCap(Paint.Cap.ROUND);
- mGraphLinePaint.setStrokeJoin(Paint.Join.ROUND);
-
- mGraphPointPaint.setColor(GRAPH_COLOR);
- mGraphPointPaint.setStrokeWidth(applyDimensionSp(GRAPH_POINT_RADIUS_SP, mDm));
- mGraphPointPaint.setStrokeCap(Paint.Cap.ROUND);
- mGraphPointPaint.setStrokeJoin(Paint.Join.ROUND);
- }
-
- /**
- * Reads new scroll axis value and updates the list accordingly. Old positions are
- * kept at the front (what you would get with getFirst), while the recent positions are
- * kept at the back (what you would get with getLast). Also updates the frame center
- * position to handle out-of-bounds cases.
- */
- void addValue(float scrollAxisValue, long eventTime) {
- // Remove values that are too old.
- while (mGraphValues.getSize() > 0
- && (eventTime - mGraphValues.getFirst().mTime) > MAX_SHOWN_TIME_INTERVAL) {
- mGraphValues.removeFirst();
- }
-
- // If there are no recent values, reset the frame center.
- if (mGraphValues.getSize() == 0) {
- mFrameCenterPosition = DEFAULT_FRAME_CENTER_POSITION;
- }
-
- // Handle new value. We multiply the scroll axis value by the scaled scroll factor to
- // get the amount of pixels to be scrolled. We also compute the accumulated position
- // by adding the current value to the last one (if not empty).
- final float displacement = scrollAxisValue * mScaledVerticalScrollFactor;
- final float prevPos = (mGraphValues.getSize() == 0 ? 0 : mGraphValues.getLast().mPos);
- final float pos = prevPos + displacement;
-
- mGraphValues.add(pos, eventTime);
-
- // The difference between the distance of the most recent position from the center
- // frame (pos - mFrameCenterPosition) and the maximum allowed distance from the center
- // frame (mFrameCenterToBorderDistance).
- final float verticalDiff = Math.abs(pos - mFrameCenterPosition)
- - mFrameCenterToBorderDistance;
- // If needed, translate frame.
- if (verticalDiff > 0) {
- final int sign = pos - mFrameCenterPosition < 0 ? -1 : 1;
- // Here, we update the center frame position by the exact amount needed for us to
- // stay within the maximum allowed distance from the center frame.
- mFrameCenterPosition += sign * verticalDiff;
- }
-
- // Redraw canvas.
- invalidate();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- // Note: vertical coordinates in Canvas go from top to bottom,
- // that is bottomY > middleY > topY.
- final int verticalMargin = applyDimensionSp(FRAME_BORDER_GAP_SP, mDm);
- final int topY = verticalMargin;
- final int bottomY = getHeight() - verticalMargin;
- final int middleY = (topY + bottomY) / 2;
-
- // Note: horizontal coordinates in Canvas go from left to right,
- // that is rightX > leftX.
- final int leftX = 0;
- final int rightX = getWidth();
-
- // Draw the frame, which includes 3 lines that show the maximum,
- // minimum and middle positions of the graph.
- canvas.drawLine(leftX, topY, rightX, topY, mFramePaint);
- canvas.drawLine(leftX, middleY, rightX, middleY, mFramePaint);
- canvas.drawLine(leftX, bottomY, rightX, bottomY, mFramePaint);
-
- // Draw the position that each frame line corresponds to.
- final int frameTextOffset = applyDimensionSp(FRAME_TEXT_OFFSET_SP, mDm);
- canvas.drawText(
- String.format(mDefaultLocale, "%.1f",
- mFrameCenterPosition + mFrameCenterToBorderDistance),
- leftX,
- topY - frameTextOffset, mFrameTextPaint
- );
- canvas.drawText(
- String.format(mDefaultLocale, "%.1f", mFrameCenterPosition),
- leftX,
- middleY - frameTextOffset, mFrameTextPaint
- );
- canvas.drawText(
- String.format(mDefaultLocale, "%.1f",
- mFrameCenterPosition - mFrameCenterToBorderDistance),
- leftX,
- bottomY - frameTextOffset, mFrameTextPaint
- );
-
- // If there are no graph values to be drawn, stop here.
- if (mGraphValues.getSize() == 0) {
- return;
- }
-
- // Draw the graph using the times and positions.
- // We start at the most recent value (which should be drawn at the right) and move
- // to the older values (which should be drawn to the left of more recent ones). Negative
- // indices are handled by circuling back to the end of the buffer.
- final long mostRecentTime = mGraphValues.getLast().mTime;
- float prevCoordX = 0;
- float prevCoordY = 0;
- float prevAge = 0;
- for (Iterator<GraphValue> iter = mGraphValues.reverseIterator(); iter.hasNext();) {
- final GraphValue value = iter.next();
-
- final int age = (int) (mostRecentTime - value.mTime);
- final float pos = value.mPos;
-
- // We get the horizontal coordinate in time units from left to right with
- // (MAX_SHOWN_TIME_INTERVAL - age). Then, we rescale it to match the canvas
- // units by dividing it by the time-domain length (MAX_SHOWN_TIME_INTERVAL)
- // and by multiplying it by the canvas length (rightX - leftX). Finally, we
- // offset the coordinate by adding it to leftX.
- final float coordX = leftX + ((float) (MAX_SHOWN_TIME_INTERVAL - age)
- / MAX_SHOWN_TIME_INTERVAL) * (rightX - leftX);
-
- // We get the vertical coordinate in position units from middle to top with
- // (pos - mFrameCenterPosition). Then, we rescale it to match the canvas
- // units by dividing it by half of the position-domain length
- // (mFrameCenterToBorderDistance) and by multiplying it by half of the canvas
- // length (middleY - topY). Finally, we offset the coordinate by subtracting
- // it from middleY (we can't "add" here because the coordinate grows from top
- // to bottom).
- final float coordY = middleY - ((pos - mFrameCenterPosition)
- / mFrameCenterToBorderDistance) * (middleY - topY);
-
- // Draw a point for this value.
- canvas.drawPoint(coordX, coordY, mGraphPointPaint);
-
- // If this value is part of the same gesture as the previous one, draw a line
- // between them. We ignore the first value (with age = 0).
- if (age != 0 && (age - prevAge) <= MAX_GESTURE_TIME) {
- canvas.drawLine(prevCoordX, prevCoordY, coordX, coordY, mGraphLinePaint);
- }
-
- prevCoordX = coordX;
- prevCoordY = coordY;
- prevAge = age;
- }
- }
-
- @VisibleForTesting
- float getFrameCenterPosition() {
- return mFrameCenterPosition;
- }
-
- /**
- * Holds data needed to draw each entry in the graph.
- */
- private static class GraphValue {
- /** Position. */
- float mPos;
- /** Time when this value was added. */
- long mTime;
-
- GraphValue(float pos, long time) {
- this.mPos = pos;
- this.mTime = time;
- }
- }
-
- /**
- * Holds the graph values as a cyclic buffer. It has a fixed capacity, and it replaces the
- * old values with new ones to avoid creating new objects.
- */
- private static class CyclicBuffer {
- private final GraphValue[] mValues;
- private final int mCapacity;
- private int mSize = 0;
- private int mLastIndex = 0;
-
- // The iteration index and counter are here to make it easier to reset them.
- /** Determines the value currently pointed by the iterator. */
- private int mIteratorIndex;
- /** Counts how many values have been iterated through. */
- private int mIteratorCount;
-
- /** Used traverse the values in reverse order. */
- private final Iterator<GraphValue> mReverseIterator = new Iterator<GraphValue>() {
- @Override
- public boolean hasNext() {
- return mIteratorCount <= mSize;
- }
-
- @Override
- public GraphValue next() {
- // Returns the value currently pointed by the iterator and moves the iterator to
- // the previous one.
- mIteratorCount++;
- return mValues[(mIteratorIndex-- + mCapacity) % mCapacity];
- }
- };
-
- CyclicBuffer(int capacity) {
- mCapacity = capacity;
- mValues = new GraphValue[capacity];
- }
-
- /**
- * Add new graph value. If there is an existing object, we replace its data with the
- * new one. With this, we re-use old objects instead of creating new ones.
- */
- void add(float pos, long time) {
- mLastIndex = (mLastIndex + 1) % mCapacity;
- if (mValues[mLastIndex] == null) {
- mValues[mLastIndex] = new GraphValue(pos, time);
- } else {
- final GraphValue oldValue = mValues[mLastIndex];
- oldValue.mPos = pos;
- oldValue.mTime = time;
- }
-
- // If needed, account for new value in the buffer size.
- if (mSize != mCapacity) {
- mSize++;
- }
- }
-
- int getSize() {
- return mSize;
- }
-
- GraphValue getFirst() {
- final int distanceBetweenLastAndFirst = (mCapacity - mSize) + 1;
- final int firstIndex = (mLastIndex + distanceBetweenLastAndFirst) % mCapacity;
- return mValues[firstIndex];
- }
-
- GraphValue getLast() {
- return mValues[mLastIndex];
- }
-
- void removeFirst() {
- mSize--;
- }
-
- /** Returns an iterator pointing at the last value. */
- Iterator<GraphValue> reverseIterator() {
- mIteratorIndex = mLastIndex;
- mIteratorCount = 1;
- return mReverseIterator;
- }
- }
- }
-}
diff --git a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
index 2ede56d..a2c8748 100644
--- a/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
+++ b/services/core/java/com/android/server/input/GestureMonitorSpyWindow.java
@@ -62,10 +62,10 @@
mWindowHandle.ownerUid = uid;
mWindowHandle.scaleFactor = 1.0f;
mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
- mWindowHandle.inputConfig =
- InputConfig.NOT_FOCUSABLE | InputConfig.SPY | InputConfig.TRUSTED_OVERLAY;
+ mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.SPY;
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ mWindowHandle.setTrustedOverlay(t, mInputSurface, true);
t.setInputWindowInfo(mInputSurface, mWindowHandle);
t.setLayer(mInputSurface, InputManagerService.INPUT_OVERLAY_LAYER_GESTURE_MONITOR);
t.setPosition(mInputSurface, 0, 0);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 6b399de..2533e02 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -117,6 +117,7 @@
import com.android.server.LocalServices;
import com.android.server.Watchdog;
import com.android.server.input.InputManagerInternal.LidSwitchCallback;
+import com.android.server.input.debug.FocusEventDebugView;
import com.android.server.inputmethod.InputMethodManagerInternal;
import com.android.server.policy.WindowManagerPolicy;
diff --git a/services/core/java/com/android/server/input/KeyboardLayoutManager.java b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
index 0eb620f..bad6bf0 100644
--- a/services/core/java/com/android/server/input/KeyboardLayoutManager.java
+++ b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
@@ -71,6 +71,7 @@
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.InputMethodSubtypeHandle;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.notification.SystemNotificationChannels;
@@ -99,7 +100,7 @@
*
* @hide
*/
-final class KeyboardLayoutManager implements InputManager.InputDeviceListener {
+class KeyboardLayoutManager implements InputManager.InputDeviceListener {
private static final String TAG = "KeyboardLayoutManager";
@@ -1295,7 +1296,8 @@
}
@SuppressLint("MissingPermission")
- private List<ImeInfo> getImeInfoListForLayoutMapping() {
+ @VisibleForTesting
+ public List<ImeInfo> getImeInfoListForLayoutMapping() {
List<ImeInfo> imeInfoList = new ArrayList<>();
UserManager userManager = Objects.requireNonNull(
mContext.getSystemService(UserManager.class));
@@ -1402,7 +1404,8 @@
}
}
- private static class ImeInfo {
+ @VisibleForTesting
+ public static class ImeInfo {
@UserIdInt int mUserId;
@NonNull InputMethodSubtypeHandle mImeSubtypeHandle;
@Nullable InputMethodSubtype mImeSubtype;
diff --git a/services/core/java/com/android/server/input/FocusEventDebugGlobalMonitor.java b/services/core/java/com/android/server/input/debug/FocusEventDebugGlobalMonitor.java
similarity index 94%
rename from services/core/java/com/android/server/input/FocusEventDebugGlobalMonitor.java
rename to services/core/java/com/android/server/input/debug/FocusEventDebugGlobalMonitor.java
index 67c221f..2b21e49 100644
--- a/services/core/java/com/android/server/input/FocusEventDebugGlobalMonitor.java
+++ b/services/core/java/com/android/server/input/debug/FocusEventDebugGlobalMonitor.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.input;
+package com.android.server.input.debug;
import android.view.Display;
import android.view.InputEvent;
@@ -22,6 +22,7 @@
import android.view.MotionEvent;
import com.android.server.UiThread;
+import com.android.server.input.InputManagerService;
/**
* Receives input events before they are dispatched and reports them to FocusEventDebugView.
diff --git a/services/core/java/com/android/server/input/debug/FocusEventDebugView.java b/services/core/java/com/android/server/input/debug/FocusEventDebugView.java
new file mode 100644
index 0000000..6eec0de
--- /dev/null
+++ b/services/core/java/com/android/server/input/debug/FocusEventDebugView.java
@@ -0,0 +1,466 @@
+/*
+ * Copyright 2023 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.input.debug;
+
+import static android.util.TypedValue.COMPLEX_UNIT_DIP;
+import static android.util.TypedValue.COMPLEX_UNIT_SP;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+
+import android.animation.LayoutTransition;
+import android.annotation.AnyThread;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Typeface;
+import android.util.DisplayMetrics;
+import android.util.Pair;
+import android.util.Slog;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.RoundedCorner;
+import android.view.View;
+import android.view.WindowInsets;
+import android.view.animation.AccelerateInterpolator;
+import android.widget.HorizontalScrollView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.input.InputManagerService;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Supplier;
+
+/**
+ * Displays focus events, such as physical keyboard KeyEvents and non-pointer MotionEvents on
+ * the screen.
+ */
+public class FocusEventDebugView extends RelativeLayout {
+
+ private static final String TAG = FocusEventDebugView.class.getSimpleName();
+
+ private static final int KEY_FADEOUT_DURATION_MILLIS = 1000;
+ private static final int KEY_TRANSITION_DURATION_MILLIS = 100;
+
+ private static final int OUTER_PADDING_DP = 16;
+ private static final int KEY_SEPARATION_MARGIN_DP = 16;
+ private static final int KEY_VIEW_SIDE_PADDING_DP = 16;
+ private static final int KEY_VIEW_VERTICAL_PADDING_DP = 8;
+ private static final int KEY_VIEW_MIN_WIDTH_DP = 32;
+ private static final int KEY_VIEW_TEXT_SIZE_SP = 12;
+ private static final double ROTATY_GRAPH_HEIGHT_FRACTION = 0.5;
+
+ private final InputManagerService mService;
+ private final int mOuterPadding;
+ private final DisplayMetrics mDm;
+
+ // Tracks all keys that are currently pressed/down.
+ private final Map<Pair<Integer /*deviceId*/, Integer /*scanCode*/>, PressedKeyView>
+ mPressedKeys = new HashMap<>();
+
+ @Nullable
+ private FocusEventDebugGlobalMonitor mFocusEventDebugGlobalMonitor;
+ @Nullable
+ private PressedKeyContainer mPressedKeyContainer;
+ @Nullable
+ private PressedKeyContainer mPressedModifierContainer;
+ private final Supplier<RotaryInputValueView> mRotaryInputValueViewFactory;
+ @Nullable
+ private RotaryInputValueView mRotaryInputValueView;
+ private final Supplier<RotaryInputGraphView> mRotaryInputGraphViewFactory;
+ @Nullable
+ private RotaryInputGraphView mRotaryInputGraphView;
+
+ @VisibleForTesting
+ FocusEventDebugView(Context c, InputManagerService service,
+ Supplier<RotaryInputValueView> rotaryInputValueViewFactory,
+ Supplier<RotaryInputGraphView> rotaryInputGraphViewFactory) {
+ super(c);
+ setFocusableInTouchMode(true);
+
+ mService = service;
+ mRotaryInputValueViewFactory = rotaryInputValueViewFactory;
+ mRotaryInputGraphViewFactory = rotaryInputGraphViewFactory;
+ mDm = mContext.getResources().getDisplayMetrics();
+ mOuterPadding = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, OUTER_PADDING_DP, mDm);
+ }
+
+ public FocusEventDebugView(Context c, InputManagerService service) {
+ this(c, service, () -> new RotaryInputValueView(c), () -> new RotaryInputGraphView(c));
+ }
+
+ @Override
+ public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+ int paddingBottom = 0;
+
+ final RoundedCorner bottomLeft =
+ insets.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT);
+ if (bottomLeft != null && !insets.isRound()) {
+ paddingBottom = bottomLeft.getRadius();
+ }
+
+ final RoundedCorner bottomRight =
+ insets.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT);
+ if (bottomRight != null && !insets.isRound()) {
+ paddingBottom = Math.max(paddingBottom, bottomRight.getRadius());
+ }
+
+ if (insets.getDisplayCutout() != null) {
+ paddingBottom =
+ Math.max(paddingBottom, insets.getDisplayCutout().getSafeInsetBottom());
+ }
+
+ setPadding(mOuterPadding, mOuterPadding, mOuterPadding, mOuterPadding + paddingBottom);
+ setClipToPadding(false);
+ invalidate();
+ return super.onApplyWindowInsets(insets);
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ handleKeyEvent(event);
+ return super.dispatchKeyEvent(event);
+ }
+
+ /** Determines whether to show the key presses visualization. */
+ @AnyThread
+ public void updateShowKeyPresses(boolean enabled) {
+ post(() -> handleUpdateShowKeyPresses(enabled));
+ }
+
+ /** Determines whether to show the rotary input visualization. */
+ @AnyThread
+ public void updateShowRotaryInput(boolean enabled) {
+ post(() -> handleUpdateShowRotaryInput(enabled));
+ }
+
+ private void handleUpdateShowKeyPresses(boolean enabled) {
+ if (enabled == showKeyPresses()) {
+ return;
+ }
+
+ if (!enabled) {
+ removeView(mPressedKeyContainer);
+ mPressedKeyContainer = null;
+ removeView(mPressedModifierContainer);
+ mPressedModifierContainer = null;
+ return;
+ }
+
+ mPressedKeyContainer = new PressedKeyContainer(mContext);
+ mPressedKeyContainer.setOrientation(LinearLayout.HORIZONTAL);
+ mPressedKeyContainer.setGravity(Gravity.RIGHT | Gravity.BOTTOM);
+ mPressedKeyContainer.setLayoutDirection(LAYOUT_DIRECTION_LTR);
+ final var scroller = new HorizontalScrollView(mContext);
+ scroller.addView(mPressedKeyContainer);
+ scroller.setHorizontalScrollBarEnabled(false);
+ scroller.addOnLayoutChangeListener(
+ (view, l, t, r, b, ol, ot, or, ob) -> scroller.fullScroll(View.FOCUS_RIGHT));
+ scroller.setHorizontalFadingEdgeEnabled(true);
+ LayoutParams scrollerLayoutParams = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
+ scrollerLayoutParams.addRule(ALIGN_PARENT_BOTTOM);
+ scrollerLayoutParams.addRule(ALIGN_PARENT_RIGHT);
+ addView(scroller, scrollerLayoutParams);
+
+ mPressedModifierContainer = new PressedKeyContainer(mContext);
+ mPressedModifierContainer.setOrientation(LinearLayout.VERTICAL);
+ mPressedModifierContainer.setGravity(Gravity.LEFT | Gravity.BOTTOM);
+ LayoutParams modifierLayoutParams = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
+ modifierLayoutParams.addRule(ALIGN_PARENT_BOTTOM);
+ modifierLayoutParams.addRule(ALIGN_PARENT_LEFT);
+ modifierLayoutParams.addRule(LEFT_OF, scroller.getId());
+ addView(mPressedModifierContainer, modifierLayoutParams);
+ }
+
+ @VisibleForTesting
+ void handleUpdateShowRotaryInput(boolean enabled) {
+ if (enabled == showRotaryInput()) {
+ return;
+ }
+
+ if (!enabled) {
+ mFocusEventDebugGlobalMonitor.dispose();
+ mFocusEventDebugGlobalMonitor = null;
+ removeView(mRotaryInputValueView);
+ mRotaryInputValueView = null;
+ removeView(mRotaryInputGraphView);
+ mRotaryInputGraphView = null;
+ return;
+ }
+
+ mFocusEventDebugGlobalMonitor = new FocusEventDebugGlobalMonitor(this, mService);
+
+ mRotaryInputValueView = mRotaryInputValueViewFactory.get();
+ LayoutParams valueLayoutParams = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
+ valueLayoutParams.addRule(CENTER_HORIZONTAL);
+ valueLayoutParams.addRule(ALIGN_PARENT_BOTTOM);
+ addView(mRotaryInputValueView, valueLayoutParams);
+
+ mRotaryInputGraphView = mRotaryInputGraphViewFactory.get();
+ LayoutParams graphLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,
+ (int) (ROTATY_GRAPH_HEIGHT_FRACTION * mDm.heightPixels));
+ graphLayoutParams.addRule(CENTER_IN_PARENT);
+ addView(mRotaryInputGraphView, graphLayoutParams);
+ }
+
+ /** Report a key event to the debug view. */
+ @AnyThread
+ public void reportKeyEvent(KeyEvent event) {
+ post(() -> handleKeyEvent(KeyEvent.obtain((KeyEvent) event)));
+ }
+
+ /** Report a motion event to the debug view. */
+ @AnyThread
+ public void reportMotionEvent(MotionEvent event) {
+ if (event.getSource() != InputDevice.SOURCE_ROTARY_ENCODER) {
+ return;
+ }
+
+ post(() -> handleRotaryInput(MotionEvent.obtain((MotionEvent) event)));
+ }
+
+ private void handleKeyEvent(KeyEvent keyEvent) {
+ if (!showKeyPresses()) {
+ return;
+ }
+
+ final var identifier = new Pair<>(keyEvent.getDeviceId(), keyEvent.getScanCode());
+ final var container = KeyEvent.isModifierKey(keyEvent.getKeyCode())
+ ? mPressedModifierContainer
+ : mPressedKeyContainer;
+ PressedKeyView pressedKeyView = mPressedKeys.get(identifier);
+ switch (keyEvent.getAction()) {
+ case KeyEvent.ACTION_DOWN: {
+ if (pressedKeyView != null) {
+ if (keyEvent.getRepeatCount() == 0) {
+ Slog.w(TAG, "Got key down for "
+ + KeyEvent.keyCodeToString(keyEvent.getKeyCode())
+ + " that was already tracked as being down.");
+ break;
+ }
+ container.handleKeyRepeat(pressedKeyView);
+ break;
+ }
+
+ pressedKeyView = new PressedKeyView(mContext, getLabel(keyEvent));
+ mPressedKeys.put(identifier, pressedKeyView);
+ container.handleKeyPressed(pressedKeyView);
+ break;
+ }
+ case KeyEvent.ACTION_UP: {
+ if (pressedKeyView == null) {
+ Slog.w(TAG, "Got key up for " + KeyEvent.keyCodeToString(keyEvent.getKeyCode())
+ + " that was not tracked as being down.");
+ break;
+ }
+ mPressedKeys.remove(identifier);
+ container.handleKeyRelease(pressedKeyView);
+ break;
+ }
+ default:
+ break;
+ }
+ keyEvent.recycle();
+ }
+
+ @VisibleForTesting
+ void handleRotaryInput(MotionEvent motionEvent) {
+ if (!showRotaryInput()) {
+ return;
+ }
+
+ float scrollAxisValue = motionEvent.getAxisValue(MotionEvent.AXIS_SCROLL);
+ mRotaryInputValueView.updateValue(scrollAxisValue);
+ mRotaryInputGraphView.addValue(scrollAxisValue, motionEvent.getEventTime());
+
+ motionEvent.recycle();
+ }
+
+ private static String getLabel(KeyEvent event) {
+ switch (event.getKeyCode()) {
+ case KeyEvent.KEYCODE_SPACE:
+ return "\u2423";
+ case KeyEvent.KEYCODE_TAB:
+ return "\u21e5";
+ case KeyEvent.KEYCODE_ENTER:
+ case KeyEvent.KEYCODE_NUMPAD_ENTER:
+ return "\u23CE";
+ case KeyEvent.KEYCODE_DEL:
+ return "\u232B";
+ case KeyEvent.KEYCODE_FORWARD_DEL:
+ return "\u2326";
+ case KeyEvent.KEYCODE_ESCAPE:
+ return "ESC";
+ case KeyEvent.KEYCODE_DPAD_UP:
+ return "\u2191";
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ return "\u2193";
+ case KeyEvent.KEYCODE_DPAD_LEFT:
+ return "\u2190";
+ case KeyEvent.KEYCODE_DPAD_RIGHT:
+ return "\u2192";
+ case KeyEvent.KEYCODE_DPAD_UP_RIGHT:
+ return "\u2197";
+ case KeyEvent.KEYCODE_DPAD_UP_LEFT:
+ return "\u2196";
+ case KeyEvent.KEYCODE_DPAD_DOWN_RIGHT:
+ return "\u2198";
+ case KeyEvent.KEYCODE_DPAD_DOWN_LEFT:
+ return "\u2199";
+ default:
+ break;
+ }
+
+ final int unicodeChar = event.getUnicodeChar();
+ if (unicodeChar != 0) {
+ return new String(Character.toChars(unicodeChar));
+ }
+
+ final var label = KeyEvent.keyCodeToString(event.getKeyCode());
+ if (label.startsWith("KEYCODE_")) {
+ return label.substring(8);
+ }
+ return label;
+ }
+
+ /** Determine whether to show key presses by checking one of the key-related objects. */
+ private boolean showKeyPresses() {
+ return mPressedKeyContainer != null;
+ }
+
+ /** Determine whether to show rotary input by checking one of the rotary-related objects. */
+ private boolean showRotaryInput() {
+ return mRotaryInputValueView != null;
+ }
+
+ private static class PressedKeyView extends TextView {
+
+ private static final ColorFilter sInvertColors = new ColorMatrixColorFilter(new float[]{
+ -1.0f, 0, 0, 0, 255, // red
+ 0, -1.0f, 0, 0, 255, // green
+ 0, 0, -1.0f, 0, 255, // blue
+ 0, 0, 0, 1.0f, 0 // alpha
+ });
+
+ PressedKeyView(Context c, String label) {
+ super(c);
+
+ final var dm = c.getResources().getDisplayMetrics();
+ final int keyViewSidePadding =
+ (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, KEY_VIEW_SIDE_PADDING_DP, dm);
+ final int keyViewVerticalPadding =
+ (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, KEY_VIEW_VERTICAL_PADDING_DP,
+ dm);
+ final int keyViewMinWidth =
+ (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, KEY_VIEW_MIN_WIDTH_DP, dm);
+ final int textSize =
+ (int) TypedValue.applyDimension(COMPLEX_UNIT_SP, KEY_VIEW_TEXT_SIZE_SP, dm);
+
+ setText(label);
+ setGravity(Gravity.CENTER);
+ setMinimumWidth(keyViewMinWidth);
+ setTextSize(textSize);
+ setTypeface(Typeface.SANS_SERIF);
+ setBackgroundResource(R.drawable.focus_event_pressed_key_background);
+ setPaddingRelative(keyViewSidePadding, keyViewVerticalPadding, keyViewSidePadding,
+ keyViewVerticalPadding);
+
+ setHighlighted(true);
+ }
+
+ void setHighlighted(boolean isHighlighted) {
+ if (isHighlighted) {
+ setTextColor(Color.BLACK);
+ getBackground().setColorFilter(sInvertColors);
+ } else {
+ setTextColor(Color.WHITE);
+ getBackground().clearColorFilter();
+ }
+ invalidate();
+ }
+ }
+
+ private static class PressedKeyContainer extends LinearLayout {
+
+ private final MarginLayoutParams mPressedKeyLayoutParams;
+
+ PressedKeyContainer(Context c) {
+ super(c);
+
+ final var dm = c.getResources().getDisplayMetrics();
+ final int keySeparationMargin =
+ (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, KEY_SEPARATION_MARGIN_DP, dm);
+
+ final var transition = new LayoutTransition();
+ transition.disableTransitionType(LayoutTransition.APPEARING);
+ transition.disableTransitionType(LayoutTransition.DISAPPEARING);
+ transition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
+ transition.setDuration(KEY_TRANSITION_DURATION_MILLIS);
+ setLayoutTransition(transition);
+
+ mPressedKeyLayoutParams = new MarginLayoutParams(WRAP_CONTENT, WRAP_CONTENT);
+ if (getOrientation() == VERTICAL) {
+ mPressedKeyLayoutParams.setMargins(0, keySeparationMargin, 0, 0);
+ } else {
+ mPressedKeyLayoutParams.setMargins(keySeparationMargin, 0, 0, 0);
+ }
+ }
+
+ public void handleKeyPressed(PressedKeyView pressedKeyView) {
+ addView(pressedKeyView, getChildCount(), mPressedKeyLayoutParams);
+ invalidate();
+ }
+
+ public void handleKeyRepeat(PressedKeyView repeatedKeyView) {
+ // Do nothing for now.
+ }
+
+ public void handleKeyRelease(PressedKeyView releasedKeyView) {
+ releasedKeyView.setHighlighted(false);
+ releasedKeyView.clearAnimation();
+ releasedKeyView.animate()
+ .alpha(0)
+ .setDuration(KEY_FADEOUT_DURATION_MILLIS)
+ .setInterpolator(new AccelerateInterpolator())
+ .withEndAction(this::cleanUpPressedKeyViews)
+ .start();
+ }
+
+ private void cleanUpPressedKeyViews() {
+ int numChildrenToRemove = 0;
+ for (int i = 0; i < getChildCount(); i++) {
+ final View child = getChildAt(i);
+ if (child.getAlpha() != 0) {
+ break;
+ }
+ child.setVisibility(View.GONE);
+ child.clearAnimation();
+ numChildrenToRemove++;
+ }
+ removeViews(0, numChildrenToRemove);
+ invalidate();
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/input/debug/RotaryInputGraphView.java b/services/core/java/com/android/server/input/debug/RotaryInputGraphView.java
new file mode 100644
index 0000000..95635d9
--- /dev/null
+++ b/services/core/java/com/android/server/input/debug/RotaryInputGraphView.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright 2023 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.input.debug;
+
+import static android.util.TypedValue.COMPLEX_UNIT_SP;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.View;
+import android.view.ViewConfiguration;
+
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Shows a graph with the rotary input values as a function of time.
+ * The graph gets reset if no action is received for a certain amount of time.
+ */
+public class RotaryInputGraphView extends View {
+
+ private static final int FRAME_COLOR = 0xbf741b47;
+ private static final int FRAME_WIDTH_SP = 2;
+ private static final int FRAME_BORDER_GAP_SP = 10;
+ private static final int FRAME_TEXT_SIZE_SP = 10;
+ private static final int FRAME_TEXT_OFFSET_SP = 2;
+ private static final int GRAPH_COLOR = 0xffff00ff;
+ private static final int GRAPH_LINE_WIDTH_SP = 1;
+ private static final int GRAPH_POINT_RADIUS_SP = 4;
+ private static final long MAX_SHOWN_TIME_INTERVAL = TimeUnit.SECONDS.toMillis(5);
+ private static final float DEFAULT_FRAME_CENTER_POSITION = 0;
+ private static final int MAX_GRAPH_VALUES_SIZE = 400;
+ /** Maximum time between values so that they are considered part of the same gesture. */
+ private static final long MAX_GESTURE_TIME = TimeUnit.SECONDS.toMillis(1);
+
+ private final DisplayMetrics mDm;
+ /**
+ * Distance in position units (amount scrolled in display pixels) from the center to the
+ * top/bottom frame lines.
+ */
+ private final float mFrameCenterToBorderDistance;
+ private final float mScaledVerticalScrollFactor;
+ private final Locale mDefaultLocale = Locale.getDefault();
+ private final Paint mFramePaint = new Paint();
+ private final Paint mFrameTextPaint = new Paint();
+ private final Paint mGraphLinePaint = new Paint();
+ private final Paint mGraphPointPaint = new Paint();
+
+ private final CyclicBuffer mGraphValues = new CyclicBuffer(MAX_GRAPH_VALUES_SIZE);
+ /** Position at which graph values are placed at the center of the graph. */
+ private float mFrameCenterPosition = DEFAULT_FRAME_CENTER_POSITION;
+
+ public RotaryInputGraphView(Context c) {
+ super(c);
+
+ mDm = mContext.getResources().getDisplayMetrics();
+ // This makes the center-to-border distance equivalent to the display height, meaning
+ // that the total height of the graph is equivalent to 2x the display height.
+ mFrameCenterToBorderDistance = mDm.heightPixels;
+ mScaledVerticalScrollFactor = ViewConfiguration.get(c).getScaledVerticalScrollFactor();
+
+ mFramePaint.setColor(FRAME_COLOR);
+ mFramePaint.setStrokeWidth(applyDimensionSp(FRAME_WIDTH_SP, mDm));
+
+ mFrameTextPaint.setColor(GRAPH_COLOR);
+ mFrameTextPaint.setTextSize(applyDimensionSp(FRAME_TEXT_SIZE_SP, mDm));
+
+ mGraphLinePaint.setColor(GRAPH_COLOR);
+ mGraphLinePaint.setStrokeWidth(applyDimensionSp(GRAPH_LINE_WIDTH_SP, mDm));
+ mGraphLinePaint.setStrokeCap(Paint.Cap.ROUND);
+ mGraphLinePaint.setStrokeJoin(Paint.Join.ROUND);
+
+ mGraphPointPaint.setColor(GRAPH_COLOR);
+ mGraphPointPaint.setStrokeWidth(applyDimensionSp(GRAPH_POINT_RADIUS_SP, mDm));
+ mGraphPointPaint.setStrokeCap(Paint.Cap.ROUND);
+ mGraphPointPaint.setStrokeJoin(Paint.Join.ROUND);
+ }
+
+ /**
+ * Reads new scroll axis value and updates the list accordingly. Old positions are
+ * kept at the front (what you would get with getFirst), while the recent positions are
+ * kept at the back (what you would get with getLast). Also updates the frame center
+ * position to handle out-of-bounds cases.
+ */
+ public void addValue(float scrollAxisValue, long eventTime) {
+ // Remove values that are too old.
+ while (mGraphValues.getSize() > 0
+ && (eventTime - mGraphValues.getFirst().mTime) > MAX_SHOWN_TIME_INTERVAL) {
+ mGraphValues.removeFirst();
+ }
+
+ // If there are no recent values, reset the frame center.
+ if (mGraphValues.getSize() == 0) {
+ mFrameCenterPosition = DEFAULT_FRAME_CENTER_POSITION;
+ }
+
+ // Handle new value. We multiply the scroll axis value by the scaled scroll factor to
+ // get the amount of pixels to be scrolled. We also compute the accumulated position
+ // by adding the current value to the last one (if not empty).
+ final float displacement = scrollAxisValue * mScaledVerticalScrollFactor;
+ final float prevPos = (mGraphValues.getSize() == 0 ? 0 : mGraphValues.getLast().mPos);
+ final float pos = prevPos + displacement;
+
+ mGraphValues.add(pos, eventTime);
+
+ // The difference between the distance of the most recent position from the center
+ // frame (pos - mFrameCenterPosition) and the maximum allowed distance from the center
+ // frame (mFrameCenterToBorderDistance).
+ final float verticalDiff = Math.abs(pos - mFrameCenterPosition)
+ - mFrameCenterToBorderDistance;
+ // If needed, translate frame.
+ if (verticalDiff > 0) {
+ final int sign = pos - mFrameCenterPosition < 0 ? -1 : 1;
+ // Here, we update the center frame position by the exact amount needed for us to
+ // stay within the maximum allowed distance from the center frame.
+ mFrameCenterPosition += sign * verticalDiff;
+ }
+
+ // Redraw canvas.
+ invalidate();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ // Note: vertical coordinates in Canvas go from top to bottom,
+ // that is bottomY > middleY > topY.
+ final int verticalMargin = applyDimensionSp(FRAME_BORDER_GAP_SP, mDm);
+ final int topY = verticalMargin;
+ final int bottomY = getHeight() - verticalMargin;
+ final int middleY = (topY + bottomY) / 2;
+
+ // Note: horizontal coordinates in Canvas go from left to right,
+ // that is rightX > leftX.
+ final int leftX = 0;
+ final int rightX = getWidth();
+
+ // Draw the frame, which includes 3 lines that show the maximum,
+ // minimum and middle positions of the graph.
+ canvas.drawLine(leftX, topY, rightX, topY, mFramePaint);
+ canvas.drawLine(leftX, middleY, rightX, middleY, mFramePaint);
+ canvas.drawLine(leftX, bottomY, rightX, bottomY, mFramePaint);
+
+ // Draw the position that each frame line corresponds to.
+ final int frameTextOffset = applyDimensionSp(FRAME_TEXT_OFFSET_SP, mDm);
+ canvas.drawText(
+ String.format(mDefaultLocale, "%.1f",
+ mFrameCenterPosition + mFrameCenterToBorderDistance),
+ leftX,
+ topY - frameTextOffset, mFrameTextPaint
+ );
+ canvas.drawText(
+ String.format(mDefaultLocale, "%.1f", mFrameCenterPosition),
+ leftX,
+ middleY - frameTextOffset, mFrameTextPaint
+ );
+ canvas.drawText(
+ String.format(mDefaultLocale, "%.1f",
+ mFrameCenterPosition - mFrameCenterToBorderDistance),
+ leftX,
+ bottomY - frameTextOffset, mFrameTextPaint
+ );
+
+ // If there are no graph values to be drawn, stop here.
+ if (mGraphValues.getSize() == 0) {
+ return;
+ }
+
+ // Draw the graph using the times and positions.
+ // We start at the most recent value (which should be drawn at the right) and move
+ // to the older values (which should be drawn to the left of more recent ones). Negative
+ // indices are handled by circuling back to the end of the buffer.
+ final long mostRecentTime = mGraphValues.getLast().mTime;
+ float prevCoordX = 0;
+ float prevCoordY = 0;
+ float prevAge = 0;
+ for (Iterator<GraphValue> iter = mGraphValues.reverseIterator(); iter.hasNext();) {
+ final GraphValue value = iter.next();
+
+ final int age = (int) (mostRecentTime - value.mTime);
+ final float pos = value.mPos;
+
+ // We get the horizontal coordinate in time units from left to right with
+ // (MAX_SHOWN_TIME_INTERVAL - age). Then, we rescale it to match the canvas
+ // units by dividing it by the time-domain length (MAX_SHOWN_TIME_INTERVAL)
+ // and by multiplying it by the canvas length (rightX - leftX). Finally, we
+ // offset the coordinate by adding it to leftX.
+ final float coordX = leftX + ((float) (MAX_SHOWN_TIME_INTERVAL - age)
+ / MAX_SHOWN_TIME_INTERVAL) * (rightX - leftX);
+
+ // We get the vertical coordinate in position units from middle to top with
+ // (pos - mFrameCenterPosition). Then, we rescale it to match the canvas
+ // units by dividing it by half of the position-domain length
+ // (mFrameCenterToBorderDistance) and by multiplying it by half of the canvas
+ // length (middleY - topY). Finally, we offset the coordinate by subtracting
+ // it from middleY (we can't "add" here because the coordinate grows from top
+ // to bottom).
+ final float coordY = middleY - ((pos - mFrameCenterPosition)
+ / mFrameCenterToBorderDistance) * (middleY - topY);
+
+ // Draw a point for this value.
+ canvas.drawPoint(coordX, coordY, mGraphPointPaint);
+
+ // If this value is part of the same gesture as the previous one, draw a line
+ // between them. We ignore the first value (with age = 0).
+ if (age != 0 && (age - prevAge) <= MAX_GESTURE_TIME) {
+ canvas.drawLine(prevCoordX, prevCoordY, coordX, coordY, mGraphLinePaint);
+ }
+
+ prevCoordX = coordX;
+ prevCoordY = coordY;
+ prevAge = age;
+ }
+ }
+
+ public float getFrameCenterPosition() {
+ return mFrameCenterPosition;
+ }
+
+ /**
+ * Converts a dimension in scaled pixel units to integer display pixels.
+ */
+ private static int applyDimensionSp(int dimensionSp, DisplayMetrics dm) {
+ return (int) TypedValue.applyDimension(COMPLEX_UNIT_SP, dimensionSp, dm);
+ }
+
+ /**
+ * Holds data needed to draw each entry in the graph.
+ */
+ private static class GraphValue {
+ /** Position. */
+ float mPos;
+ /** Time when this value was added. */
+ long mTime;
+
+ GraphValue(float pos, long time) {
+ this.mPos = pos;
+ this.mTime = time;
+ }
+ }
+
+ /**
+ * Holds the graph values as a cyclic buffer. It has a fixed capacity, and it replaces the
+ * old values with new ones to avoid creating new objects.
+ */
+ private static class CyclicBuffer {
+ private final GraphValue[] mValues;
+ private final int mCapacity;
+ private int mSize = 0;
+ private int mLastIndex = 0;
+
+ // The iteration index and counter are here to make it easier to reset them.
+ /** Determines the value currently pointed by the iterator. */
+ private int mIteratorIndex;
+ /** Counts how many values have been iterated through. */
+ private int mIteratorCount;
+
+ /** Used traverse the values in reverse order. */
+ private final Iterator<GraphValue> mReverseIterator = new Iterator<GraphValue>() {
+ @Override
+ public boolean hasNext() {
+ return mIteratorCount <= mSize;
+ }
+
+ @Override
+ public GraphValue next() {
+ // Returns the value currently pointed by the iterator and moves the iterator to
+ // the previous one.
+ mIteratorCount++;
+ return mValues[(mIteratorIndex-- + mCapacity) % mCapacity];
+ }
+ };
+
+ CyclicBuffer(int capacity) {
+ mCapacity = capacity;
+ mValues = new GraphValue[capacity];
+ }
+
+ /**
+ * Add new graph value. If there is an existing object, we replace its data with the
+ * new one. With this, we re-use old objects instead of creating new ones.
+ */
+ void add(float pos, long time) {
+ mLastIndex = (mLastIndex + 1) % mCapacity;
+ if (mValues[mLastIndex] == null) {
+ mValues[mLastIndex] = new GraphValue(pos, time);
+ } else {
+ final GraphValue oldValue = mValues[mLastIndex];
+ oldValue.mPos = pos;
+ oldValue.mTime = time;
+ }
+
+ // If needed, account for new value in the buffer size.
+ if (mSize != mCapacity) {
+ mSize++;
+ }
+ }
+
+ int getSize() {
+ return mSize;
+ }
+
+ GraphValue getFirst() {
+ final int distanceBetweenLastAndFirst = (mCapacity - mSize) + 1;
+ final int firstIndex = (mLastIndex + distanceBetweenLastAndFirst) % mCapacity;
+ return mValues[firstIndex];
+ }
+
+ GraphValue getLast() {
+ return mValues[mLastIndex];
+ }
+
+ void removeFirst() {
+ mSize--;
+ }
+
+ /** Returns an iterator pointing at the last value. */
+ Iterator<GraphValue> reverseIterator() {
+ mIteratorIndex = mLastIndex;
+ mIteratorCount = 1;
+ return mReverseIterator;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/input/debug/RotaryInputValueView.java b/services/core/java/com/android/server/input/debug/RotaryInputValueView.java
new file mode 100644
index 0000000..9fadac5
--- /dev/null
+++ b/services/core/java/com/android/server/input/debug/RotaryInputValueView.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2023 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.input.debug;
+
+import static android.util.TypedValue.COMPLEX_UNIT_SP;
+
+import android.content.Context;
+import android.graphics.ColorFilter;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Typeface;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+import android.view.ViewConfiguration;
+import android.widget.TextView;
+
+import com.android.internal.R;
+
+import java.util.Locale;
+
+/**
+ * Draws the most recent rotary input value and indicates whether the source is active.
+ */
+public class RotaryInputValueView extends TextView {
+
+ private static final int INACTIVE_TEXT_COLOR = 0xffff00ff;
+ private static final int ACTIVE_TEXT_COLOR = 0xff420f28;
+ private static final int TEXT_SIZE_SP = 8;
+ private static final int SIDE_PADDING_SP = 4;
+ /** Determines how long the active status lasts. */
+ private static final int ACTIVE_STATUS_DURATION = 250 /* milliseconds */;
+ private static final ColorFilter ACTIVE_BACKGROUND_FILTER =
+ new ColorMatrixColorFilter(new float[]{
+ 0, 0, 0, 0, 255, // red
+ 0, 0, 0, 0, 0, // green
+ 0, 0, 0, 0, 255, // blue
+ 0, 0, 0, 0, 200 // alpha
+ });
+
+ private final Runnable mUpdateActivityStatusCallback = () -> updateActivityStatus(false);
+ private final float mScaledVerticalScrollFactor;
+ private final Locale mDefaultLocale = Locale.getDefault();
+
+ public RotaryInputValueView(Context c) {
+ super(c);
+
+ DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
+ mScaledVerticalScrollFactor = ViewConfiguration.get(c).getScaledVerticalScrollFactor();
+
+ setText(getFormattedValue(0));
+ setTextColor(INACTIVE_TEXT_COLOR);
+ setTextSize(applyDimensionSp(TEXT_SIZE_SP, dm));
+ setPaddingRelative(applyDimensionSp(SIDE_PADDING_SP, dm), 0,
+ applyDimensionSp(SIDE_PADDING_SP, dm), 0);
+ setTypeface(null, Typeface.BOLD);
+ setBackgroundResource(R.drawable.focus_event_rotary_input_background);
+ }
+
+ /** Updates the shown text with the formatted value. */
+ public void updateValue(float value) {
+ removeCallbacks(mUpdateActivityStatusCallback);
+
+ setText(getFormattedValue(value * mScaledVerticalScrollFactor));
+
+ updateActivityStatus(true);
+ postDelayed(mUpdateActivityStatusCallback, ACTIVE_STATUS_DURATION);
+ }
+
+ /** Updates whether or not there's active rotary input. */
+ public void updateActivityStatus(boolean active) {
+ if (active) {
+ setTextColor(ACTIVE_TEXT_COLOR);
+ getBackground().setColorFilter(ACTIVE_BACKGROUND_FILTER);
+ } else {
+ setTextColor(INACTIVE_TEXT_COLOR);
+ getBackground().clearColorFilter();
+ }
+ }
+
+ private String getFormattedValue(float value) {
+ return String.format(mDefaultLocale, "%s%.1f", value < 0 ? "-" : "+", Math.abs(value));
+ }
+
+ /**
+ * Converts a dimension in scaled pixel units to integer display pixels.
+ */
+ private static int applyDimensionSp(int dimensionSp, DisplayMetrics dm) {
+ return (int) TypedValue.applyDimension(COMPLEX_UNIT_SP, dimensionSp, dm);
+ }
+}
diff --git a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
index 7726f40..dbbbed3 100644
--- a/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
+++ b/services/core/java/com/android/server/inputmethod/HandwritingEventReceiverSurface.java
@@ -57,13 +57,13 @@
InputConfig.NOT_FOCUSABLE
| InputConfig.NOT_TOUCHABLE
| InputConfig.SPY
- | InputConfig.INTERCEPTS_STYLUS
- | InputConfig.TRUSTED_OVERLAY;
+ | InputConfig.INTERCEPTS_STYLUS;
// Configure the surface to receive stylus events across the entire display.
mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+ mWindowHandle.setTrustedOverlay(t, mInputSurface, true);
t.setInputWindowInfo(mInputSurface, mWindowHandle);
t.setLayer(mInputSurface, InputManagerService.INPUT_OVERLAY_LAYER_HANDWRITING_SURFACE);
t.setPosition(mInputSurface, 0, 0);
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
index 93c66a1..08cf3f7 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -1431,13 +1431,17 @@
mContextHubWrapper.onBtMainSettingChanged(btEnabled);
}
} else {
- Log.d(TAG, "BT adapter not available. Defaulting to disabled");
- if (forceUpdate || mIsBtMainEnabled) {
- mIsBtMainEnabled = false;
+ Log.d(TAG, "BT adapter not available. Getting permissions from user settings");
+ boolean btEnabled = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.BLUETOOTH_ON, 0) == 1;
+ boolean btScanEnabled = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE, 0) == 1;
+ if (forceUpdate || mIsBtMainEnabled != btEnabled) {
+ mIsBtMainEnabled = btEnabled;
mContextHubWrapper.onBtMainSettingChanged(mIsBtMainEnabled);
}
- if (forceUpdate || mIsBtScanningEnabled) {
- mIsBtScanningEnabled = false;
+ if (forceUpdate || mIsBtScanningEnabled != btScanEnabled) {
+ mIsBtScanningEnabled = btScanEnabled;
mContextHubWrapper.onBtScanningSettingChanged(mIsBtScanningEnabled);
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationBitmapJobService.java b/services/core/java/com/android/server/notification/NotificationBitmapJobService.java
index 4335a1d..e1a0707 100644
--- a/services/core/java/com/android/server/notification/NotificationBitmapJobService.java
+++ b/services/core/java/com/android/server/notification/NotificationBitmapJobService.java
@@ -29,7 +29,12 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
-import java.util.Calendar;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.ZonedDateTime;
+import java.time.ZoneId;
/**
* This service runs everyday at 2am local time to remove expired bitmaps.
@@ -69,26 +74,25 @@
* @return Milliseconds until the next time the job should run.
*/
private static long getRunAfterMs() {
- Calendar cal = Calendar.getInstance(); // Uses local time zone
- final long now = cal.getTimeInMillis();
+ ZoneId zoneId = ZoneId.systemDefault();
+ ZonedDateTime now = Instant.now().atZone(zoneId);
- cal.set(Calendar.HOUR_OF_DAY, 2);
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.MILLISECOND, 0);
- final long today2AM = cal.getTimeInMillis();
+ LocalDate today = now.toLocalDate();
+ LocalTime twoAM = LocalTime.of(/* hour= */ 2, /* minute= */ 0);
- cal.add(Calendar.DAY_OF_YEAR, 1);
- final long tomorrow2AM = cal.getTimeInMillis();
+ ZonedDateTime today2AM = ZonedDateTime.of(today, twoAM, zoneId);
+ ZonedDateTime tomorrow2AM = today2AM.plusDays(1);
return getTimeUntilRemoval(now, today2AM, tomorrow2AM);
}
@VisibleForTesting
- static long getTimeUntilRemoval(long now, long today2AM, long tomorrow2AM) {
- if (now < today2AM) {
- return today2AM - now;
+ static long getTimeUntilRemoval(ZonedDateTime now, ZonedDateTime today2AM,
+ ZonedDateTime tomorrow2AM) {
+ if (Duration.between(now, today2AM).isNegative()) {
+ return Duration.between(now, tomorrow2AM).toMillis();
}
- return tomorrow2AM - now;
+ return Duration.between(now, today2AM).toMillis();
}
@Override
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryJobService.java b/services/core/java/com/android/server/notification/NotificationHistoryJobService.java
index 3776ad7..c9317d1 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryJobService.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryJobService.java
@@ -27,6 +27,7 @@
import android.os.CancellationSignal;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import java.util.concurrent.TimeUnit;
@@ -77,5 +78,11 @@
}
return false;
}
+
+ @Override
+ @VisibleForTesting
+ protected void attachBaseContext(Context base) {
+ super.attachBaseContext(base);
+ }
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index db69d93..87c3067 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -396,7 +396,7 @@
static final int MESSAGE_FINISH_TOKEN_TIMEOUT = 7;
static final int MESSAGE_ON_PACKAGE_CHANGED = 8;
- static final long BITMAP_EXPIRATION_TIME_MS = TimeUnit.HOURS.toMillis(24);
+ static final Duration BITMAP_DURATION = Duration.ofHours(24);
// ranking thread messages
private static final int MESSAGE_RECONSIDER_RANKING = 1000;
@@ -6705,7 +6705,7 @@
final long timePostedMs = r.getSbn().getPostTime();
final long timeNowMs = System.currentTimeMillis();
- if (isBitmapExpired(timePostedMs, timeNowMs, BITMAP_EXPIRATION_TIME_MS)) {
+ if (isBitmapExpired(timePostedMs, timeNowMs, BITMAP_DURATION.toMillis())) {
removeBitmapAndRepost(r);
}
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 071a036..68a8e40 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -75,13 +75,13 @@
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.multiuser.Flags;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Environment;
import android.os.FileUtils;
+import android.os.Flags;
import android.os.Handler;
import android.os.IBinder;
import android.os.IProgressListener;
@@ -286,6 +286,8 @@
private static final int USER_VERSION = 11;
+ private static final int MAX_USER_STRING_LENGTH = 500;
+
private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms
static final int WRITE_USER_MSG = 1;
@@ -1557,7 +1559,7 @@
logQuietModeEnabled(userId, enableQuietMode, callingPackage);
// Broadcast generic intents for all profiles
- if (android.os.Flags.allowPrivateProfile()) {
+ if (Flags.allowPrivateProfile()) {
broadcastProfileAvailabilityChanges(profile, parent.getUserHandle(),
enableQuietMode, false);
}
@@ -3783,8 +3785,6 @@
@GuardedBy({"mPackagesLock"})
private void readUserListLP() {
- // Whether guest restrictions are present on userlist.xml
- boolean guestRestrictionsArePresentOnUserListXml = false;
try (ResilientAtomicFile file = getUserListFile()) {
FileInputStream fin = null;
try {
@@ -3834,7 +3834,6 @@
}
}
} else if (name.equals(TAG_GUEST_RESTRICTIONS)) {
- guestRestrictionsArePresentOnUserListXml = true;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& type != XmlPullParser.END_TAG) {
if (type == XmlPullParser.START_TAG) {
@@ -3853,7 +3852,6 @@
updateUserIds();
upgradeIfNecessaryLP();
- updateUsersWithFeatureFlags(guestRestrictionsArePresentOnUserListXml);
} catch (Exception e) {
// Remove corrupted file and retry.
file.failRead(fin, e);
@@ -3879,25 +3877,6 @@
}
/**
- * Update any user formats or Xml data that need to be updated based on the current user state
- * and the feature flag settings.
- */
- @GuardedBy({"mPackagesLock"})
- private void updateUsersWithFeatureFlags(boolean guestRestrictionsArePresentOnUserListXml) {
- // User Xml re-writes are required when guest restrictions are saved on userlist.xml but
- // as per the feature flag it should be on the SYSTEM user's xml or guest restrictions
- // are saved on SYSTEM user's xml but as per the flags it should not be saved there.
- if (guestRestrictionsArePresentOnUserListXml
- == Flags.saveGlobalAndGuestRestrictionsOnSystemUserXml()) {
- for (int userId: getUserIds()) {
- writeUserLP(getUserDataNoChecks(userId));
- }
-
- writeUserListLP();
- }
- }
-
- /**
* Version of {@link #upgradeIfNecessaryLP()} that takes in the userVersion for testing
* purposes. For non-tests, use {@link #upgradeIfNecessaryLP()}.
*/
@@ -4397,39 +4376,26 @@
// Write seed data
if (userData.persistSeedData) {
if (userData.seedAccountName != null) {
- serializer.attribute(null, ATTR_SEED_ACCOUNT_NAME, userData.seedAccountName);
+ serializer.attribute(null, ATTR_SEED_ACCOUNT_NAME,
+ truncateString(userData.seedAccountName));
}
if (userData.seedAccountType != null) {
- serializer.attribute(null, ATTR_SEED_ACCOUNT_TYPE, userData.seedAccountType);
+ serializer.attribute(null, ATTR_SEED_ACCOUNT_TYPE,
+ truncateString(userData.seedAccountType));
}
}
if (userInfo.name != null) {
serializer.startTag(null, TAG_NAME);
- serializer.text(userInfo.name);
+ serializer.text(truncateString(userInfo.name));
serializer.endTag(null, TAG_NAME);
}
synchronized (mRestrictionsLock) {
UserRestrictionsUtils.writeRestrictions(serializer,
mBaseUserRestrictions.getRestrictions(userInfo.id), TAG_RESTRICTIONS);
- if (Flags.saveGlobalAndGuestRestrictionsOnSystemUserXml()) {
- if (userInfo.id == UserHandle.USER_SYSTEM) {
- UserRestrictionsUtils.writeRestrictions(serializer,
- mDevicePolicyUserRestrictions.getRestrictions(UserHandle.USER_ALL),
- TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS);
-
- serializer.startTag(null, TAG_GUEST_RESTRICTIONS);
- synchronized (mGuestRestrictions) {
- UserRestrictionsUtils.writeRestrictions(serializer, mGuestRestrictions,
- TAG_RESTRICTIONS);
- }
- serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
- }
- } else {
- UserRestrictionsUtils.writeRestrictions(serializer,
- mDevicePolicyUserRestrictions.getRestrictions(UserHandle.USER_ALL),
- TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS);
- }
+ UserRestrictionsUtils.writeRestrictions(serializer,
+ mDevicePolicyUserRestrictions.getRestrictions(UserHandle.USER_ALL),
+ TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS);
UserRestrictionsUtils.writeRestrictions(serializer,
mDevicePolicyUserRestrictions.getRestrictions(userInfo.id),
@@ -4469,6 +4435,13 @@
serializer.endDocument();
}
+ private String truncateString(String original) {
+ if (original == null || original.length() <= MAX_USER_STRING_LENGTH) {
+ return original;
+ }
+ return original.substring(0, MAX_USER_STRING_LENGTH);
+ }
+
/*
* Writes the user list file in this format:
*
@@ -4498,15 +4471,12 @@
serializer.attributeInt(null, ATTR_USER_VERSION, mUserVersion);
serializer.attributeInt(null, ATTR_USER_TYPE_VERSION, mUserTypeVersion);
- if (!Flags.saveGlobalAndGuestRestrictionsOnSystemUserXml()) {
- serializer.startTag(null, TAG_GUEST_RESTRICTIONS);
- synchronized (mGuestRestrictions) {
- UserRestrictionsUtils
- .writeRestrictions(serializer, mGuestRestrictions,
- TAG_RESTRICTIONS);
- }
- serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
+ serializer.startTag(null, TAG_GUEST_RESTRICTIONS);
+ synchronized (mGuestRestrictions) {
+ UserRestrictionsUtils
+ .writeRestrictions(serializer, mGuestRestrictions, TAG_RESTRICTIONS);
}
+ serializer.endTag(null, TAG_GUEST_RESTRICTIONS);
int[] userIdsToWrite;
synchronized (mUsersLock) {
userIdsToWrite = new int[mUsers.size()];
@@ -4650,19 +4620,6 @@
localRestrictions = UserRestrictionsUtils.readRestrictions(parser);
} else if (TAG_DEVICE_POLICY_GLOBAL_RESTRICTIONS.equals(tag)) {
globalRestrictions = UserRestrictionsUtils.readRestrictions(parser);
- } else if (name.equals(TAG_GUEST_RESTRICTIONS)) {
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
- && type != XmlPullParser.END_TAG) {
- if (type == XmlPullParser.START_TAG) {
- if (parser.getName().equals(TAG_RESTRICTIONS)) {
- synchronized (mGuestRestrictions) {
- UserRestrictionsUtils
- .readRestrictions(parser, mGuestRestrictions);
- }
- }
- break;
- }
- }
} else if (TAG_ACCOUNT.equals(tag)) {
type = parser.next();
if (type == XmlPullParser.TEXT) {
@@ -4923,7 +4880,7 @@
@UserIdInt int parentId, boolean preCreate, @Nullable String[] disallowedPackages,
@NonNull TimingsTraceAndSlog t, @Nullable Object token)
throws UserManager.CheckedUserOperationException {
-
+ String truncatedName = truncateString(name);
final UserTypeDetails userTypeDetails = mUserTypes.get(userType);
if (userTypeDetails == null) {
throwCheckedUserOperationException(
@@ -4958,8 +4915,8 @@
// Try to use a pre-created user (if available).
if (!preCreate && parentId < 0 && isUserTypeEligibleForPreCreation(userTypeDetails)) {
- final UserInfo preCreatedUser = convertPreCreatedUserIfPossible(userType, flags, name,
- token);
+ final UserInfo preCreatedUser = convertPreCreatedUserIfPossible(userType, flags,
+ truncatedName, token);
if (preCreatedUser != null) {
return preCreatedUser;
}
@@ -5054,7 +5011,7 @@
flags |= UserInfo.FLAG_EPHEMERAL_ON_CREATE;
}
- userInfo = new UserInfo(userId, name, null, flags, userType);
+ userInfo = new UserInfo(userId, truncatedName, null, flags, userType);
userInfo.serialNumber = mNextSerialNumber++;
userInfo.creationTime = getCreationTime();
userInfo.partial = true;
@@ -6510,8 +6467,8 @@
Slog.e(LOG_TAG, "No such user for settings seed data u=" + userId);
return;
}
- userData.seedAccountName = accountName;
- userData.seedAccountType = accountType;
+ userData.seedAccountName = truncateString(accountName);
+ userData.seedAccountType = truncateString(accountType);
userData.seedAccountOptions = accountOptions;
userData.persistSeedData = persist;
}
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index ebc7163..b83421f 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -42,6 +42,7 @@
import android.os.Process;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.permission.flags.Flags;
import android.service.voice.VoiceInteractionManagerInternal;
import android.service.voice.VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity;
import android.text.TextUtils;
@@ -75,9 +76,6 @@
private static final boolean SYSPROP_HOTWORD_DETECTION_SERVICE_REQUIRED =
SystemProperties.getBoolean("ro.hotword.detection_service_required", false);
- //TODO(b/289087412): import this from the flag value in set up in device config.
- private static final boolean IS_VOICE_ACTIVATION_OP_ENABLED = false;
-
@NonNull
private final Object mLock = new Object();
@@ -212,7 +210,7 @@
* @return the op that should be noted for the voice activations of the app by detected hotword.
*/
public static int getVoiceActivationOp() {
- if (IS_VOICE_ACTIVATION_OP_ENABLED) {
+ if (Flags.voiceActivationPermissionApis()) {
return OP_RECEIVE_SANDBOX_TRIGGER_AUDIO;
}
return OP_RECORD_AUDIO_HOTWORD;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 097656c..3a6664a 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -333,6 +333,11 @@
static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP = 0;
static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME = 1;
+ // must match: config_shortPressOnSettingsBehavior in config.xml
+ static final int SHORT_PRESS_SETTINGS_NOTHING = 0;
+ static final int SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL = 1;
+ static final int LAST_SHORT_PRESS_SETTINGS_BEHAVIOR = SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL;
+
static final int PENDING_KEY_NULL = -1;
// Must match: config_shortPressOnStemPrimaryBehavior in config.xml
@@ -611,6 +616,9 @@
// What we do when the user double-taps on home
int mDoubleTapOnHomeBehavior;
+ // What we do when the user presses on settings
+ int mShortPressOnSettingsBehavior;
+
// Must match config_primaryShortPressTargetActivity in config.xml
ComponentName mPrimaryShortPressTargetActivity;
@@ -2766,6 +2774,13 @@
if (mPackageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)) {
mShortPressOnWindowBehavior = SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE;
}
+
+ mShortPressOnSettingsBehavior = res.getInteger(
+ com.android.internal.R.integer.config_shortPressOnSettingsBehavior);
+ if (mShortPressOnSettingsBehavior < SHORT_PRESS_SETTINGS_NOTHING
+ || mShortPressOnSettingsBehavior > LAST_SHORT_PRESS_SETTINGS_BEHAVIOR) {
+ mShortPressOnSettingsBehavior = SHORT_PRESS_SETTINGS_NOTHING;
+ }
}
private void updateSettings() {
@@ -3632,6 +3647,15 @@
Slog.wtf(TAG, "KEYCODE_STYLUS_BUTTON_* should be handled in"
+ " interceptKeyBeforeQueueing");
return true;
+ case KeyEvent.KEYCODE_SETTINGS:
+ if (mShortPressOnSettingsBehavior == SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL) {
+ if (!down) {
+ toggleNotificationPanel();
+ logKeyboardSystemsEvent(event, KeyboardLogEvent.TOGGLE_NOTIFICATION_PANEL);
+ }
+ return true;
+ }
+ break;
}
if (isValidGlobalKey(keyCode)
&& mGlobalKeyManager.handleGlobalKey(mContext, keyCode, event)) {
@@ -6272,6 +6296,9 @@
pw.print("mLongPressOnPowerBehavior=");
pw.println(longPressOnPowerBehaviorToString(mLongPressOnPowerBehavior));
pw.print(prefix);
+ pw.print("mShortPressOnSettingsBehavior=");
+ pw.println(shortPressOnSettingsBehaviorToString(mShortPressOnSettingsBehavior));
+ pw.print(prefix);
pw.print("mLongPressOnPowerAssistantTimeoutMs=");
pw.println(mLongPressOnPowerAssistantTimeoutMs);
pw.print(prefix);
@@ -6470,6 +6497,17 @@
}
}
+ private static String shortPressOnSettingsBehaviorToString(int behavior) {
+ switch (behavior) {
+ case SHORT_PRESS_SETTINGS_NOTHING:
+ return "SHORT_PRESS_SETTINGS_NOTHING";
+ case SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL:
+ return "SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL";
+ default:
+ return Integer.toString(behavior);
+ }
+ }
+
private static String veryLongPressOnPowerBehaviorToString(int behavior) {
switch (behavior) {
case VERY_LONG_PRESS_POWER_NOTHING:
diff --git a/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java b/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java
index 3d89afa..becbbf2 100644
--- a/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java
+++ b/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java
@@ -25,6 +25,8 @@
import android.util.Slog;
import android.util.SparseArray;
import android.view.HapticFeedbackConstants;
+import android.view.flags.FeatureFlags;
+import android.view.flags.FeatureFlagsImpl;
import com.android.internal.annotations.VisibleForTesting;
@@ -54,6 +56,7 @@
// If present and valid, a vibration here will be used for an effect.
// Otherwise, the system's default vibration will be used.
@Nullable private final SparseArray<VibrationEffect> mHapticCustomizations;
+ private final FeatureFlags mViewFeatureFlags;
/** @hide */
public HapticFeedbackVibrationProvider(Resources res, Vibrator vibrator) {
@@ -62,14 +65,16 @@
/** @hide */
public HapticFeedbackVibrationProvider(Resources res, VibratorInfo vibratorInfo) {
- this(res, vibratorInfo, loadHapticCustomizations(res, vibratorInfo));
+ this(res, vibratorInfo, loadHapticCustomizations(res, vibratorInfo),
+ new FeatureFlagsImpl());
}
/** @hide */
@VisibleForTesting HapticFeedbackVibrationProvider(
Resources res,
VibratorInfo vibratorInfo,
- @Nullable SparseArray<VibrationEffect> hapticCustomizations) {
+ @Nullable SparseArray<VibrationEffect> hapticCustomizations,
+ FeatureFlags viewFeatureFlags) {
mVibratorInfo = vibratorInfo;
mHapticTextHandleEnabled = res.getBoolean(
com.android.internal.R.bool.config_enableHapticTextHandle);
@@ -78,6 +83,7 @@
hapticCustomizations = null;
}
mHapticCustomizations = hapticCustomizations;
+ mViewFeatureFlags = viewFeatureFlags;
mSafeModeEnabledVibrationEffect =
effectHasCustomization(HapticFeedbackConstants.SAFE_MODE_ENABLED)
@@ -201,12 +207,16 @@
default:
attrs = TOUCH_VIBRATION_ATTRIBUTES;
}
+
+ int flags = 0;
if (bypassVibrationIntensitySetting) {
- attrs = new VibrationAttributes.Builder(attrs)
- .setFlags(VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)
- .build();
+ flags |= VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF;
}
- return attrs;
+ if (shouldBypassInterruptionPolicy(effectId, mViewFeatureFlags)) {
+ flags |= VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY;
+ }
+
+ return flags == 0 ? attrs : new VibrationAttributes.Builder(attrs).setFlags(flags).build();
}
/** Dumps relevant state. */
@@ -295,4 +305,19 @@
return null;
}
}
+
+ private static boolean shouldBypassInterruptionPolicy(
+ int effectId, FeatureFlags viewFeatureFlags) {
+ switch (effectId) {
+ case HapticFeedbackConstants.SCROLL_TICK:
+ case HapticFeedbackConstants.SCROLL_ITEM_FOCUS:
+ case HapticFeedbackConstants.SCROLL_LIMIT:
+ // The SCROLL_* constants should bypass interruption filter, so that scroll haptics
+ // can play regardless of focus modes like DND. Guard this behavior by the feature
+ // flag controlling the general scroll feedback APIs.
+ return viewFeatureFlags.scrollFeedbackApi();
+ default:
+ return false;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index ee3d697..45bd152 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -448,6 +448,7 @@
String reason, IBinder token) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate, reason = " + reason);
try {
+ attrs = fixupVibrationAttributes(attrs, effect);
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.VIBRATE, "vibrate");
return vibrateInternal(uid, displayId, opPkg, effect, attrs, reason, token);
@@ -457,7 +458,7 @@
}
HalVibration vibrateWithoutPermissionCheck(int uid, int displayId, String opPkg,
- @NonNull CombinedVibration effect, @Nullable VibrationAttributes attrs,
+ @NonNull CombinedVibration effect, @NonNull VibrationAttributes attrs,
String reason, IBinder token) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate no perm check, reason = " + reason);
try {
@@ -468,7 +469,7 @@
}
private HalVibration vibrateInternal(int uid, int displayId, String opPkg,
- @NonNull CombinedVibration effect, @Nullable VibrationAttributes attrs,
+ @NonNull CombinedVibration effect, @NonNull VibrationAttributes attrs,
String reason, IBinder token) {
if (token == null) {
Slog.e(TAG, "token must not be null");
@@ -478,7 +479,6 @@
if (!isEffectValid(effect)) {
return null;
}
- attrs = fixupVibrationAttributes(attrs, effect);
// Create Vibration.Stats as close to the received request as possible, for tracking.
HalVibration vib = new HalVibration(token, effect,
new Vibration.CallerInfo(attrs, uid, displayId, opPkg, reason));
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index c39b266..4a5311b 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -577,7 +577,8 @@
.getRootTask(WINDOWING_MODE_UNDEFINED, activityType);
if (rootTask == null) return false;
final ActivityRecord r = rootTask.topRunningActivity();
- if (r == null || r.isVisibleRequested() || !r.attachedToProcess()
+ if (r == null || (r.isVisibleRequested() && rootTask.isTopRootTaskInDisplayArea())
+ || !r.attachedToProcess()
|| !r.mActivityComponent.equals(intent.getComponent())
|| !mService.isCallerRecents(r.getUid())
// Recents keeps invisible while device is locked.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 61bae71..0b67321 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -6448,19 +6448,8 @@
if (!restarting && hasVisibleActivities) {
deferWindowLayout();
try {
- final Task topTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
- if (topTask != null
- && topTask.topRunningActivity(true /* focusableOnly */) == null) {
- topTask.adjustFocusToNextFocusableTask("handleAppDied");
- }
- if (!mRootWindowContainer.resumeFocusedTasksTopActivities()) {
- // If there was nothing to resume, and we are not already restarting
- // this process, but there is a visible activity that is hosted by the
- // process...then make sure all visible activities are running, taking
- // care of restarting this process.
- mRootWindowContainer.ensureActivitiesVisible(null, 0,
- !PRESERVE_WINDOWS);
- }
+ mRootWindowContainer.ensureVisibilityOnVisibleActivityDiedOrCrashed(
+ "handleAppDied");
} finally {
continueWindowLayout();
}
@@ -6901,7 +6890,18 @@
@Override
public int finishTopCrashedActivities(WindowProcessController crashedApp, String reason) {
synchronized (mGlobalLock) {
- return mRootWindowContainer.finishTopCrashedActivities(crashedApp, reason);
+ deferWindowLayout();
+ try {
+ final Task finishedTask = mRootWindowContainer.finishTopCrashedActivities(
+ crashedApp, reason);
+ if (finishedTask != null) {
+ mRootWindowContainer.ensureVisibilityOnVisibleActivityDiedOrCrashed(reason);
+ return finishedTask.mTaskId;
+ }
+ return INVALID_TASK_ID;
+ } finally {
+ continueWindowLayout();
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index c2885da..4237668 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -163,7 +163,8 @@
if (window == null) {
EmbeddedWindowController.EmbeddedWindow embeddedWindow =
- wmService.mEmbeddedWindowController.getByFocusToken(focusedWindowToken);
+ wmService.mEmbeddedWindowController.getByInputTransferToken(
+ focusedWindowToken);
if (embeddedWindow != null) {
ProtoLog.d(WM_DEBUG_BACK_PREVIEW,
"Current focused window is embeddedWindow. Dispatch KEYCODE_BACK.");
diff --git a/services/core/java/com/android/server/wm/CompatModePackages.java b/services/core/java/com/android/server/wm/CompatModePackages.java
index 2439159..73bcc8d 100644
--- a/services/core/java/com/android/server/wm/CompatModePackages.java
+++ b/services/core/java/com/android/server/wm/CompatModePackages.java
@@ -66,29 +66,29 @@
public final class CompatModePackages {
/**
- * {@link CompatModePackages#DOWNSCALED_INVERSE} is the gatekeeper of all per-app buffer inverse
- * downscale changes. Enabling this change will allow the following scaling factors:
- * {@link CompatModePackages#DOWNSCALE_90}
- * {@link CompatModePackages#DOWNSCALE_85}
- * {@link CompatModePackages#DOWNSCALE_80}
- * {@link CompatModePackages#DOWNSCALE_75}
- * {@link CompatModePackages#DOWNSCALE_70}
- * {@link CompatModePackages#DOWNSCALE_65}
- * {@link CompatModePackages#DOWNSCALE_60}
- * {@link CompatModePackages#DOWNSCALE_55}
- * {@link CompatModePackages#DOWNSCALE_50}
- * {@link CompatModePackages#DOWNSCALE_45}
- * {@link CompatModePackages#DOWNSCALE_40}
- * {@link CompatModePackages#DOWNSCALE_35}
- * {@link CompatModePackages#DOWNSCALE_30}
+ * <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> is the gatekeeper of all per-app buffer
+ * inverse downscale changes. Enabling this change will allow the following scaling factors:
+ * <a href="#DOWNSCALE_90">DOWNSCALE_90</a>
+ * <a href="#DOWNSCALE_85">DOWNSCALE_85</a>
+ * <a href="#DOWNSCALE_80">DOWNSCALE_80</a>
+ * <a href="#DOWNSCALE_75">DOWNSCALE_75</a>
+ * <a href="#DOWNSCALE_70">DOWNSCALE_70</a>
+ * <a href="#DOWNSCALE_65">DOWNSCALE_65</a>
+ * <a href="#DOWNSCALE_60">DOWNSCALE_60</a>
+ * <a href="#DOWNSCALE_55">DOWNSCALE_55</a>
+ * <a href="#DOWNSCALE_50">DOWNSCALE_50</a>
+ * <a href="#DOWNSCALE_45">DOWNSCALE_45</a>
+ * <a href="#DOWNSCALE_40">DOWNSCALE_40</a>
+ * <a href="#DOWNSCALE_35">DOWNSCALE_35</a>
+ * <a href="#DOWNSCALE_30">DOWNSCALE_30</a>
*
- * If {@link CompatModePackages#DOWNSCALED_INVERSE} is enabled for an app package, then the app
- * will be forcibly resized to the lowest enabled scaling factor e.g. 1/0.8 if both 1/0.8 and
- * 1/0.7 (* 100%) were enabled.
+ * If <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> is enabled for an app package, then
+ * the app will be forcibly resized to the lowest enabled scaling factor e.g. 1/0.8 if both
+ * 1/0.8 and 1/0.7 (* 100%) were enabled.
*
- * When both {@link CompatModePackages#DOWNSCALED_INVERSE}
- * and {@link CompatModePackages#DOWNSCALED} are enabled, then
- * {@link CompatModePackages#DOWNSCALED_INVERSE} takes precedence.
+ * When both <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a>
+ * and <a href="#DOWNSCALED">DOWNSCALED</a> are enabled, then
+ * <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> takes precedence.
*/
@ChangeId
@Disabled
@@ -96,29 +96,29 @@
public static final long DOWNSCALED_INVERSE = 273564678L; // This is a Bug ID.
/**
- * {@link CompatModePackages#DOWNSCALED} is the gatekeeper of all per-app buffer downscaling
+ * <a href="#DOWNSCALED">DOWNSCALED</a> is the gatekeeper of all per-app buffer downscaling
* changes. Enabling this change will allow the following scaling factors:
- * {@link CompatModePackages#DOWNSCALE_90}
- * {@link CompatModePackages#DOWNSCALE_85}
- * {@link CompatModePackages#DOWNSCALE_80}
- * {@link CompatModePackages#DOWNSCALE_75}
- * {@link CompatModePackages#DOWNSCALE_70}
- * {@link CompatModePackages#DOWNSCALE_65}
- * {@link CompatModePackages#DOWNSCALE_60}
- * {@link CompatModePackages#DOWNSCALE_55}
- * {@link CompatModePackages#DOWNSCALE_50}
- * {@link CompatModePackages#DOWNSCALE_45}
- * {@link CompatModePackages#DOWNSCALE_40}
- * {@link CompatModePackages#DOWNSCALE_35}
- * {@link CompatModePackages#DOWNSCALE_30}
+ * <a href="#DOWNSCALE_90">DOWNSCALE_90</a>
+ * <a href="#DOWNSCALE_85">DOWNSCALE_85</a>
+ * <a href="#DOWNSCALE_80">DOWNSCALE_80</a>
+ * <a href="#DOWNSCALE_75">DOWNSCALE_75</a>
+ * <a href="#DOWNSCALE_70">DOWNSCALE_70</a>
+ * <a href="#DOWNSCALE_65">DOWNSCALE_65</a>
+ * <a href="#DOWNSCALE_60">DOWNSCALE_60</a>
+ * <a href="#DOWNSCALE_55">DOWNSCALE_55</a>
+ * <a href="#DOWNSCALE_50">DOWNSCALE_50</a>
+ * <a href="#DOWNSCALE_45">DOWNSCALE_45</a>
+ * <a href="#DOWNSCALE_40">DOWNSCALE_40</a>
+ * <a href="#DOWNSCALE_35">DOWNSCALE_35</a>
+ * <a href="#DOWNSCALE_30">DOWNSCALE_30</a>
*
- * If {@link CompatModePackages#DOWNSCALED} is enabled for an app package, then the app will be
+ * If <a href="#DOWNSCALED">DOWNSCALED</a> is enabled for an app package, then the app will be
* forcibly resized to the highest enabled scaling factor e.g. 80% if both 80% and 70% were
* enabled.
*
- * When both {@link CompatModePackages#DOWNSCALED_INVERSE}
- * and {@link CompatModePackages#DOWNSCALED} are enabled, then
- * {@link CompatModePackages#DOWNSCALED_INVERSE} takes precedence.
+ * When both <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a>
+ * and <a href="#DOWNSCALED">DOWNSCALED</a> are enabled, then
+ * <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> takes precedence.
*/
@ChangeId
@Disabled
@@ -126,12 +126,13 @@
public static final long DOWNSCALED = 168419799L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_90} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_90">DOWNSCALE_90</a> for a package will force the app to assume it's
* running on a display with 90% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 111.11% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 111.11% the vertical and horizontal resolution of
+ * the real display
*/
@ChangeId
@Disabled
@@ -139,12 +140,13 @@
public static final long DOWNSCALE_90 = 182811243L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_85} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_85">DOWNSCALE_85</a> for a package will force the app to assume it's
* running on a display with 85% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 117.65% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 117.65% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -152,12 +154,13 @@
public static final long DOWNSCALE_85 = 189969734L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_80} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_80">DOWNSCALE_80</a> for a package will force the app to assume it's
* running on a display with 80% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 125% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 125% the vertical and horizontal resolution of the real
+ * display
*/
@ChangeId
@Disabled
@@ -165,12 +168,13 @@
public static final long DOWNSCALE_80 = 176926753L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_75} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_75">DOWNSCALE_75</a> for a package will force the app to assume it's
* running on a display with 75% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 133.33% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 133.33% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -178,12 +182,13 @@
public static final long DOWNSCALE_75 = 189969779L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_70} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_70">DOWNSCALE_70</a> for a package will force the app to assume it's
* running on a display with 70% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 142.86% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 142.86% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -191,12 +196,13 @@
public static final long DOWNSCALE_70 = 176926829L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_65} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_65">DOWNSCALE_65</a> for a package will force the app to assume it's
* running on a display with 65% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 153.85% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 153.85% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -204,12 +210,13 @@
public static final long DOWNSCALE_65 = 189969744L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_60} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_60">DOWNSCALE_60</a> for a package will force the app to assume it's
* running on a display with 60% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 166.67% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 166.67% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -217,12 +224,13 @@
public static final long DOWNSCALE_60 = 176926771L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_55} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_55">DOWNSCALE_55</a> for a package will force the app to assume it's
* running on a display with 55% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 181.82% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 181.82% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -230,12 +238,13 @@
public static final long DOWNSCALE_55 = 189970036L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_50} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_50">DOWNSCALE_50</a> for a package will force the app to assume it's
* running on a display with 50% vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 200% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 200% the vertical and horizontal resolution of the real
+ * display
*/
@ChangeId
@Disabled
@@ -243,12 +252,13 @@
public static final long DOWNSCALE_50 = 176926741L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_45} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_45">DOWNSCALE_45</a> for a package will force the app to assume it's
* running on a display with 45% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 222.22% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 222.22% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -256,12 +266,13 @@
public static final long DOWNSCALE_45 = 189969782L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_40} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_40">DOWNSCALE_40</a> for a package will force the app to assume it's
* running on a display with 40% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 250% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 250% the vertical and horizontal resolution of the real
+ * display
*/
@ChangeId
@Disabled
@@ -269,12 +280,13 @@
public static final long DOWNSCALE_40 = 189970038L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_35} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_35">DOWNSCALE_35</a> for a package will force the app to assume it's
* running on a display with 35% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 285.71% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 285.71% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
@@ -282,12 +294,13 @@
public static final long DOWNSCALE_35 = 189969749L;
/**
- * With {@link CompatModePackages#DOWNSCALED} enabled, subsequently enabling change-id
- * {@link CompatModePackages#DOWNSCALE_30} for a package will force the app to assume it's
+ * With <a href="#DOWNSCALED">DOWNSCALED</a> enabled, subsequently enabling change-id
+ * <a href="#DOWNSCALE_30">DOWNSCALE_30</a> for a package will force the app to assume it's
* running on a display with 30% the vertical and horizontal resolution of the real display.
*
- * With {@link CompatModePackages#DOWNSCALED_INVERSE} enabled will force the app to assume it's
- * running on a display with 333.33% the vertical and horizontal resolution of the real display
+ * With <a href="#DOWNSCALED_INVERSE">DOWNSCALED_INVERSE</a> enabled will force the app to
+ * assume it's running on a display with 333.33% the vertical and horizontal resolution of the
+ * real display
*/
@ChangeId
@Disabled
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 0f1a105..7af4aad 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -48,7 +48,6 @@
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
-import android.os.InputConfig;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
@@ -186,6 +185,10 @@
// Crop the input surface to the display size.
mTmpClipRect.set(0, 0, mDisplaySize.x, mDisplaySize.y);
+ // Make trusted overlay to not block any touches while D&D ongoing and allowing
+ // touches to pass through to windows underneath. This allows user to interact with the
+ // UI to navigate while dragging.
+ h.setTrustedOverlay(mTransaction, mInputSurface, true);
mTransaction.show(mInputSurface)
.setInputWindowInfo(mInputSurface, h)
.setLayer(mInputSurface, Integer.MAX_VALUE)
@@ -377,11 +380,6 @@
mDragWindowHandle.ownerUid = MY_UID;
mDragWindowHandle.scaleFactor = 1.0f;
- // InputConfig.TRUSTED_OVERLAY: To not block any touches while D&D ongoing and allowing
- // touches to pass through to windows underneath. This allows user to interact with the
- // UI to navigate while dragging.
- mDragWindowHandle.inputConfig = InputConfig.TRUSTED_OVERLAY;
-
// The drag window cannot receive new touches.
mDragWindowHandle.touchableRegion.setEmpty();
diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
index c9bae12..275396f 100644
--- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java
+++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
@@ -45,8 +45,8 @@
private static final String TAG = TAG_WITH_CLASS_NAME ? "EmbeddedWindowController" : TAG_WM;
/* maps input token to an embedded window */
private ArrayMap<IBinder /*input token */, EmbeddedWindow> mWindows = new ArrayMap<>();
- private ArrayMap<IBinder /*focus grant token */, EmbeddedWindow> mWindowsByFocusToken =
- new ArrayMap<>();
+ private ArrayMap<IBinder /*input transfer token */, EmbeddedWindow>
+ mWindowsByInputTransferToken = new ArrayMap<>();
private ArrayMap<IBinder /*window token*/, EmbeddedWindow> mWindowsByWindowToken =
new ArrayMap<>();
private final Object mGlobalLock;
@@ -67,14 +67,14 @@
void add(IBinder inputToken, EmbeddedWindow window) {
try {
mWindows.put(inputToken, window);
- final IBinder focusToken = window.getFocusGrantToken();
- mWindowsByFocusToken.put(focusToken, window);
+ final IBinder inputTransferToken = window.getInputTransferToken();
+ mWindowsByInputTransferToken.put(inputTransferToken, window);
mWindowsByWindowToken.put(window.getWindowToken(), window);
updateProcessController(window);
window.mClient.asBinder().linkToDeath(()-> {
synchronized (mGlobalLock) {
mWindows.remove(inputToken);
- mWindowsByFocusToken.remove(focusToken);
+ mWindowsByInputTransferToken.remove(inputTransferToken);
}
}, 0);
} catch (RemoteException e) {
@@ -105,7 +105,7 @@
EmbeddedWindow ew = mWindows.valueAt(i);
if (ew.mClient.asBinder() == client.asBinder()) {
mWindows.removeAt(i).onRemoved();
- mWindowsByFocusToken.remove(ew.getFocusGrantToken());
+ mWindowsByInputTransferToken.remove(ew.getInputTransferToken());
mWindowsByWindowToken.remove(ew.getWindowToken());
return;
}
@@ -117,7 +117,7 @@
EmbeddedWindow ew = mWindows.valueAt(i);
if (ew.mHostWindowState == host) {
mWindows.removeAt(i).onRemoved();
- mWindowsByFocusToken.remove(ew.getFocusGrantToken());
+ mWindowsByInputTransferToken.remove(ew.getInputTransferToken());
mWindowsByWindowToken.remove(ew.getWindowToken());
}
}
@@ -127,8 +127,8 @@
return mWindows.get(inputToken);
}
- EmbeddedWindow getByFocusToken(IBinder focusGrantToken) {
- return mWindowsByFocusToken.get(focusGrantToken);
+ EmbeddedWindow getByInputTransferToken(IBinder inputTransferToken) {
+ return mWindowsByInputTransferToken.get(inputTransferToken);
}
EmbeddedWindow getByWindowToken(IBinder windowToken) {
@@ -153,7 +153,7 @@
* to request focus transfer to the embedded. This is not the input token since we don't
* want to give clients access to each others input token.
*/
- private final IBinder mFocusGrantToken;
+ private final IBinder mInputTransferToken;
private boolean mIsFocusable;
@@ -171,7 +171,7 @@
*/
EmbeddedWindow(Session session, WindowManagerService service, IWindow clientToken,
WindowState hostWindowState, int ownerUid, int ownerPid, int windowType,
- int displayId, IBinder focusGrantToken, String inputHandleName,
+ int displayId, IBinder inputTransferToken, String inputHandleName,
boolean isFocusable) {
mSession = session;
mWmService = service;
@@ -183,7 +183,7 @@
mOwnerPid = ownerPid;
mWindowType = windowType;
mDisplayId = displayId;
- mFocusGrantToken = focusGrantToken;
+ mInputTransferToken = inputTransferToken;
final String hostWindowName =
(mHostWindowState != null) ? "-" + mHostWindowState.getWindowTag().toString()
: "";
@@ -260,8 +260,8 @@
return mOwnerUid;
}
- IBinder getFocusGrantToken() {
- return mFocusGrantToken;
+ IBinder getInputTransferToken() {
+ return mInputTransferToken;
}
IBinder getInputChannelToken() {
@@ -290,7 +290,7 @@
// Use null session since this is being granted by system server and doesn't
// require the host session to be passed in
mWmService.grantEmbeddedWindowFocus(null, mHostWindowState.mClient,
- mFocusGrantToken, grantFocus);
+ mInputTransferToken, grantFocus);
if (grantFocus) {
// If granting focus to the embedded when tapped, we need to ensure the host
// gains focus as well or the transfer won't take effect since it requires
@@ -298,7 +298,7 @@
mHostWindowState.handleTapOutsideFocusInsideSelf();
}
} else {
- mWmService.grantEmbeddedWindowFocus(mSession, mFocusGrantToken, grantFocus);
+ mWmService.grantEmbeddedWindowFocus(mSession, mInputTransferToken, grantFocus);
}
}
}
diff --git a/services/core/java/com/android/server/wm/InputConsumerImpl.java b/services/core/java/com/android/server/wm/InputConsumerImpl.java
index 39622c1..c21930d 100644
--- a/services/core/java/com/android/server/wm/InputConsumerImpl.java
+++ b/services/core/java/com/android/server/wm/InputConsumerImpl.java
@@ -74,7 +74,7 @@
mWindowHandle.ownerPid = WindowManagerService.MY_PID;
mWindowHandle.ownerUid = WindowManagerService.MY_UID;
mWindowHandle.scaleFactor = 1.0f;
- mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.TRUSTED_OVERLAY;
+ mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE;
mInputSurface = mService.makeSurfaceBuilder(
mService.mRoot.getDisplayContent(displayId).getSession())
@@ -129,12 +129,14 @@
void show(SurfaceControl.Transaction t, WindowContainer w) {
t.show(mInputSurface);
+ mWindowHandle.setTrustedOverlay(t, mInputSurface, true);
t.setInputWindowInfo(mInputSurface, mWindowHandle);
t.setRelativeLayer(mInputSurface, w.getSurfaceControl(), 1);
}
void show(SurfaceControl.Transaction t, int layer) {
t.show(mInputSurface);
+ mWindowHandle.setTrustedOverlay(t, mInputSurface, true);
t.setInputWindowInfo(mInputSurface, mWindowHandle);
t.setLayer(mInputSurface, layer);
}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 825d38b..af307ec3 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -675,6 +675,11 @@
w.getKeyInterceptionInfo());
if (w.mWinAnimator.hasSurface()) {
+ // Update trusted overlay changes here because they are tied to input info. Input
+ // changes can be updated even if surfaces aren't.
+ inputWindowHandle.setTrustedOverlay(mInputTransaction,
+ w.mWinAnimator.mSurfaceController.mSurfaceControl,
+ w.isWindowTrustedOverlay());
populateInputWindowHandle(inputWindowHandle, w);
setInputWindowInfoIfNeeded(mInputTransaction,
w.mWinAnimator.mSurfaceController.mSurfaceControl, inputWindowHandle);
@@ -732,7 +737,7 @@
new InputWindowHandle(null /* inputApplicationHandle */, displayId));
inputWindowHandle.setName(name);
inputWindowHandle.setLayoutParamsType(TYPE_SECURE_SYSTEM_OVERLAY);
- inputWindowHandle.setTrustedOverlay(true);
+ inputWindowHandle.setTrustedOverlay(t, sc, true);
populateOverlayInputInfo(inputWindowHandle);
setInputWindowInfoIfNeeded(t, sc, inputWindowHandle);
}
diff --git a/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java b/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java
index 64b7a60..90d81bd 100644
--- a/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java
+++ b/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java
@@ -195,6 +195,11 @@
mChanged = true;
}
+ void setTrustedOverlay(SurfaceControl.Transaction t, SurfaceControl sc,
+ boolean trustedOverlay) {
+ mHandle.setTrustedOverlay(t, sc, trustedOverlay);
+ }
+
void setOwnerPid(int pid) {
if (mHandle.ownerPid == pid) {
return;
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index c3977d6..82d4b90 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -62,6 +62,7 @@
import android.window.TaskSnapshot;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.IResultReceiver;
import com.android.internal.protolog.common.ProtoLog;
import com.android.server.LocalServices;
import com.android.server.inputmethod.InputMethodManagerInternal;
@@ -244,7 +245,8 @@
}
@Override
- public void finish(boolean moveHomeToTop, boolean sendUserLeaveHint) {
+ public void finish(boolean moveHomeToTop, boolean sendUserLeaveHint,
+ IResultReceiver finishCb) {
ProtoLog.d(WM_DEBUG_RECENTS_ANIMATIONS,
"finish(%b): mCanceled=%b", moveHomeToTop, mCanceled);
final long token = Binder.clearCallingIdentity();
@@ -257,6 +259,13 @@
} finally {
Binder.restoreCallingIdentity(token);
}
+ if (finishCb != null) {
+ try {
+ finishCb.send(0, new Bundle());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to report animation finished", e);
+ }
+ }
}
@Override
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index a88aa2e..cf6a1fe 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2319,19 +2319,36 @@
*
* @param app The app that crashed.
* @param reason Reason to perform this action.
- * @return The task id that was finished in this root task, or INVALID_TASK_ID if none was
- * finished.
+ * @return The finished task which was on top or visible, otherwise {@code null} if the crashed
+ * app doesn't have activity in visible task.
*/
- int finishTopCrashedActivities(WindowProcessController app, String reason) {
+ @Nullable
+ Task finishTopCrashedActivities(WindowProcessController app, String reason) {
Task focusedRootTask = getTopDisplayFocusedRootTask();
final Task[] finishedTask = new Task[1];
forAllRootTasks(rootTask -> {
+ final boolean recordTopOrVisible = finishedTask[0] == null
+ && (focusedRootTask == rootTask || rootTask.isVisibleRequested());
final Task t = rootTask.finishTopCrashedActivityLocked(app, reason);
- if (rootTask == focusedRootTask || finishedTask[0] == null) {
+ if (recordTopOrVisible) {
finishedTask[0] = t;
}
});
- return finishedTask[0] != null ? finishedTask[0].mTaskId : INVALID_TASK_ID;
+ return finishedTask[0];
+ }
+
+ void ensureVisibilityOnVisibleActivityDiedOrCrashed(String reason) {
+ final Task topTask = getTopDisplayFocusedRootTask();
+ if (topTask != null && topTask.topRunningActivity(true /* focusableOnly */) == null) {
+ // Move the next focusable task to front.
+ topTask.adjustFocusToNextFocusableTask(reason);
+ }
+ if (!resumeFocusedTasksTopActivities()) {
+ // It may be nothing to resume because there are pausing activities or all the top
+ // activities are resumed. Then it still needs to make sure all visible activities are
+ // running in case the tasks were reordered or there are non-top visible activities.
+ ensureActivitiesVisible(null /* starting */, 0 /* configChanges */, !PRESERVE_WINDOWS);
+ }
}
boolean resumeFocusedTasksTopActivities() {
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index bbe44c5..e6d4866 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -884,8 +884,8 @@
@Override
public void grantInputChannel(int displayId, SurfaceControl surface,
IWindow window, IBinder hostInputToken, int flags, int privateFlags, int type,
- int inputFeatures, IBinder windowToken, IBinder focusGrantToken, String inputHandleName,
- InputChannel outInputChannel) {
+ int inputFeatures, IBinder windowToken, IBinder inputTransferToken,
+ String inputHandleName, InputChannel outInputChannel) {
if (hostInputToken == null && !mCanAddInternalSystemWindow) {
// Callers without INTERNAL_SYSTEM_WINDOW permission cannot grant input channel to
// embedded windows without providing a host window input token
@@ -896,7 +896,7 @@
try {
mService.grantInputChannel(this, mUid, mPid, displayId, surface, window, hostInputToken,
flags, mCanAddInternalSystemWindow ? privateFlags : 0,
- type, inputFeatures, windowToken, focusGrantToken, inputHandleName,
+ type, inputFeatures, windowToken, inputTransferToken, inputHandleName,
outInputChannel);
} finally {
Binder.restoreCallingIdentity(identity);
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index c6547a0..882104a 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -372,8 +372,7 @@
parent.forAllTasks(t -> {
// Skip transient-launch task
if (t == transientRootTask) return false;
- if (t.isVisibleRequested() && !t.isAlwaysOnTop()
- && !t.getWindowConfiguration().tasksAreFloating()) {
+ if (t.isVisibleRequested() && !t.isAlwaysOnTop()) {
if (t.isRootTask()) {
mTransientHideTasks.add(t);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 60dc84c..074b404 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2493,14 +2493,6 @@
outInsetsState.set(win.getCompatInsetsState(), true /* copySources */);
}
- // TODO (b/298562855): Remove this after identifying the reason why the frame is empty.
- if (win.mAttrs.providedInsets != null && win.getFrame().isEmpty()) {
- Slog.w(TAG, "Empty frame of " + win
- + " configChanged=" + configChanged
- + " frame=" + win.getFrame().toShortString()
- + " attrs=" + attrs);
- }
-
ProtoLog.v(WM_DEBUG_FOCUS, "Relayout of %s: focusMayChange=%b",
win, focusMayChange);
@@ -8803,7 +8795,7 @@
void grantInputChannel(Session session, int callingUid, int callingPid, int displayId,
SurfaceControl surface, IWindow window, IBinder hostInputToken,
int flags, int privateFlags, int inputFeatures, int type, IBinder windowToken,
- IBinder focusGrantToken, String inputHandleName, InputChannel outInputChannel) {
+ IBinder inputTransferToken, String inputHandleName, InputChannel outInputChannel) {
final int sanitizedType = sanitizeWindowType(session, displayId, windowToken, type);
final InputApplicationHandle applicationHandle;
final String name;
@@ -8812,7 +8804,7 @@
EmbeddedWindowController.EmbeddedWindow win =
new EmbeddedWindowController.EmbeddedWindow(session, this, window,
mInputToWindowMap.get(hostInputToken), callingUid, callingPid,
- sanitizedType, displayId, focusGrantToken, inputHandleName,
+ sanitizedType, displayId, inputTransferToken, inputHandleName,
(flags & FLAG_NOT_FOCUSABLE) == 0);
win.openInputChannel(outInputChannel);
mEmbeddedWindowController.add(outInputChannel.getToken(), win);
@@ -8884,11 +8876,6 @@
h.inputConfig |= InputConfig.NOT_FOCUSABLE;
}
- // Check private trusted overlay flag to set trustedOverlay field of input window handle.
- if ((privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0) {
- h.inputConfig |= InputConfig.TRUSTED_OVERLAY;
- }
-
h.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
h.ownerUid = callingUid;
h.ownerPid = callingPid;
@@ -8908,6 +8895,8 @@
}
final SurfaceControl.Transaction t = mTransactionFactory.get();
+ // Check private trusted overlay flag to set trustedOverlay field of input window handle.
+ h.setTrustedOverlay(t, surface, (privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0);
t.setInputWindowInfo(surface, h);
t.apply();
t.close();
@@ -9139,10 +9128,10 @@
return mPossibleDisplayInfoMapper.getPossibleDisplayInfos(displayId);
}
- void grantEmbeddedWindowFocus(Session session, IBinder focusToken, boolean grantFocus) {
+ void grantEmbeddedWindowFocus(Session session, IBinder inputTransferToken, boolean grantFocus) {
synchronized (mGlobalLock) {
final EmbeddedWindowController.EmbeddedWindow embeddedWindow =
- mEmbeddedWindowController.getByFocusToken(focusToken);
+ mEmbeddedWindowController.getByInputTransferToken(inputTransferToken);
if (embeddedWindow == null) {
Slog.e(TAG, "Embedded window not found");
return;
@@ -9187,8 +9176,8 @@
}
}
- void grantEmbeddedWindowFocus(Session session, IWindow callingWindow, IBinder targetFocusToken,
- boolean grantFocus) {
+ void grantEmbeddedWindowFocus(Session session, IWindow callingWindow,
+ IBinder inputTransferToken, boolean grantFocus) {
synchronized (mGlobalLock) {
final WindowState hostWindow =
windowForClientLocked(session, callingWindow, false /* throwOnError*/);
@@ -9201,7 +9190,7 @@
return;
}
final EmbeddedWindowController.EmbeddedWindow embeddedWindow =
- mEmbeddedWindowController.getByFocusToken(targetFocusToken);
+ mEmbeddedWindowController.getByInputTransferToken(inputTransferToken);
if (embeddedWindow == null) {
Slog.e(TAG, "Embedded window not found");
return;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ebef606..4beec2b 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -178,6 +178,7 @@
import static com.android.server.wm.WindowStateProto.VIEW_VISIBILITY;
import static com.android.server.wm.WindowStateProto.WINDOW_CONTAINER;
import static com.android.server.wm.WindowStateProto.WINDOW_FRAMES;
+import static com.android.window.flags.Flags.surfaceTrustedOverlay;
import android.annotation.CallSuper;
import android.annotation.NonNull;
@@ -1110,7 +1111,9 @@
mInputWindowHandle.setName(getName());
mInputWindowHandle.setPackageName(mAttrs.packageName);
mInputWindowHandle.setLayoutParamsType(mAttrs.type);
- mInputWindowHandle.setTrustedOverlay(shouldWindowHandleBeTrusted(s));
+ if (!surfaceTrustedOverlay()) {
+ mInputWindowHandle.setTrustedOverlay(isWindowTrustedOverlay());
+ }
if (DEBUG) {
Slog.v(TAG, "Window " + this + " client=" + c.asBinder()
+ " token=" + token + " (" + mAttrs.token + ")" + " params=" + a);
@@ -1185,12 +1188,12 @@
}
}
- boolean shouldWindowHandleBeTrusted(Session s) {
+ public boolean isWindowTrustedOverlay() {
return InputMonitor.isTrustedOverlay(mAttrs.type)
|| ((mAttrs.privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0
- && s.mCanAddInternalSystemWindow)
+ && mSession.mCanAddInternalSystemWindow)
|| ((mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_APPLICATION_OVERLAY) != 0
- && s.mCanCreateSystemApplicationOverlay);
+ && mSession.mCanCreateSystemApplicationOverlay);
}
int getTouchOcclusionMode() {
@@ -5187,6 +5190,9 @@
updateFrameRateSelectionPriorityIfNeeded();
updateScaleIfNeeded();
mWinAnimator.prepareSurfaceLocked(getSyncTransaction());
+ if (surfaceTrustedOverlay()) {
+ getSyncTransaction().setTrustedOverlay(mSurfaceControl, isWindowTrustedOverlay());
+ }
}
super.prepareSurfaces();
}
@@ -5939,7 +5945,13 @@
}
boolean isTrustedOverlay() {
- return mInputWindowHandle.isTrustedOverlay();
+ if (surfaceTrustedOverlay()) {
+ WindowState parentWindow = getParentWindow();
+ return isWindowTrustedOverlay() || (parentWindow != null
+ && parentWindow.isWindowTrustedOverlay());
+ } else {
+ return mInputWindowHandle.isTrustedOverlay();
+ }
}
public boolean receiveFocusFromTapOutside() {
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index ec5378f..bc70658 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -78,6 +78,7 @@
"onload.cpp",
":lib_cachedAppOptimizer_native",
":lib_gameManagerService_native",
+ ":lib_oomConnection_native",
],
include_dirs: [
@@ -122,6 +123,7 @@
"libhardware_legacy",
"libhidlbase",
"libmeminfo",
+ "libmemevents",
"libmemtrackproxy",
"libmtp",
"libnativehelper",
@@ -239,3 +241,8 @@
"com_android_server_app_GameManagerService.cpp",
],
}
+
+filegroup {
+ name: "lib_oomConnection_native",
+ srcs: ["com_android_server_am_OomConnection.cpp",],
+}
diff --git a/services/core/jni/com_android_server_am_OomConnection.cpp b/services/core/jni/com_android_server_am_OomConnection.cpp
new file mode 100644
index 0000000..e892d23
--- /dev/null
+++ b/services/core/jni/com_android_server_am_OomConnection.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#define LOG_TAG "OomConnection"
+
+#include <core_jni_helpers.h>
+#include <jni.h>
+#include <memevents/memevents.h>
+
+namespace android {
+
+// Used to cache the results of the JNI name lookup
+static struct {
+ jclass clazz;
+ jmethodID ctor;
+} sOomKillRecordInfo;
+
+static memevents::MemEventListener memevent_listener;
+
+/**
+ * Initialize listening and waiting for new out-of-memory (OOM) events to occur.
+ * Once a OOM event is detected, we then fetch the list of OOM kills, and return
+ * a corresponding java array with the information gathered.
+ *
+ * In the case that we encounter an error, we make sure to close the epfd, and
+ * the OOM file descriptor, by calling `deregisterAllEvents()`.
+ *
+ * @return list of `android.os.OomKillRecord`
+ * @throws java.lang.RuntimeException
+ */
+static jobjectArray android_server_am_OomConnection_waitOom(JNIEnv* env, jobject) {
+ const memevents::MemEvent oom_event = memevents::MemEvent::OOM_KILL;
+ if (!memevent_listener.registerEvent(oom_event)) {
+ memevent_listener.deregisterAllEvents();
+ jniThrowRuntimeException(env, "listener failed to register to OOM events");
+ return nullptr;
+ }
+
+ memevents::MemEvent event_received;
+ do {
+ event_received = memevent_listener.listen();
+ if (event_received == memevents::MemEvent::ERROR) {
+ memevent_listener.deregisterAllEvents();
+ jniThrowRuntimeException(env, "listener received error event");
+ return nullptr;
+ }
+ } while (event_received != oom_event);
+
+ std::vector<memevents::OomKill> oom_events;
+ if (!memevent_listener.getOomEvents(oom_events)) {
+ memevent_listener.deregisterAllEvents();
+ jniThrowRuntimeException(env, "Failed to get OOM events");
+ return nullptr;
+ }
+
+ jobjectArray java_oom_array =
+ env->NewObjectArray(oom_events.size(), sOomKillRecordInfo.clazz, nullptr);
+ if (java_oom_array == NULL) {
+ memevent_listener.deregisterAllEvents();
+ jniThrowRuntimeException(env, "Failed to create OomKillRecord array");
+ return nullptr;
+ }
+
+ for (int i = 0; i < oom_events.size(); i++) {
+ const memevents::OomKill oom_event = oom_events[i];
+ jstring process_name = env->NewStringUTF(oom_event.process_name);
+ if (process_name == NULL) {
+ memevent_listener.deregisterAllEvents();
+ jniThrowRuntimeException(env, "Failed creating java string for process name");
+ }
+ jobject java_oom_kill = env->NewObject(sOomKillRecordInfo.clazz, sOomKillRecordInfo.ctor,
+ oom_event.timestamp_ms, oom_event.pid, oom_event.uid,
+ process_name, oom_event.oom_score_adj);
+ if (java_oom_kill == NULL) {
+ memevent_listener.deregisterAllEvents();
+ jniThrowRuntimeException(env, "Failed to create OomKillRecord object");
+ return java_oom_array;
+ }
+ env->SetObjectArrayElement(java_oom_array, i, java_oom_kill);
+ }
+ return java_oom_array;
+}
+
+static const JNINativeMethod sOomConnectionMethods[] = {
+ /* name, signature, funcPtr */
+ {"waitOom", "()[Landroid/os/OomKillRecord;",
+ (void*)android_server_am_OomConnection_waitOom},
+};
+
+int register_android_server_am_OomConnection(JNIEnv* env) {
+ sOomKillRecordInfo.clazz = FindClassOrDie(env, "android/os/OomKillRecord");
+ sOomKillRecordInfo.clazz = MakeGlobalRefOrDie(env, sOomKillRecordInfo.clazz);
+
+ sOomKillRecordInfo.ctor =
+ GetMethodIDOrDie(env, sOomKillRecordInfo.clazz, "<init>", "(JIILjava/lang/String;S)V");
+
+ return RegisterMethodsOrDie(env, "com/android/server/am/OomConnection", sOomConnectionMethods,
+ NELEM(sOomConnectionMethods));
+}
+} // namespace android
\ No newline at end of file
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index f6f6737..df44895 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -52,6 +52,7 @@
int register_android_server_HardwarePropertiesManagerService(JNIEnv* env);
int register_android_server_SyntheticPasswordManager(JNIEnv* env);
int register_android_hardware_display_DisplayViewport(JNIEnv* env);
+int register_android_server_am_OomConnection(JNIEnv* env);
int register_android_server_am_CachedAppOptimizer(JNIEnv* env);
int register_android_server_am_LowMemDetector(JNIEnv* env);
int register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(JNIEnv* env);
@@ -112,6 +113,7 @@
register_android_server_storage_AppFuse(env);
register_android_server_SyntheticPasswordManager(env);
register_android_hardware_display_DisplayViewport(env);
+ register_android_server_am_OomConnection(env);
register_android_server_am_CachedAppOptimizer(env);
register_android_server_am_LowMemDetector(env);
register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(env);
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 d0a9c45..debd891 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -46,6 +46,8 @@
<xs:annotation name="nonnull"/>
<xs:annotation name="final"/>
</xs:element>
+ <xs:element type="powerThrottlingConfig" name="powerThrottlingConfig" minOccurs="0"
+ maxOccurs="1"/>
<xs:element type="luxThrottling" name="luxThrottling" minOccurs="0"
maxOccurs="1"/>
<xs:element type="highBrightnessMode" name="highBrightnessMode" minOccurs="0"
@@ -350,6 +352,43 @@
</xs:sequence>
</xs:complexType>
+ <xs:complexType name="powerThrottlingMap">
+ <xs:sequence>
+ <xs:element name="powerThrottlingPoint" type="powerThrottlingPoint" maxOccurs="unbounded" minOccurs="1">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="id" type="xs:string"/>
+ </xs:complexType>
+
+ <xs:complexType name="powerThrottlingPoint">
+ <xs:sequence>
+ <xs:element type="thermalStatus" name="thermalStatus">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ <xs:element type="nonNegativeDecimal" name="powerQuotaMilliWatts">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="powerThrottlingConfig">
+ <xs:element type="nonNegativeDecimal" name="brightnessLowestCapAllowed">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ <xs:element name="pollingWindowMillis" type="xs:nonNegativeInteger">
+ <xs:annotation name="nonnull"/>
+ <xs:annotation name="final"/>
+ </xs:element>
+ <xs:element type="powerThrottlingMap" name="powerThrottlingMap" maxOccurs="unbounded">
+ <xs:annotation name="final"/>
+ </xs:element>
+ </xs:complexType>
+
<xs:complexType name="nitsMap">
<xs:sequence>
<xs:element name="point" type="point" 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 949b1f2..2d27f0c 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -106,6 +106,7 @@
method public final com.android.server.display.config.SensorDetails getLightSensor();
method public com.android.server.display.config.LuxThrottling getLuxThrottling();
method @Nullable public final String getName();
+ method public com.android.server.display.config.PowerThrottlingConfig getPowerThrottlingConfig();
method public final com.android.server.display.config.SensorDetails getProxSensor();
method public com.android.server.display.config.DisplayQuirks getQuirks();
method public com.android.server.display.config.RefreshRateConfigs getRefreshRate();
@@ -138,6 +139,7 @@
method public final void setLightSensor(com.android.server.display.config.SensorDetails);
method public void setLuxThrottling(com.android.server.display.config.LuxThrottling);
method public final void setName(@Nullable String);
+ method public void setPowerThrottlingConfig(com.android.server.display.config.PowerThrottlingConfig);
method public final void setProxSensor(com.android.server.display.config.SensorDetails);
method public void setQuirks(com.android.server.display.config.DisplayQuirks);
method public void setRefreshRate(com.android.server.display.config.RefreshRateConfigs);
@@ -246,6 +248,30 @@
method public final void setValue(@NonNull java.math.BigDecimal);
}
+ public class PowerThrottlingConfig {
+ ctor public PowerThrottlingConfig();
+ method @NonNull public final java.math.BigDecimal getBrightnessLowestCapAllowed();
+ method @NonNull public final java.math.BigInteger getPollingWindowMillis();
+ method public final java.util.List<com.android.server.display.config.PowerThrottlingMap> getPowerThrottlingMap();
+ method public final void setBrightnessLowestCapAllowed(@NonNull java.math.BigDecimal);
+ method public final void setPollingWindowMillis(@NonNull java.math.BigInteger);
+ }
+
+ public class PowerThrottlingMap {
+ ctor public PowerThrottlingMap();
+ method public String getId();
+ method @NonNull public final java.util.List<com.android.server.display.config.PowerThrottlingPoint> getPowerThrottlingPoint();
+ method public void setId(String);
+ }
+
+ public class PowerThrottlingPoint {
+ ctor public PowerThrottlingPoint();
+ method @NonNull public final java.math.BigDecimal getPowerQuotaMilliWatts();
+ method @NonNull public final com.android.server.display.config.ThermalStatus getThermalStatus();
+ method public final void setPowerQuotaMilliWatts(@NonNull java.math.BigDecimal);
+ method public final void setThermalStatus(@NonNull com.android.server.display.config.ThermalStatus);
+ }
+
public enum PredefinedBrightnessLimitNames {
method public String getRawName();
enum_constant public static final com.android.server.display.config.PredefinedBrightnessLimitNames _default;
diff --git a/services/core/xsd/display-layout-config/display-layout-config.xsd b/services/core/xsd/display-layout-config/display-layout-config.xsd
index 57b5d00..4e95465 100644
--- a/services/core/xsd/display-layout-config/display-layout-config.xsd
+++ b/services/core/xsd/display-layout-config/display-layout-config.xsd
@@ -52,6 +52,7 @@
<xs:element name="address" type="xs:nonNegativeInteger"/>
<xs:element name="position" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="brightnessThrottlingMapId" type="xs:string" minOccurs="0" maxOccurs="1" />
+ <xs:element name="powerThrottlingMapId" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="refreshRateThermalThrottlingMapId" type="xs:string" minOccurs="0" />
<xs:element name="leadDisplayAddress" type="xs:nonNegativeInteger" minOccurs="0" maxOccurs="1" />
</xs:sequence>
diff --git a/services/core/xsd/display-layout-config/schema/current.txt b/services/core/xsd/display-layout-config/schema/current.txt
index 2d4f7a4..195cae5 100644
--- a/services/core/xsd/display-layout-config/schema/current.txt
+++ b/services/core/xsd/display-layout-config/schema/current.txt
@@ -8,6 +8,7 @@
method public String getDisplayGroup();
method public java.math.BigInteger getLeadDisplayAddress();
method public String getPosition();
+ method public String getPowerThrottlingMapId();
method public String getRefreshRateThermalThrottlingMapId();
method public String getRefreshRateZoneId();
method public boolean isDefaultDisplay();
@@ -19,6 +20,7 @@
method public void setEnabled(boolean);
method public void setLeadDisplayAddress(java.math.BigInteger);
method public void setPosition(String);
+ method public void setPowerThrottlingMapId(String);
method public void setRefreshRateThermalThrottlingMapId(String);
method public void setRefreshRateZoneId(String);
}
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
index b90f08e..3c190bf 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerUi.java
@@ -32,6 +32,7 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.ResultReceiver;
+import android.os.UserHandle;
import android.service.credentials.CredentialProviderInfoFactory;
import android.util.Slog;
@@ -171,7 +172,9 @@
.setAction(UUID.randomUUID().toString());
//TODO: Create unique pending intent using request code and cancel any pre-existing pending
// intents
- return PendingIntent.getActivity(
- mContext, /*requestCode=*/0, intent, PendingIntent.FLAG_IMMUTABLE);
+ return PendingIntent.getActivityAsUser(
+ mContext, /*requestCode=*/0, intent,
+ PendingIntent.FLAG_IMMUTABLE, /*options=*/null,
+ UserHandle.of(mUserId));
}
}
diff --git a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
index 3eb6718..7bd1cc4 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
@@ -31,6 +31,7 @@
import android.credentials.ui.GetCredentialProviderData;
import android.credentials.ui.ProviderPendingIntentResponse;
import android.os.ICancellationSignal;
+import android.service.autofill.Flags;
import android.service.credentials.Action;
import android.service.credentials.BeginGetCredentialOption;
import android.service.credentials.BeginGetCredentialRequest;
@@ -42,6 +43,7 @@
import android.service.credentials.RemoteEntry;
import android.util.Pair;
import android.util.Slog;
+import android.view.autofill.AutofillId;
import java.util.ArrayList;
import java.util.HashMap;
@@ -379,13 +381,23 @@
// but does not resolve to a valid option. For now, not skipping it because
// it may be possible that the provider adds their own extras and expects to receive
// those and complete the flow.
- if (mBeginGetOptionToCredentialOptionMap.get(id) == null) {
+ Intent intent = new Intent();
+ CredentialOption credentialOption = mBeginGetOptionToCredentialOptionMap.get(id);
+ if (credentialOption == null) {
Slog.w(TAG, "Id from Credential Entry does not resolve to a valid option");
- return new Intent();
+ return intent;
}
- return new Intent().putExtra(CredentialProviderService.EXTRA_GET_CREDENTIAL_REQUEST,
+ AutofillId autofillId = credentialOption
+ .getCandidateQueryData()
+ .getParcelable(CredentialProviderService.EXTRA_AUTOFILL_ID, AutofillId.class);
+ if (autofillId != null && Flags.autofillCredmanIntegration()) {
+ intent.putExtra(CredentialProviderService.EXTRA_AUTOFILL_ID, autofillId);
+ }
+ return intent.putExtra(
+ CredentialProviderService.EXTRA_GET_CREDENTIAL_REQUEST,
new GetCredentialRequest(
- mCallingAppInfo, List.of(mBeginGetOptionToCredentialOptionMap.get(id))));
+ mCallingAppInfo,
+ List.of(credentialOption)));
}
private Intent setUpFillInIntentWithQueryRequest() {
diff --git a/services/foldables/devicestateprovider/tests/Android.bp b/services/foldables/devicestateprovider/tests/Android.bp
index a8db05e..84a6df3 100644
--- a/services/foldables/devicestateprovider/tests/Android.bp
+++ b/services/foldables/devicestateprovider/tests/Android.bp
@@ -20,11 +20,11 @@
"foldable-device-state-provider",
"androidx.test.rules",
"junit",
- "truth-prebuilt",
+ "truth",
"mockito-target-extended-minus-junit4",
"androidx.test.uiautomator_uiautomator",
"androidx.test.ext.junit",
"testables",
],
- test_suites: ["device-tests"]
+ test_suites: ["device-tests"],
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 57fa12d..49ad84a 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -264,6 +264,8 @@
"com.android.server.backup.BackupManagerService$Lifecycle";
private static final String APPWIDGET_SERVICE_CLASS =
"com.android.server.appwidget.AppWidgetService";
+ private static final String ARC_SYSTEM_HEALTH_SERVICE =
+ "com.android.server.arc.health.ArcSystemHealthService";
private static final String VOICE_RECOGNITION_MANAGER_SERVICE_CLASS =
"com.android.server.voiceinteraction.VoiceInteractionManagerService";
private static final String APP_HIBERNATION_SERVICE_CLASS =
@@ -1287,6 +1289,12 @@
}
}
+ if (Build.IS_ARC) {
+ t.traceBegin("StartArcSystemHealthService");
+ mSystemServiceManager.startService(ARC_SYSTEM_HEALTH_SERVICE);
+ t.traceEnd();
+ }
+
t.traceBegin("StartUserManagerService");
mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
t.traceEnd();
diff --git a/services/robotests/backup/Android.bp b/services/robotests/backup/Android.bp
index e04dd68..8b9efb3 100644
--- a/services/robotests/backup/Android.bp
+++ b/services/robotests/backup/Android.bp
@@ -59,7 +59,7 @@
"mockito-robolectric-prebuilt",
"platform-test-annotations",
"testng",
- "truth-prebuilt",
+ "truth",
],
instrumentation_for: "BackupFrameworksServicesLib",
diff --git a/services/tests/InputMethodSystemServerTests/Android.bp b/services/tests/InputMethodSystemServerTests/Android.bp
index 36446f6..ffe6dc5 100644
--- a/services/tests/InputMethodSystemServerTests/Android.bp
+++ b/services/tests/InputMethodSystemServerTests/Android.bp
@@ -44,7 +44,7 @@
"service-permission.stubs.system_server",
"servicestests-core-utils",
"servicestests-utils-mockito-extended",
- "truth-prebuilt",
+ "truth",
],
libs: [
@@ -92,7 +92,7 @@
"service-permission.stubs.system_server",
"servicestests-core-utils",
"servicestests-utils-mockito-extended",
- "truth-prebuilt",
+ "truth",
"SimpleImeTestingLib",
"SimpleImeImsLib",
],
diff --git a/services/tests/PackageManager/packageinstaller/Android.bp b/services/tests/PackageManager/packageinstaller/Android.bp
index 35d754b..e8fce8e 100644
--- a/services/tests/PackageManager/packageinstaller/Android.bp
+++ b/services/tests/PackageManager/packageinstaller/Android.bp
@@ -32,7 +32,7 @@
"androidx.test.runner",
"junit",
"kotlin-test",
- "truth-prebuilt",
+ "truth",
],
platform_apis: true,
test_suites: ["device-tests"],
diff --git a/services/tests/PackageManagerComponentOverrideTests/Android.bp b/services/tests/PackageManagerComponentOverrideTests/Android.bp
index bc36970..00850a5 100644
--- a/services/tests/PackageManagerComponentOverrideTests/Android.bp
+++ b/services/tests/PackageManagerComponentOverrideTests/Android.bp
@@ -38,7 +38,7 @@
"service-permission.stubs.system_server",
"servicestests-utils-mockito-extended",
"testng", // TODO: remove once Android migrates to JUnit 4.12, which provides assertThrows
- "truth-prebuilt",
+ "truth",
],
jni_libs: [
diff --git a/services/tests/PackageManagerServiceTests/appenumeration/Android.bp b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp
index 9c4e6fd..ad7af44 100644
--- a/services/tests/PackageManagerServiceTests/appenumeration/Android.bp
+++ b/services/tests/PackageManagerServiceTests/appenumeration/Android.bp
@@ -29,7 +29,7 @@
static_libs: [
"compatibility-device-util-axt",
"androidx.test.runner",
- "truth-prebuilt",
+ "truth",
"Harrier",
],
platform_apis: true,
diff --git a/services/tests/PackageManagerServiceTests/host/Android.bp b/services/tests/PackageManagerServiceTests/host/Android.bp
index ce28682..6eacef7 100644
--- a/services/tests/PackageManagerServiceTests/host/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/Android.bp
@@ -30,7 +30,7 @@
libs: [
"tradefed",
"junit",
- "truth-prebuilt",
+ "truth",
],
static_libs: [
"ApexInstallHelper",
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp
index 462c580..cea9c59 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/DeviceSide/Android.bp
@@ -38,6 +38,6 @@
"junit-params",
"androidx.test.ext.junit",
"androidx.test.rules",
- "truth-prebuilt",
+ "truth",
],
}
diff --git a/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp b/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp
index 5718474..ed5f2b5 100644
--- a/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp
+++ b/services/tests/PackageManagerServiceTests/host/test-apps/OverlayActor/Android.bp
@@ -28,6 +28,6 @@
"androidx.test.runner",
"junit",
"kotlin-test",
- "truth-prebuilt",
+ "truth",
],
}
diff --git a/services/tests/PackageManagerServiceTests/server/Android.bp b/services/tests/PackageManagerServiceTests/server/Android.bp
index a1d846e..3aca1ca 100644
--- a/services/tests/PackageManagerServiceTests/server/Android.bp
+++ b/services/tests/PackageManagerServiceTests/server/Android.bp
@@ -41,7 +41,7 @@
"mockito-target-minus-junit4",
"platform-test-annotations",
"ShortcutManagerTestUtils",
- "truth-prebuilt",
+ "truth",
"testables",
"platformprotosnano",
"framework-protos",
@@ -51,7 +51,7 @@
"servicestests-utils",
"service-permission.impl",
"testng",
- "truth-prebuilt",
+ "truth",
"junit",
"junit-params",
"platform-compat-test-rules",
diff --git a/services/tests/PackageManagerServiceTests/unit/Android.bp b/services/tests/PackageManagerServiceTests/unit/Android.bp
index 9b3b8c35..85059838 100644
--- a/services/tests/PackageManagerServiceTests/unit/Android.bp
+++ b/services/tests/PackageManagerServiceTests/unit/Android.bp
@@ -37,7 +37,7 @@
"services.core",
"servicestests-utils",
"servicestests-core-utils",
- "truth-prebuilt",
+ "truth",
],
jni_libs: [
"libdexmakerjvmtiagent",
diff --git a/services/tests/RemoteProvisioningServiceTests/Android.bp b/services/tests/RemoteProvisioningServiceTests/Android.bp
index fc2c085..19c9136 100644
--- a/services/tests/RemoteProvisioningServiceTests/Android.bp
+++ b/services/tests/RemoteProvisioningServiceTests/Android.bp
@@ -30,8 +30,8 @@
"mockito-target",
"service-rkp.impl",
"services.core",
- "truth-prebuilt",
- "truth-java8-extension-jar",
+ "truth",
+ "truth-java8-extension",
],
test_suites: [
"device-tests",
diff --git a/services/tests/apexsystemservices/Android.bp b/services/tests/apexsystemservices/Android.bp
index e724e804..9dacfea 100644
--- a/services/tests/apexsystemservices/Android.bp
+++ b/services/tests/apexsystemservices/Android.bp
@@ -34,7 +34,7 @@
"compatibility-host-util",
"cts-install-lib-host",
"frameworks-base-hostutils",
- "truth-prebuilt",
+ "truth",
"modules-utils-build-testing",
],
test_suites: [
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 6ef150c..c37d21a 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -179,6 +179,89 @@
}
@Test
+ public void testPowerThrottlingConfigFromDisplayConfig() throws IOException {
+ setupDisplayDeviceConfigFromDisplayConfigFile();
+
+ DisplayDeviceConfig.PowerThrottlingConfigData powerThrottlingConfigData =
+ mDisplayDeviceConfig.getPowerThrottlingConfigData();
+ assertNotNull(powerThrottlingConfigData);
+ assertEquals(0.1f, powerThrottlingConfigData.brightnessLowestCapAllowed, SMALL_DELTA);
+ assertEquals(10, powerThrottlingConfigData.pollingWindowMillis);
+ }
+
+ @Test
+ public void testPowerThrottlingDataFromDisplayConfig() throws IOException {
+ setupDisplayDeviceConfigFromDisplayConfigFile();
+
+ List<DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel>
+ defaultThrottlingLevels = new ArrayList<>();
+ defaultThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.light), 800f
+ ));
+ defaultThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.moderate), 600f
+ ));
+ defaultThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.severe), 400f
+ ));
+ defaultThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.critical), 200f
+ ));
+ defaultThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.emergency), 100f
+ ));
+ defaultThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.shutdown), 50f
+ ));
+
+ DisplayDeviceConfig.PowerThrottlingData defaultThrottlingData =
+ new DisplayDeviceConfig.PowerThrottlingData(defaultThrottlingLevels);
+
+ List<DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel>
+ concurrentThrottlingLevels = new ArrayList<>();
+ concurrentThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.light), 800f
+ ));
+ concurrentThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.moderate), 600f
+ ));
+ concurrentThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.severe), 400f
+ ));
+ concurrentThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.critical), 200f
+ ));
+ concurrentThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.emergency), 100f
+ ));
+ concurrentThrottlingLevels.add(
+ new DisplayDeviceConfig.PowerThrottlingData.ThrottlingLevel(
+ DisplayDeviceConfig.convertThermalStatus(ThermalStatus.shutdown), 50f
+ ));
+ DisplayDeviceConfig.PowerThrottlingData concurrentThrottlingData =
+ new DisplayDeviceConfig.PowerThrottlingData(concurrentThrottlingLevels);
+
+ HashMap<String, DisplayDeviceConfig.PowerThrottlingData> throttlingDataMap =
+ new HashMap<>(2);
+ throttlingDataMap.put("default", defaultThrottlingData);
+ throttlingDataMap.put("concurrent", concurrentThrottlingData);
+
+ assertEquals(throttlingDataMap,
+ mDisplayDeviceConfig.getPowerThrottlingDataMapByThrottlingId());
+ }
+
+ @Test
public void testConfigValuesFromConfigResource() {
setupDisplayDeviceConfigFromConfigResourceFile();
verifyConfigValuesFromConfigResource();
@@ -845,6 +928,64 @@
+ "</screenBrightnessRampSlowIncreaseIdle>\n";
}
+ private String getPowerThrottlingConfig() {
+ return "<powerThrottlingConfig >\n"
+ + "<brightnessLowestCapAllowed>0.1</brightnessLowestCapAllowed>\n"
+ + "<pollingWindowMillis>10</pollingWindowMillis>\n"
+ + "<powerThrottlingMap>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>light</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>800</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>moderate</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>600</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>severe</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>400</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>critical</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>200</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>emergency</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>100</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>shutdown</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>50</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "</powerThrottlingMap>\n"
+ + "<powerThrottlingMap id=\"concurrent\">\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>light</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>800</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>moderate</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>600</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>severe</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>400</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>critical</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>200</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>emergency</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>100</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "<powerThrottlingPoint>\n"
+ + "<thermalStatus>shutdown</thermalStatus>\n"
+ + "<powerQuotaMilliWatts>50</powerQuotaMilliWatts>\n"
+ + "</powerThrottlingPoint>\n"
+ + "</powerThrottlingMap>\n"
+ + "</powerThrottlingConfig>\n";
+ }
private String getScreenBrightnessRampCapsIdle() {
return "<screenBrightnessRampIncreaseMaxIdleMillis>"
+ "4000"
@@ -915,6 +1056,7 @@
+ "</displayBrightnessPoint>\n"
+ "</displayBrightnessMapping>\n"
+ "</autoBrightness>\n"
+ + getPowerThrottlingConfig()
+ "<highBrightnessMode enabled=\"true\">\n"
+ "<transitionPoint>" + BRIGHTNESS[1] + "</transitionPoint>\n"
+ "<minimumLux>10000</minimumLux>\n"
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
index c63fac9..ee187ba 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/HdrClamperTest.java
@@ -22,6 +22,9 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -97,6 +100,37 @@
}
@Test
+ public void testRegisterHdrListener() {
+ verify(mMockHdrInfoListener).register(mMockBinder);
+ }
+
+ @Test
+ public void testRegisterOtherHdrListenerWhenCalledWithOtherToken() {
+ IBinder otherBinder = mock(IBinder.class);
+ mHdrClamper.resetHdrConfig(TEST_HDR_DATA, WIDTH, HEIGHT, MIN_HDR_PERCENT, otherBinder);
+
+ verify(mMockHdrInfoListener).unregister(mMockBinder);
+ verify(mMockHdrInfoListener).register(otherBinder);
+ }
+
+ @Test
+ public void testRegisterHdrListenerOnceWhenCalledWithSameToken() {
+ mHdrClamper.resetHdrConfig(TEST_HDR_DATA, WIDTH, HEIGHT, MIN_HDR_PERCENT, mMockBinder);
+
+ verify(mMockHdrInfoListener, never()).unregister(mMockBinder);
+ verify(mMockHdrInfoListener, times(1)).register(mMockBinder);
+ }
+
+ @Test
+ public void testRegisterNotCalledIfHbmConfigIsMissing() {
+ IBinder otherBinder = mock(IBinder.class);
+ mHdrClamper.resetHdrConfig(TEST_HDR_DATA, WIDTH, HEIGHT, -1, otherBinder);
+
+ verify(mMockHdrInfoListener).unregister(mMockBinder);
+ verify(mMockHdrInfoListener, never()).register(otherBinder);
+ }
+
+ @Test
public void testClamper_AmbientLuxChangesAboveLimit() {
mHdrClamper.onAmbientLuxChange(500);
diff --git a/services/tests/inprocesstests/Android.bp b/services/tests/inprocesstests/Android.bp
index 7c237ac..086e84b 100644
--- a/services/tests/inprocesstests/Android.bp
+++ b/services/tests/inprocesstests/Android.bp
@@ -14,7 +14,7 @@
"androidx.test.core",
"androidx.test.rules",
"services.core",
- "truth-prebuilt",
+ "truth",
"platform-test-annotations",
],
test_suites: ["general-tests"],
diff --git a/services/tests/mockingservicestests/Android.bp b/services/tests/mockingservicestests/Android.bp
index 101498a..063af57 100644
--- a/services/tests/mockingservicestests/Android.bp
+++ b/services/tests/mockingservicestests/Android.bp
@@ -46,6 +46,7 @@
"androidx.test.espresso.core",
"androidx.test.espresso.contrib",
"androidx.test.ext.truth",
+ "flag-junit",
"frameworks-base-testutils",
"hamcrest-library",
"kotlin-test",
@@ -67,7 +68,7 @@
"servicestests-core-utils",
"servicestests-utils-mockito-extended",
"testables",
- "truth-prebuilt",
+ "truth",
// TODO: remove once Android migrates to JUnit 4.12, which provides assertThrows
"testng",
"compatibility-device-util-axt",
diff --git a/services/tests/mockingservicestests/jni/Android.bp b/services/tests/mockingservicestests/jni/Android.bp
index f1dc1fa..1eb9888 100644
--- a/services/tests/mockingservicestests/jni/Android.bp
+++ b/services/tests/mockingservicestests/jni/Android.bp
@@ -22,6 +22,7 @@
srcs: [
":lib_cachedAppOptimizer_native",
":lib_gameManagerService_native",
+ ":lib_oomConnection_native",
"onload.cpp",
],
@@ -42,6 +43,7 @@
"libgui",
"libhidlbase",
"liblog",
+ "libmemevents",
"libmeminfo",
"libnativehelper",
"libprocessgroup",
diff --git a/services/tests/mockingservicestests/jni/onload.cpp b/services/tests/mockingservicestests/jni/onload.cpp
index 23ccb22..fb91051 100644
--- a/services/tests/mockingservicestests/jni/onload.cpp
+++ b/services/tests/mockingservicestests/jni/onload.cpp
@@ -26,6 +26,7 @@
namespace android {
int register_android_server_am_CachedAppOptimizer(JNIEnv* env);
int register_android_server_app_GameManagerService(JNIEnv* env);
+int register_android_server_am_OomConnection(JNIEnv* env);
};
using namespace android;
@@ -42,6 +43,7 @@
ALOG_ASSERT(env, "Could not retrieve the env!");
register_android_server_am_CachedAppOptimizer(env);
register_android_server_app_GameManagerService(env);
+ register_android_server_am_OomConnection(env);
return JNI_VERSION_1_4;
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index 5b1508b..be29163 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -1290,7 +1290,8 @@
}
@Test
- public void testLightStepIdleStateIdlingTimeIncreases() {
+ public void testLightStepIdleStateIdlingTimeIncreasesExponentially() {
+ mConstants.LIGHT_IDLE_INCREASE_LINEARLY = false;
final long maintenanceTimeMs = 60_000L;
mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = maintenanceTimeMs;
mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = maintenanceTimeMs;
@@ -1335,13 +1336,88 @@
eq(mInjector.nowElapsed + idlingTimeMs),
anyLong(), anyString(), any(), any(Handler.class));
- for (int i = 0; i < 2; ++i) {
+ for (int i = 0; i < 10; ++i) {
// IDLE->MAINTENANCE alarm
mInjector.nowElapsed = mDeviceIdleController.getNextLightAlarmTimeForTesting();
alarmListener.onAlarm();
verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
long maintenanceExpiryTime = mInjector.nowElapsed + maintenanceTimeMs;
idlingTimeMs *= mConstants.LIGHT_IDLE_FACTOR;
+ idlingTimeMs = Math.min(idlingTimeMs, mConstants.LIGHT_MAX_IDLE_TIMEOUT);
+ // Set MAINTENANCE->IDLE
+ alarmManagerInOrder.verify(mAlarmManager).setWindow(
+ eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
+ eq(maintenanceExpiryTime),
+ anyLong(), anyString(), any(), any(Handler.class));
+
+ // MAINTENANCE->IDLE alarm
+ mInjector.nowElapsed = mDeviceIdleController.getNextLightAlarmTimeForTesting();
+ alarmListener.onAlarm();
+ verifyLightStateConditions(LIGHT_STATE_IDLE);
+ // Set IDLE->MAINTENANCE again
+ alarmManagerInOrder.verify(mAlarmManager).setWindow(
+ eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
+ eq(mInjector.nowElapsed + idlingTimeMs),
+ anyLong(), anyString(), any(), any(Handler.class));
+ }
+ }
+
+ @Test
+ public void testLightStepIdleStateIdlingTimeIncreasesLinearly() {
+ mConstants.LIGHT_IDLE_INCREASE_LINEARLY = true;
+ final long maintenanceTimeMs = 60_000L;
+ mConstants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = maintenanceTimeMs;
+ mConstants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = maintenanceTimeMs;
+ mConstants.LIGHT_IDLE_TIMEOUT = 5 * 60_000L;
+ mConstants.LIGHT_MAX_IDLE_TIMEOUT = 30 * 60_000L;
+ mConstants.LIGHT_IDLE_FACTOR = 2f;
+ mConstants.LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS = 2 * 60_000L;
+
+ setNetworkConnected(true);
+ mDeviceIdleController.setJobsActive(false);
+ mDeviceIdleController.setAlarmsActive(false);
+ mDeviceIdleController.setActiveIdleOpsForTest(0);
+
+ InOrder alarmManagerInOrder = inOrder(mAlarmManager);
+
+ final ArgumentCaptor<AlarmManager.OnAlarmListener> alarmListenerCaptor = ArgumentCaptor
+ .forClass(AlarmManager.OnAlarmListener.class);
+ doNothing().when(mAlarmManager).setWindow(anyInt(), anyLong(), anyLong(),
+ eq("DeviceIdleController.light"), alarmListenerCaptor.capture(), any());
+
+ // Set state to INACTIVE.
+ mDeviceIdleController.becomeActiveLocked("testing", 0);
+ setChargingOn(false);
+ setScreenOn(false);
+ verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+ long idlingTimeMs = mConstants.LIGHT_IDLE_TIMEOUT;
+ final long idleAfterInactiveExpiryTime =
+ mInjector.nowElapsed + mConstants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT;
+ alarmManagerInOrder.verify(mAlarmManager).setWindow(
+ eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
+ eq(idleAfterInactiveExpiryTime),
+ anyLong(), anyString(), any(), any(Handler.class));
+
+ final AlarmManager.OnAlarmListener alarmListener =
+ alarmListenerCaptor.getAllValues().get(0);
+
+ // INACTIVE -> IDLE alarm
+ mInjector.nowElapsed = mDeviceIdleController.getNextLightAlarmTimeForTesting();
+ alarmListener.onAlarm();
+ verifyLightStateConditions(LIGHT_STATE_IDLE);
+ alarmManagerInOrder.verify(mAlarmManager).setWindow(
+ eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
+ eq(mInjector.nowElapsed + idlingTimeMs),
+ anyLong(), anyString(), any(), any(Handler.class));
+
+ for (int i = 0; i < 10; ++i) {
+ // IDLE->MAINTENANCE alarm
+ mInjector.nowElapsed = mDeviceIdleController.getNextLightAlarmTimeForTesting();
+ alarmListener.onAlarm();
+ verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+ long maintenanceExpiryTime = mInjector.nowElapsed + maintenanceTimeMs;
+ idlingTimeMs += mConstants.LIGHT_IDLE_LINEAR_INCREASE_FACTOR_MS;
+ idlingTimeMs = Math.min(idlingTimeMs, mConstants.LIGHT_MAX_IDLE_TIMEOUT);
// Set MAINTENANCE->IDLE
alarmManagerInOrder.verify(mAlarmManager).setWindow(
eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerInternalTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerInternalTest.java
index 64cc397..9ba4f5b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerInternalTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerInternalTest.java
@@ -218,4 +218,9 @@
assertEquals(errMsg, Thread.State.TERMINATED, getState());
}
}
+
+ // TODO: [b/302724778] Remove manual JNI load
+ static {
+ System.loadLibrary("mockingservicestestjni");
+ }
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 2bc66ac..40b5458 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -1210,4 +1210,9 @@
return returnValueForstartUserOnSecondaryDisplay;
}
}
+
+ // TODO: [b/302724778] Remove manual JNI load
+ static {
+ System.loadLibrary("mockingservicestestjni");
+ }
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/AppChildProcessTest.java b/services/tests/mockingservicestests/src/com/android/server/am/AppChildProcessTest.java
index 1c0989c..9391d5b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/AppChildProcessTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/AppChildProcessTest.java
@@ -338,4 +338,8 @@
}
}
+ // TODO: [b/302724778] Remove manual JNI load
+ static {
+ System.loadLibrary("mockingservicestestjni");
+ }
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
index d56229c..e15942b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationExitInfoTest.java
@@ -1126,4 +1126,9 @@
};
}
}
+
+ // TODO: [b/302724778] Remove manual JNI load
+ static {
+ System.loadLibrary("mockingservicestestjni");
+ }
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java b/services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java
index 0abf46b..596a3f3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/AsyncProcessStartTest.java
@@ -284,4 +284,9 @@
return app;
}
+
+ // TODO: [b/302724778] Remove manual JNI load
+ static {
+ System.loadLibrary("mockingservicestestjni");
+ }
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java b/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java
index 434d200..dfb8fda 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/CacheOomRankerTest.java
@@ -803,4 +803,9 @@
return mHandler;
}
}
+
+ // TODO: [b/302724778] Remove manual JNI load
+ static {
+ System.loadLibrary("mockingservicestestjni");
+ }
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ServiceTimeoutTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ServiceTimeoutTest.java
index fd1b068..7ec27be 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ServiceTimeoutTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ServiceTimeoutTest.java
@@ -201,4 +201,9 @@
return mActiveServices;
}
}
+
+ // TODO: [b/302724778] Remove manual JNI load
+ static {
+ System.loadLibrary("mockingservicestestjni");
+ }
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
index 2b56ea8..bded9b4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
@@ -34,6 +34,7 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+import static com.android.server.job.Flags.FLAG_RELAX_PREFETCH_CONNECTIVITY_CONSTRAINT_ONLY_ON_CHARGER;
import static com.android.server.job.JobSchedulerService.FREQUENT_INDEX;
import static com.android.server.job.JobSchedulerService.RARE_INDEX;
import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
@@ -66,6 +67,7 @@
import android.os.Build;
import android.os.Looper;
import android.os.SystemClock;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.telephony.CellSignalStrength;
import android.telephony.SignalStrength;
import android.telephony.TelephonyCallback;
@@ -79,6 +81,7 @@
import com.android.server.net.NetworkPolicyManagerInternal;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -107,6 +110,9 @@
@Mock
private PackageManager mPackageManager;
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
private Constants mConstants;
private FlexibilityController mFlexibilityController;
@@ -898,7 +904,8 @@
assertTrue(controller.isSatisfied(latePrefetchUnknownUp, net, caps, mConstants));
}
- // Metered network is only when prefetching, late, and in opportunistic quota
+ // Metered network is only when prefetching, charging*, late, and in opportunistic quota
+ // *Charging only when the flag is enabled
{
final Network net = mock(Network.class);
final NetworkCapabilities caps = createCapabilitiesBuilder()
@@ -910,6 +917,8 @@
assertFalse(controller.isSatisfied(latePrefetch, net, caps, mConstants));
assertFalse(controller.isSatisfied(latePrefetchUnknownDown, net, caps, mConstants));
assertFalse(controller.isSatisfied(latePrefetchUnknownUp, net, caps, mConstants));
+ mSetFlagsRule.disableFlags(FLAG_RELAX_PREFETCH_CONNECTIVITY_CONSTRAINT_ONLY_ON_CHARGER);
+ when(mService.isBatteryCharging()).thenReturn(false);
when(mNetPolicyManagerInternal.getSubscriptionOpportunisticQuota(
any(), eq(NetworkPolicyManagerInternal.QUOTA_TYPE_JOBS)))
@@ -918,6 +927,21 @@
// Only relax restrictions when we at least know the estimated download bytes.
assertFalse(controller.isSatisfied(latePrefetchUnknownDown, net, caps, mConstants));
assertTrue(controller.isSatisfied(latePrefetchUnknownUp, net, caps, mConstants));
+
+ mSetFlagsRule.enableFlags(FLAG_RELAX_PREFETCH_CONNECTIVITY_CONSTRAINT_ONLY_ON_CHARGER);
+ when(mNetPolicyManagerInternal.getSubscriptionOpportunisticQuota(
+ any(), eq(NetworkPolicyManagerInternal.QUOTA_TYPE_JOBS)))
+ .thenReturn(9876543210L);
+ assertFalse(controller.isSatisfied(latePrefetch, net, caps, mConstants));
+ // Only relax restrictions when we at least know the estimated download bytes.
+ assertFalse(controller.isSatisfied(latePrefetchUnknownDown, net, caps, mConstants));
+ assertFalse(controller.isSatisfied(latePrefetchUnknownUp, net, caps, mConstants));
+
+ when(mService.isBatteryCharging()).thenReturn(true);
+ assertTrue(controller.isSatisfied(latePrefetch, net, caps, mConstants));
+ // Only relax restrictions when we at least know the estimated download bytes.
+ assertFalse(controller.isSatisfied(latePrefetchUnknownDown, net, caps, mConstants));
+ assertTrue(controller.isSatisfied(latePrefetchUnknownUp, net, caps, mConstants));
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
index 6304270..305569e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -308,7 +308,6 @@
addDefaultProfileAndParent();
mUms.setBootUser(PROFILE_USER_ID);
-
// Boot user not switchable so return most recently in foreground.
assertWithMessage("getBootUser")
.that(mUmi.getBootUser(/* waitUntilSet= */ false)).isEqualTo(OTHER_USER_ID);
@@ -523,6 +522,24 @@
.isFalse();
}
+ @Test
+ public void testCreateUserWithLongName_TruncatesName() {
+ UserInfo user = mUms.createUserWithThrow(generateLongString(), USER_TYPE_FULL_SECONDARY, 0);
+ assertThat(user.name.length()).isEqualTo(500);
+ UserInfo user1 = mUms.createUserWithThrow("Test", USER_TYPE_FULL_SECONDARY, 0);
+ assertThat(user1.name.length()).isEqualTo(4);
+ }
+
+ private String generateLongString() {
+ String partialString = "Test Name Test Name Test Name Test Name Test Name Test Name Test "
+ + "Name Test Name Test Name Test Name "; //String of length 100
+ StringBuilder resultString = new StringBuilder();
+ for (int i = 0; i < 660; i++) {
+ resultString.append(partialString);
+ }
+ return resultString.toString();
+ }
+
private void removeNonSystemUsers() {
for (UserInfo user : mUms.getUsers(true)) {
if (!user.getUserHandle().isSystem()) {
diff --git a/services/tests/powerstatstests/Android.bp b/services/tests/powerstatstests/Android.bp
index 8ab4507..18a4f00 100644
--- a/services/tests/powerstatstests/Android.bp
+++ b/services/tests/powerstatstests/Android.bp
@@ -16,7 +16,7 @@
"coretests-aidl",
"platformprotosnano",
"junit",
- "truth-prebuilt",
+ "truth",
"androidx.test.runner",
"androidx.test.ext.junit",
"androidx.test.ext.truth",
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 20d8a5d..2ece8c7 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -2,6 +2,13 @@
// Build FrameworksServicesTests package
//########################################################################
+java_defaults {
+ name: "FrameworksServicesTests-jni-defaults",
+ jni_libs: [
+ "libservicestestjni",
+ ],
+}
+
package {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
@@ -13,6 +20,9 @@
android_test {
name: "FrameworksServicesTests",
+ defaults: [
+ "FrameworksServicesTests-jni-defaults",
+ ],
// Include all test java files.
srcs: [
@@ -51,7 +61,7 @@
"mockito-target-minus-junit4",
"platform-test-annotations",
"ShortcutManagerTestUtils",
- "truth-prebuilt",
+ "truth",
"testables",
"androidx.test.uiautomator_uiautomator",
"platformprotosnano",
@@ -62,7 +72,7 @@
// TODO: remove once Android migrates to JUnit 4.12,
// which provides assertThrows
"testng",
- "truth-prebuilt",
+ "truth",
"junit",
"junit-params",
"ActivityContext",
diff --git a/services/tests/servicestests/jni/Android.bp b/services/tests/servicestests/jni/Android.bp
new file mode 100644
index 0000000..174beb8
--- /dev/null
+++ b/services/tests/servicestests/jni/Android.bp
@@ -0,0 +1,58 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+cc_library_shared {
+ name: "libservicestestjni",
+
+ defaults: ["android.hardware.graphics.common-ndk_shared"],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wno-unused-parameter",
+ "-Wthread-safety",
+ ],
+
+ srcs: [
+ ":lib_cachedAppOptimizer_native",
+ ":lib_gameManagerService_native",
+ ":lib_oomConnection_native",
+ "onload.cpp",
+ ],
+
+ include_dirs: [
+ "frameworks/base/libs",
+ "frameworks/native/services",
+ "frameworks/native/libs/math/include",
+ "frameworks/native/libs/ui/include",
+ "system/memory/libmeminfo/include",
+ ],
+
+ shared_libs: [
+ "libandroid",
+ "libandroid_runtime",
+ "libbase",
+ "libbinder",
+ "libgralloctypes",
+ "libgui",
+ "libhidlbase",
+ "liblog",
+ "libmeminfo",
+ "libmemevents",
+ "libnativehelper",
+ "libprocessgroup",
+ "libutils",
+ "libcutils",
+ "android.hardware.graphics.bufferqueue@1.0",
+ "android.hardware.graphics.bufferqueue@2.0",
+ "android.hardware.graphics.common@1.2",
+ "android.hardware.graphics.mapper@4.0",
+ "android.hidl.token@1.0-utils",
+ ],
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/jni/onload.cpp b/services/tests/servicestests/jni/onload.cpp
new file mode 100644
index 0000000..f160b3d
--- /dev/null
+++ b/services/tests/servicestests/jni/onload.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+/*
+ * this is a mini native libaray for cached app optimizer tests to run properly. It
+ * loads all the native methods necessary.
+ */
+#include <nativehelper/JNIHelp.h>
+#include "jni.h"
+#include "utils/Log.h"
+#include "utils/misc.h"
+
+namespace android {
+int register_android_server_am_CachedAppOptimizer(JNIEnv* env);
+int register_android_server_app_GameManagerService(JNIEnv* env);
+int register_android_server_am_OomConnection(JNIEnv* env);
+};
+
+using namespace android;
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
+{
+ JNIEnv* env = NULL;
+ jint result = -1;
+
+ if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+ ALOGE("GetEnv failed!");
+ return result;
+ }
+ ALOG_ASSERT(env, "Could not retrieve the env!");
+ register_android_server_am_CachedAppOptimizer(env);
+ register_android_server_app_GameManagerService(env);
+ register_android_server_am_OomConnection(env);
+ return JNI_VERSION_1_4;
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/AnrHelperTest.java b/services/tests/servicestests/src/com/android/server/am/AnrHelperTest.java
index acdfee9..c0051c6 100644
--- a/services/tests/servicestests/src/com/android/server/am/AnrHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AnrHelperTest.java
@@ -172,4 +172,9 @@
anyString(), any(), any(), any(), anyBoolean(), any(), eq(mAuxExecutorService),
anyBoolean(), anyBoolean(), any());
}
+
+ // TODO: [b/302724778] Remove manual JNI load
+ static {
+ System.loadLibrary("servicestestjni");
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/am/AnrTimerTest.java b/services/tests/servicestests/src/com/android/server/am/AnrTimerTest.java
index 9fdbdda..70527ce 100644
--- a/services/tests/servicestests/src/com/android/server/am/AnrTimerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AnrTimerTest.java
@@ -228,6 +228,7 @@
TestHandler mTestHandler;
TestInjector(int skip, boolean immediate) {
+ super(mHandler);
mTracker = new TestTracker(skip);
mImmediate = immediate;
}
@@ -249,9 +250,16 @@
return mTestHandler;
}
+ @Override
AnrTimer.CpuTracker getTracker() {
return mTracker;
}
+
+ /** For test purposes, always enable the feature. */
+ @Override
+ boolean getFeatureEnabled() {
+ return true;
+ }
}
// Tests
@@ -261,7 +269,6 @@
// 4. Start a couple of timers. Verify max active timers. Discard one and verify the active
// count drops by 1. Accept one and verify the active count drops by 1.
-
@Test
public void testSimpleTimeout() throws Exception {
// Create an immediate TestHandler.
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
index c5ce7f5..9f75cf8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
@@ -43,7 +43,6 @@
import android.app.PropertyInvalidatedCache;
import android.content.pm.UserInfo;
import android.content.pm.UserInfo.UserInfoFlag;
-import android.multiuser.Flags;
import android.os.Looper;
import android.os.Parcel;
import android.os.UserHandle;
@@ -125,34 +124,18 @@
mUserManagerService.putUserInfo(data.info);
- //Local restrictions are written to the user specific files and global restrictions
- // are written to the SYSTEM user file.
+ // Set a global and user restriction so they get written out to the user file.
setUserRestrictions(data.info.id, globalRestriction, localRestriction, true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(baos);
mUserManagerService.writeUserLP(data, out);
- byte[] secondaryUserBytes = baos.toByteArray();
- baos.reset();
-
- byte[] systemUserBytes = new byte[0];
- if (Flags.saveGlobalAndGuestRestrictionsOnSystemUserXml()) {
- UserData systemUserData = new UserData();
- systemUserData.info = mUserManagerService.getUserInfo(UserHandle.USER_SYSTEM);
- mUserManagerService.writeUserLP(systemUserData, baos);
- systemUserBytes = baos.toByteArray();
- }
+ byte[] bytes = baos.toByteArray();
// Clear the restrictions to see if they are properly read in from the user file.
setUserRestrictions(data.info.id, globalRestriction, localRestriction, false);
- //read the secondary and SYSTEM user file to fetch local/global device policy restrictions.
- mUserManagerService.readUserLP(data.info.id, new ByteArrayInputStream(secondaryUserBytes));
- if (Flags.saveGlobalAndGuestRestrictionsOnSystemUserXml()) {
- mUserManagerService.readUserLP(UserHandle.USER_SYSTEM,
- new ByteArrayInputStream(systemUserBytes));
- }
-
+ mUserManagerService.readUserLP(data.info.id, new ByteArrayInputStream(bytes));
assertTrue(mUserManagerService.hasUserRestrictionOnAnyUser(globalRestriction));
assertTrue(mUserManagerService.hasUserRestrictionOnAnyUser(localRestriction));
}
diff --git a/services/tests/uiservicestests/Android.bp b/services/tests/uiservicestests/Android.bp
index 1d37f9d..d1f4961 100644
--- a/services/tests/uiservicestests/Android.bp
+++ b/services/tests/uiservicestests/Android.bp
@@ -39,7 +39,7 @@
"hamcrest-library",
"servicestests-utils",
"testables",
- "truth-prebuilt",
+ "truth",
// TODO: remove once Android migrates to JUnit 4.12,
// which provides assertThrows
"testng",
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationBitmapJobServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationBitmapJobServiceTest.java
index 312057ee..348d1bf 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationBitmapJobServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationBitmapJobServiceTest.java
@@ -44,6 +44,12 @@
import org.mockito.Mock;
import java.lang.reflect.Field;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.ZonedDateTime;
+import java.time.ZoneId;
@RunWith(AndroidTestingRunner.class)
public class NotificationBitmapJobServiceTest extends UiServiceTestCase {
@@ -103,17 +109,39 @@
@Test
public void testGetTimeUntilRemoval_beforeToday2am_returnTimeUntilToday2am() {
- final long timeUntilRemoval = mJobService.getTimeUntilRemoval(/* now= */ 1,
- /* today2AM= */ 2, /* tomorrow2AM= */ 26);
+ ZoneId zoneId = ZoneId.systemDefault();
+ ZonedDateTime now = Instant.now().atZone(zoneId);
+ LocalDate today = now.toLocalDate();
- assertThat(timeUntilRemoval).isEqualTo(1);
+ LocalTime oneAM = LocalTime.of(/* hour= */ 1, /* minute= */ 0);
+ LocalTime twoAM = LocalTime.of(/* hour= */ 2, /* minute= */ 0);
+
+ ZonedDateTime today1AM = ZonedDateTime.of(today, oneAM, zoneId);
+ ZonedDateTime today2AM = ZonedDateTime.of(today, twoAM, zoneId);
+ ZonedDateTime tomorrow2AM = today2AM.plusDays(1);
+
+ final long msUntilRemoval = mJobService.getTimeUntilRemoval(
+ /* now= */ today1AM, today2AM, tomorrow2AM);
+
+ assertThat(msUntilRemoval).isEqualTo(Duration.ofHours(1).toMillis());
}
@Test
public void testGetTimeUntilRemoval_afterToday2am_returnTimeUntilTomorrow2am() {
- final long timeUntilRemoval = mJobService.getTimeUntilRemoval(/* now= */ 3,
- /* today2AM= */ 2, /* tomorrow2AM= */ 26);
+ ZoneId zoneId = ZoneId.systemDefault();
+ ZonedDateTime now = Instant.now().atZone(zoneId);
+ LocalDate today = now.toLocalDate();
- assertThat(timeUntilRemoval).isEqualTo(23);
+ LocalTime threeAM = LocalTime.of(/* hour= */ 3, /* minute= */ 0);
+ LocalTime twoAM = LocalTime.of(/* hour= */ 2, /* minute= */ 0);
+
+ ZonedDateTime today3AM = ZonedDateTime.of(today, threeAM, zoneId);
+ ZonedDateTime today2AM = ZonedDateTime.of(today, twoAM, zoneId);
+ ZonedDateTime tomorrow2AM = today2AM.plusDays(1);
+
+ final long msUntilRemoval = mJobService.getTimeUntilRemoval(/* now= */ today3AM,
+ today2AM, tomorrow2AM);
+
+ assertThat(msUntilRemoval).isEqualTo(Duration.ofHours(23).toMillis());
}
}
\ No newline at end of file
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryJobServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryJobServiceTest.java
index d758e71..3499a12 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryJobServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryJobServiceTest.java
@@ -71,10 +71,10 @@
@Before
public void setUp() throws Exception {
mJobService = new NotificationHistoryJobService();
+ mJobService.attachBaseContext(mContext);
+ mJobService.onCreate();
+ mJobService.onBind(/* intent= */ null); // Create JobServiceEngine within JobService.
- final Field field = JobService.class.getDeclaredField("mEngine");
- field.setAccessible(true);
- field.set(mJobService, mock(JobServiceEngine.class));
mContext.addMockSystemService(JobScheduler.class, mMockJobScheduler);
// add NotificationManagerInternal to LocalServices
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index 7a55143..c05f814 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -462,7 +462,7 @@
}
private void detailedAssertEquals(NotificationRankingUpdate a, NotificationRankingUpdate b) {
- assertEquals(a.getRankingMap(), b.getRankingMap());
+ detailedAssertEquals(a.getRankingMap(), b.getRankingMap());
}
private void detailedAssertEquals(String comment, Ranking a, Ranking b) {
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index c98d235..91129a1 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -91,7 +91,7 @@
import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
-import static com.android.server.notification.NotificationManagerService.BITMAP_EXPIRATION_TIME_MS;
+import static com.android.server.notification.NotificationManagerService.BITMAP_DURATION;
import static com.android.server.notification.NotificationManagerService.DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE;
import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_ADJUSTED;
import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_POSTED;
@@ -11381,7 +11381,7 @@
long timePostedMs = System.currentTimeMillis();
if (isExpired) {
- timePostedMs -= BITMAP_EXPIRATION_TIME_MS;
+ timePostedMs -= BITMAP_DURATION.toMillis();
}
StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
notification, UserHandle.getUserHandleForUid(mUid), null, timePostedMs);
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java
index a91bd2b..0003555 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java
@@ -16,6 +16,8 @@
package com.android.server.vibrator;
+import static android.os.VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY;
+import static android.os.VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF;
import static android.os.VibrationEffect.Composition.PRIMITIVE_CLICK;
import static android.os.VibrationEffect.Composition.PRIMITIVE_TICK;
import static android.os.VibrationEffect.EFFECT_TEXTURE_TICK;
@@ -24,8 +26,13 @@
import static android.view.HapticFeedbackConstants.CONTEXT_CLICK;
import static android.view.HapticFeedbackConstants.SAFE_MODE_ENABLED;
import static android.view.HapticFeedbackConstants.TEXT_HANDLE_MOVE;
+import static android.view.HapticFeedbackConstants.SCROLL_ITEM_FOCUS;
+import static android.view.HapticFeedbackConstants.SCROLL_LIMIT;
+import static android.view.HapticFeedbackConstants.SCROLL_TICK;
+
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.mockito.Mockito.when;
@@ -37,6 +44,7 @@
import android.os.VibratorInfo;
import android.util.AtomicFile;
import android.util.SparseArray;
+import android.view.flags.FeatureFlags;
import androidx.test.InstrumentationRegistry;
@@ -59,23 +67,25 @@
private static final VibrationEffect PRIMITIVE_CLICK_EFFECT =
VibrationEffect.startComposition().addPrimitive(PRIMITIVE_CLICK, 0.3497f).compose();
+ private static final int[] SCROLL_FEEDBACK_CONSTANTS =
+ new int[] {SCROLL_ITEM_FOCUS, SCROLL_LIMIT, SCROLL_TICK};
private Context mContext = InstrumentationRegistry.getContext();
private VibratorInfo mVibratorInfo = VibratorInfo.EMPTY_VIBRATOR_INFO;
@Mock private Resources mResourcesMock;
+ @Mock private FeatureFlags mViewFeatureFlags;
@Test
public void testNonExistentCustomization_useDefault() throws Exception {
// No customization file is set.
- HapticFeedbackVibrationProvider hapticProvider =
- new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo);
+ HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations();
assertThat(hapticProvider.getVibrationForHapticFeedback(CONTEXT_CLICK))
.isEqualTo(VibrationEffect.get(EFFECT_TICK));
// The customization file specifies no customization.
setupCustomizationFile("<haptic-feedback-constants></haptic-feedback-constants>");
- hapticProvider = new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo);
+ hapticProvider = createProviderWithDefaultCustomizations();
assertThat(hapticProvider.getVibrationForHapticFeedback(CONTEXT_CLICK))
.isEqualTo(VibrationEffect.get(EFFECT_TICK));
@@ -84,8 +94,7 @@
@Test
public void testExceptionParsingCustomizations_useDefault() throws Exception {
setupCustomizationFile("<bad-xml></bad-xml>");
- HapticFeedbackVibrationProvider hapticProvider =
- new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo);
+ HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations();
assertThat(hapticProvider.getVibrationForHapticFeedback(CONTEXT_CLICK))
.isEqualTo(VibrationEffect.get(EFFECT_TICK));
@@ -97,8 +106,7 @@
SparseArray<VibrationEffect> customizations = new SparseArray<>();
customizations.put(CONTEXT_CLICK, PRIMITIVE_CLICK_EFFECT);
- HapticFeedbackVibrationProvider hapticProvider =
- new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo, customizations);
+ HapticFeedbackVibrationProvider hapticProvider = createProvider(customizations);
// The override for `CONTEXT_CLICK` is used.
assertThat(hapticProvider.getVibrationForHapticFeedback(CONTEXT_CLICK))
@@ -118,8 +126,7 @@
+ "</haptic-feedback-constants>";
setupCustomizationFile(xml);
- HapticFeedbackVibrationProvider hapticProvider =
- new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo);
+ HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations();
// The override for `CONTEXT_CLICK` is not used because the vibration is not supported.
assertThat(hapticProvider.getVibrationForHapticFeedback(CONTEXT_CLICK))
@@ -137,15 +144,12 @@
customizations.put(TEXT_HANDLE_MOVE, PRIMITIVE_CLICK_EFFECT);
// Test with a customization available for `TEXT_HANDLE_MOVE`.
- HapticFeedbackVibrationProvider hapticProvider =
- new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo, customizations);
+ HapticFeedbackVibrationProvider hapticProvider = createProvider(customizations);
assertThat(hapticProvider.getVibrationForHapticFeedback(TEXT_HANDLE_MOVE)).isNull();
// Test with no customization available for `TEXT_HANDLE_MOVE`.
- hapticProvider =
- new HapticFeedbackVibrationProvider(
- mResourcesMock, mVibratorInfo, /* hapticCustomizations= */ null);
+ hapticProvider = createProvider(/* customizations= */ null);
assertThat(hapticProvider.getVibrationForHapticFeedback(TEXT_HANDLE_MOVE)).isNull();
}
@@ -158,16 +162,13 @@
customizations.put(TEXT_HANDLE_MOVE, PRIMITIVE_CLICK_EFFECT);
// Test with a customization available for `TEXT_HANDLE_MOVE`.
- HapticFeedbackVibrationProvider hapticProvider =
- new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo, customizations);
+ HapticFeedbackVibrationProvider hapticProvider = createProvider(customizations);
assertThat(hapticProvider.getVibrationForHapticFeedback(TEXT_HANDLE_MOVE))
.isEqualTo(PRIMITIVE_CLICK_EFFECT);
// Test with no customization available for `TEXT_HANDLE_MOVE`.
- hapticProvider =
- new HapticFeedbackVibrationProvider(
- mResourcesMock, mVibratorInfo, /* hapticCustomizations= */ null);
+ hapticProvider = createProvider(/* customizations= */ null);
assertThat(hapticProvider.getVibrationForHapticFeedback(TEXT_HANDLE_MOVE))
.isEqualTo(VibrationEffect.get(EFFECT_TEXTURE_TICK));
@@ -181,15 +182,13 @@
SparseArray<VibrationEffect> customizations = new SparseArray<>();
customizations.put(SAFE_MODE_ENABLED, PRIMITIVE_CLICK_EFFECT);
- HapticFeedbackVibrationProvider hapticProvider =
- new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo, customizations);
+ HapticFeedbackVibrationProvider hapticProvider = createProvider(customizations);
assertThat(hapticProvider.getVibrationForHapticFeedback(SAFE_MODE_ENABLED))
.isEqualTo(PRIMITIVE_CLICK_EFFECT);
mockSafeModeEnabledVibration(null);
- hapticProvider =
- new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo, customizations);
+ hapticProvider = createProvider(customizations);
assertThat(hapticProvider.getVibrationForHapticFeedback(SAFE_MODE_ENABLED))
.isEqualTo(PRIMITIVE_CLICK_EFFECT);
@@ -199,9 +198,7 @@
public void testNoValidCustomizationPresentForSafeModeEnabled_resourceBasedVibrationUsed()
throws Exception {
mockSafeModeEnabledVibration(10, 20, 30, 40);
- HapticFeedbackVibrationProvider hapticProvider =
- new HapticFeedbackVibrationProvider(
- mResourcesMock, mVibratorInfo, /* hapticCustomizations= */ null);
+ HapticFeedbackVibrationProvider hapticProvider = createProvider(/* customizations= */ null);
assertThat(hapticProvider.getVibrationForHapticFeedback(SAFE_MODE_ENABLED))
.isEqualTo(VibrationEffect.createWaveform(new long[] {10, 20, 30, 40}, -1));
@@ -211,35 +208,65 @@
public void testNoValidCustomizationAndResourcePresentForSafeModeEnabled_noVibrationUsed()
throws Exception {
mockSafeModeEnabledVibration(null);
- HapticFeedbackVibrationProvider hapticProvider =
- new HapticFeedbackVibrationProvider(
- mResourcesMock, mVibratorInfo, /* hapticCustomizations= */ null);
+ HapticFeedbackVibrationProvider hapticProvider = createProvider(/* customizations= */ null);
assertThat(hapticProvider.getVibrationForHapticFeedback(SAFE_MODE_ENABLED)).isNull();
}
@Test
public void testVibrationAttribute_forNotBypassingIntensitySettings() {
- HapticFeedbackVibrationProvider hapticProvider =
- new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo);
+ HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations();
VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
SAFE_MODE_ENABLED, /* bypassVibrationIntensitySetting= */ false);
- assertThat(attrs.getFlags() & VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)
- .isEqualTo(0);
+ assertThat(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)).isFalse();
}
@Test
public void testVibrationAttribute_forByassingIntensitySettings() {
- HapticFeedbackVibrationProvider hapticProvider =
- new HapticFeedbackVibrationProvider(mResourcesMock, mVibratorInfo);
+ HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations();
VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
SAFE_MODE_ENABLED, /* bypassVibrationIntensitySetting= */ true);
- assertThat(attrs.getFlags() & VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)
- .isNotEqualTo(0);
+ assertThat(attrs.isFlagSet(FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF)).isTrue();
+ }
+
+ @Test
+ public void testVibrationAttribute_scrollFeedback_scrollApiFlagOn_bypassInterruptPolicy() {
+ when(mViewFeatureFlags.scrollFeedbackApi()).thenReturn(true);
+ HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations();
+
+ for (int effectId : SCROLL_FEEDBACK_CONSTANTS) {
+ VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
+ effectId, /* bypassVibrationIntensitySetting= */ false);
+ assertWithMessage("Expected FLAG_BYPASS_INTERRUPTION_POLICY for effect " + effectId)
+ .that(attrs.isFlagSet(FLAG_BYPASS_INTERRUPTION_POLICY)).isTrue();
+ }
+ }
+
+ @Test
+ public void testVibrationAttribute_scrollFeedback_scrollApiFlagOff_noBypassInterruptPolicy() {
+ when(mViewFeatureFlags.scrollFeedbackApi()).thenReturn(false);
+ HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations();
+
+ for (int effectId : SCROLL_FEEDBACK_CONSTANTS) {
+ VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback(
+ effectId, /* bypassVibrationIntensitySetting= */ false);
+ assertWithMessage("Expected no FLAG_BYPASS_INTERRUPTION_POLICY for effect " + effectId)
+ .that(attrs.isFlagSet(FLAG_BYPASS_INTERRUPTION_POLICY)).isFalse();
+ }
+ }
+
+ private HapticFeedbackVibrationProvider createProviderWithDefaultCustomizations() {
+ return createProvider(/* customizations= */ null);
+ }
+
+ private HapticFeedbackVibrationProvider createProvider(
+ SparseArray<VibrationEffect> customizations) {
+ return new HapticFeedbackVibrationProvider(
+ mResourcesMock, mVibratorInfo, customizations, mViewFeatureFlags);
}
private void mockVibratorPrimitiveSupport(int... supportedPrimitives) {
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index 0eec9cd..40e0e84 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -31,6 +31,7 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
@@ -46,6 +47,7 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.res.Resources;
import android.hardware.input.IInputManager;
@@ -87,6 +89,7 @@
import android.view.Display;
import android.view.HapticFeedbackConstants;
import android.view.InputDevice;
+import android.view.flags.FeatureFlags;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.FlakyTest;
@@ -172,6 +175,8 @@
private VirtualDeviceManagerInternal mVirtualDeviceManagerInternalMock;
@Mock
private AudioManager mAudioManagerMock;
+ @Mock
+ private FeatureFlags mViewFeatureFlags;
private final Map<Integer, FakeVibratorControllerProvider> mVibratorProviders = new HashMap<>();
@@ -321,7 +326,8 @@
HapticFeedbackVibrationProvider createHapticFeedbackVibrationProvider(
Resources resources, VibratorInfo vibratorInfo) {
return new HapticFeedbackVibrationProvider(
- resources, vibratorInfo, mHapticFeedbackVibrationMap);
+ resources, vibratorInfo, mHapticFeedbackVibrationMap,
+ mViewFeatureFlags);
}
});
return mService;
@@ -649,6 +655,42 @@
}
@Test
+ public void vibrate_withoutBypassFlagsPermissions_bypassFlagsNotApplied() throws Exception {
+ denyPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS);
+ denyPermission(android.Manifest.permission.MODIFY_PHONE_STATE);
+ denyPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING);
+
+ assertCanVibrateWithBypassFlags(false);
+ }
+
+ @Test
+ public void vibrate_withSecureSettingsPermission_bypassFlagsApplied() throws Exception {
+ grantPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS);
+ denyPermission(android.Manifest.permission.MODIFY_PHONE_STATE);
+ denyPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING);
+
+ assertCanVibrateWithBypassFlags(true);
+ }
+
+ @Test
+ public void vibrate_withModifyPhoneStatePermission_bypassFlagsApplied() throws Exception {
+ denyPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS);
+ grantPermission(android.Manifest.permission.MODIFY_PHONE_STATE);
+ denyPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING);
+
+ assertCanVibrateWithBypassFlags(true);
+ }
+
+ @Test
+ public void vibrate_withModifyAudioRoutingPermission_bypassFlagsApplied() throws Exception {
+ denyPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS);
+ denyPermission(android.Manifest.permission.MODIFY_PHONE_STATE);
+ grantPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING);
+
+ assertCanVibrateWithBypassFlags(true);
+ }
+
+ @Test
public void vibrate_withRingtone_usesRingerModeSettings() throws Exception {
mockVibrators(1);
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1);
@@ -1166,7 +1208,7 @@
}
@Test
- public void vibrate_withTriggerCallback_finishesVibration() throws Exception {
+ public void vibrate_withriggerCallback_finishesVibration() throws Exception {
mockCapabilities(IVibratorManager.CAP_SYNC, IVibratorManager.CAP_PREPARE_COMPOSE);
mockVibrators(1, 2);
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
@@ -1303,10 +1345,18 @@
}
@Test
- public void performHapticFeedback_doesNotRequirePermission() throws Exception {
+ public void performHapticFeedback_doesNotRequireVibrateOrBypassPermissions() throws Exception {
+ // Deny permissions that would have been required for regular vibrations, and check that
+ // the vibration proceed as expected to verify that haptic feedback does not need these
+ // permissions.
denyPermission(android.Manifest.permission.VIBRATE);
+ denyPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS);
+ denyPermission(android.Manifest.permission.MODIFY_PHONE_STATE);
+ denyPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING);
+ // Flag override to enable the scroll feedack constants to bypass interruption policies.
+ when(mViewFeatureFlags.scrollFeedbackApi()).thenReturn(true);
mHapticFeedbackVibrationMap.put(
- HapticFeedbackConstants.KEYBOARD_TAP,
+ HapticFeedbackConstants.SCROLL_TICK,
VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
mockVibrators(1);
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1);
@@ -1315,13 +1365,16 @@
HalVibration vibration =
performHapticFeedbackAndWaitUntilFinished(
- service, HapticFeedbackConstants.KEYBOARD_TAP, /* always= */ true);
+ service, HapticFeedbackConstants.SCROLL_TICK, /* always= */ true);
List<VibrationEffectSegment> playedSegments = fakeVibrator.getAllEffectSegments();
assertEquals(1, playedSegments.size());
PrebakedSegment segment = (PrebakedSegment) playedSegments.get(0);
assertEquals(VibrationEffect.EFFECT_CLICK, segment.getEffectId());
- assertEquals(VibrationAttributes.USAGE_TOUCH, vibration.callerInfo.attrs.getUsage());
+ VibrationAttributes attrs = vibration.callerInfo.attrs;
+ assertEquals(VibrationAttributes.USAGE_HARDWARE_FEEDBACK, attrs.getUsage());
+ assertTrue(attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF));
+ assertTrue(attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY));
}
@Test
@@ -2261,6 +2314,31 @@
assertNull(metrics.halUnsupportedEffectsUsed);
}
+ private void assertCanVibrateWithBypassFlags(boolean expectedCanApplyBypassFlags)
+ throws Exception {
+ mockVibrators(1);
+ mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
+ VibratorManagerService service = createSystemReadyService();
+
+ HalVibration vibration = vibrateAndWaitUntilFinished(
+ service,
+ VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK),
+ new VibrationAttributes.Builder()
+ .setUsage(VibrationAttributes.USAGE_TOUCH)
+ .setFlags(
+ VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF
+ | VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY)
+ .build());
+
+ VibrationAttributes attrs = vibration.callerInfo.attrs;
+ assertEquals(
+ expectedCanApplyBypassFlags,
+ attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_USER_VIBRATION_INTENSITY_OFF));
+ assertEquals(
+ expectedCanApplyBypassFlags,
+ attrs.isFlagSet(VibrationAttributes.FLAG_BYPASS_INTERRUPTION_POLICY));
+ }
+
private VibrationEffectSegment expectedPrebaked(int effectId) {
return expectedPrebaked(effectId, VibrationEffect.EFFECT_STRENGTH_MEDIUM);
}
@@ -2327,12 +2405,13 @@
return vib;
}
- private void vibrateAndWaitUntilFinished(VibratorManagerService service, VibrationEffect effect,
- VibrationAttributes attrs) throws InterruptedException {
- vibrateAndWaitUntilFinished(service, CombinedVibration.createParallel(effect), attrs);
+ private HalVibration vibrateAndWaitUntilFinished(VibratorManagerService service,
+ VibrationEffect effect, VibrationAttributes attrs) throws InterruptedException {
+ return vibrateAndWaitUntilFinished(
+ service, CombinedVibration.createParallel(effect), attrs);
}
- private void vibrateAndWaitUntilFinished(VibratorManagerService service,
+ private HalVibration vibrateAndWaitUntilFinished(VibratorManagerService service,
CombinedVibration effect, VibrationAttributes attrs) throws InterruptedException {
HalVibration vib =
service.vibrateWithPermissionCheck(UID, Display.DEFAULT_DISPLAY, PACKAGE_NAME,
@@ -2340,6 +2419,8 @@
if (vib != null) {
vib.waitForEnd();
}
+
+ return vib;
}
private void vibrate(VibratorManagerService service, VibrationEffect effect,
@@ -2368,7 +2449,15 @@
return predicateResult;
}
+ private void grantPermission(String permission) {
+ when(mContextSpy.checkCallingOrSelfPermission(permission))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
+ doNothing().when(mContextSpy).enforceCallingOrSelfPermission(eq(permission), anyString());
+ }
+
private void denyPermission(String permission) {
+ when(mContextSpy.checkCallingOrSelfPermission(permission))
+ .thenReturn(PackageManager.PERMISSION_DENIED);
doThrow(new SecurityException()).when(mContextSpy)
.enforceCallingOrSelfPermission(eq(permission), anyString());
}
diff --git a/services/tests/voiceinteractiontests/Android.bp b/services/tests/voiceinteractiontests/Android.bp
index e704ebf..744cb63 100644
--- a/services/tests/voiceinteractiontests/Android.bp
+++ b/services/tests/voiceinteractiontests/Android.bp
@@ -43,7 +43,7 @@
"services.soundtrigger",
"servicestests-core-utils",
"servicestests-utils-mockito-extended",
- "truth-prebuilt",
+ "truth",
],
libs: [
diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp
index c2812a1..af39b2f 100644
--- a/services/tests/wmtests/Android.bp
+++ b/services/tests/wmtests/Android.bp
@@ -57,12 +57,14 @@
"platform-test-annotations",
"servicestests-utils",
"testng",
- "truth-prebuilt",
+ "truth",
"testables",
"hamcrest-library",
"platform-compat-test-rules",
"CtsSurfaceValidatorLib",
"service-sdksandbox.impl",
+ "com.android.window.flags.window-aconfig-java",
+ "flag-junit",
],
libs: [
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 42e3383..762e23c 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -47,6 +47,8 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_MEDIA_PROJECTION"/>
+ <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"/>
+ <uses-permission android:name="android.permission.MONITOR_INPUT"/>
<!-- TODO: Remove largeHeap hack when memory leak is fixed (b/123984854) -->
<application android:debuggable="true"
@@ -104,6 +106,11 @@
android:showWhenLocked="true"
android:turnScreenOn="true" />
+ <activity android:name="android.app.Activity"
+ android:exported="true"
+ android:showWhenLocked="true"
+ android:turnScreenOn="true" />
+
<activity
android:name="androidx.test.core.app.InstrumentationActivityInvoker$EmptyActivity"
android:exported="true">
diff --git a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
index 0a7bb00..71098aa 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ShortcutLoggingTests.java
@@ -20,6 +20,7 @@
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_HOME_ALL_APPS;
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_HOME_ASSIST;
import static com.android.server.policy.PhoneWindowManager.LONG_PRESS_HOME_NOTIFICATION_PANEL;
+import static com.android.server.policy.PhoneWindowManager.SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL;
import android.platform.test.annotations.Presubmit;
import android.view.KeyEvent;
@@ -284,6 +285,16 @@
KeyboardLogEvent.APP_SWITCH, KeyEvent.KEYCODE_H, META_ON}};
}
+ @Keep
+ private static Object[][] shortPressOnSettingsTestArguments() {
+ // testName, testKeys, shortPressOnSettingsBehavior, expectedLogEvent, expectedKey,
+ // expectedModifierState
+ return new Object[][]{
+ {"SETTINGS key -> Toggle Notification panel", new int[]{KeyEvent.KEYCODE_SETTINGS},
+ SHORT_PRESS_SETTINGS_NOTIFICATION_PANEL,
+ KeyboardLogEvent.TOGGLE_NOTIFICATION_PANEL, KeyEvent.KEYCODE_SETTINGS, 0}};
+ }
+
@Before
public void setUp() {
setUpPhoneWindowManager(/*supportSettingsUpdate*/ true);
@@ -294,6 +305,7 @@
mPhoneWindowManager.overrideEnableBugReportTrigger(true);
mPhoneWindowManager.overrideStatusBarManagerInternal();
mPhoneWindowManager.overrideStartActivity();
+ mPhoneWindowManager.overrideSendBroadcast();
mPhoneWindowManager.overrideUserSetupComplete();
mPhoneWindowManager.setupAssistForLaunch();
mPhoneWindowManager.overrideTogglePanel();
@@ -330,4 +342,15 @@
mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent,
expectedKey, expectedModifierState, "Failed while executing " + testName);
}
+
+ @Test
+ @Parameters(method = "shortPressOnSettingsTestArguments")
+ public void testShortPressOnSettings(String testName, int[] testKeys,
+ int shortPressOnSettingsBehavior, KeyboardLogEvent expectedLogEvent, int expectedKey,
+ int expectedModifierState) {
+ mPhoneWindowManager.overrideShortPressOnSettingsBehavior(shortPressOnSettingsBehavior);
+ sendKeyCombination(testKeys, 0 /* duration */);
+ mPhoneWindowManager.assertShortcutLogged(VENDOR_ID, PRODUCT_ID, expectedLogEvent,
+ expectedKey, expectedModifierState, "Failed while executing " + testName);
+ }
}
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 ef28ffa..2244dbe 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -375,6 +375,10 @@
mPhoneWindowManager.mDoubleTapOnHomeBehavior = behavior;
}
+ void overrideShortPressOnSettingsBehavior(int behavior) {
+ mPhoneWindowManager.mShortPressOnSettingsBehavior = behavior;
+ }
+
void overrideCanStartDreaming(boolean canDream) {
doReturn(canDream).when(mDreamManagerInternal).canStartDreaming(anyBoolean());
}
@@ -484,6 +488,10 @@
doNothing().when(mContext).startActivityAsUser(any(), any(), any());
}
+ void overrideSendBroadcast() {
+ doNothing().when(mContext).sendBroadcastAsUser(any(), any(), any());
+ }
+
void overrideUserSetupComplete() {
doReturn(true).when(mPhoneWindowManager).isUserSetupComplete();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 3bc6450..c241033 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -549,10 +549,12 @@
// Let's pretend that the app has crashed.
firstActivity.app.setThread(null);
- mRootWindowContainer.finishTopCrashedActivities(firstActivity.app, "test");
+ final Task finishedTask = mRootWindowContainer.finishTopCrashedActivities(
+ firstActivity.app, "test");
// Verify that the root task was removed.
assertEquals(originalRootTaskCount, defaultTaskDisplayArea.getRootTaskCount());
+ assertEquals(rootTask, finishedTask);
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceControlViewHostTests.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceControlViewHostTests.java
index c1d5147..8119fd4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceControlViewHostTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceControlViewHostTests.java
@@ -138,11 +138,11 @@
IWindow window = IWindow.Stub.asInterface(mActivity.mSurfaceView.getWindowToken());
WindowManagerGlobal.getWindowSession().grantEmbeddedWindowFocus(window,
- mScvh1.getFocusGrantToken(), true);
+ mScvh1.getInputTransferToken(), true);
assertTrue("Failed to gain focus for view1", waitForWindowFocus(mView1, true));
WindowManagerGlobal.getWindowSession().grantEmbeddedWindowFocus(window,
- mScvh2.getFocusGrantToken(), true);
+ mScvh2.getInputTransferToken(), true);
assertTrue("Failed to gain focus for view2", waitForWindowFocus(mView2, true));
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TrustedOverlayTests.java b/services/tests/wmtests/src/com/android/server/wm/TrustedOverlayTests.java
new file mode 100644
index 0000000..ac49839
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/TrustedOverlayTests.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.os.IBinder;
+import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.server.wm.BuildUtils;
+import android.server.wm.CtsWindowInfoUtils;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.WindowManager;
+
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.window.flags.Flags;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@Presubmit
+public class TrustedOverlayTests {
+ private static final String TAG = "TrustedOverlayTests";
+ private static final long TIMEOUT_S = 5L * BuildUtils.HW_TIMEOUT_MULTIPLIER;
+
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
+ @Rule
+ public TestName mName = new TestName();
+
+ @Rule
+ public final ActivityScenarioRule<Activity> mActivityRule = new ActivityScenarioRule<>(
+ Activity.class);
+
+ private Instrumentation mInstrumentation;
+ private Activity mActivity;
+
+ @Before
+ public void setup() {
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ mActivityRule.getScenario().onActivity(activity -> {
+ mActivity = activity;
+ });
+ }
+
+ @RequiresFlagsDisabled(Flags.FLAG_SURFACE_TRUSTED_OVERLAY)
+ @Test
+ public void setTrustedOverlayInputWindow() throws InterruptedException {
+ testTrustedOverlayChildHelper(false);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_SURFACE_TRUSTED_OVERLAY)
+ public void setTrustedOverlayChildLayer() throws InterruptedException {
+ testTrustedOverlayChildHelper(true);
+ }
+
+ /**
+ * b/300659960 where setting spy window and trusted overlay were not happening in the same
+ * transaction causing the system to crash. This ensures there are no synchronization issues
+ * setting both spy window and trusted overlay.
+ */
+ @Test
+ public void setSpyWindowDoesntCrash() throws InterruptedException {
+ IBinder[] tokens = new IBinder[1];
+ CountDownLatch hostTokenReady = new CountDownLatch(1);
+ mInstrumentation.runOnMainSync(() -> {
+ WindowManager.LayoutParams params = mActivity.getWindow().getAttributes();
+ params.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_SPY;
+ params.privateFlags |= PRIVATE_FLAG_TRUSTED_OVERLAY;
+ mActivity.getWindow().setAttributes(params);
+
+ View rootView = mActivity.getWindow().getDecorView();
+ if (rootView.isAttachedToWindow()) {
+ tokens[0] = rootView.getWindowToken();
+ hostTokenReady.countDown();
+ } else {
+ rootView.getViewTreeObserver().addOnWindowAttachListener(
+ new ViewTreeObserver.OnWindowAttachListener() {
+ @Override
+ public void onWindowAttached() {
+ tokens[0] = rootView.getWindowToken();
+ hostTokenReady.countDown();
+ }
+
+ @Override
+ public void onWindowDetached() {
+ }
+ });
+ }
+ });
+
+ assertTrue("Failed to wait for host to get added",
+ hostTokenReady.await(TIMEOUT_S, TimeUnit.SECONDS));
+
+ boolean[] foundTrusted = new boolean[1];
+ CtsWindowInfoUtils.waitForWindowInfos(
+ windowInfos -> {
+ for (var windowInfo : windowInfos) {
+ if (windowInfo.windowToken == tokens[0] && windowInfo.isTrustedOverlay) {
+ foundTrusted[0] = true;
+ return true;
+ }
+ }
+ return false;
+ }, TIMEOUT_S, TimeUnit.SECONDS);
+
+ if (!foundTrusted[0]) {
+ CtsWindowInfoUtils.dumpWindowsOnScreen(TAG, mName.getMethodName());
+ }
+
+ assertTrue("Failed to find window or was not marked trusted", foundTrusted[0]);
+ }
+
+ private void testTrustedOverlayChildHelper(boolean expectedTrustedChild)
+ throws InterruptedException {
+ IBinder[] tokens = new IBinder[2];
+ CountDownLatch hostTokenReady = new CountDownLatch(1);
+ mInstrumentation.runOnMainSync(() -> {
+ mActivity.getWindow().addPrivateFlags(PRIVATE_FLAG_TRUSTED_OVERLAY);
+ View rootView = mActivity.getWindow().getDecorView();
+ if (rootView.isAttachedToWindow()) {
+ tokens[0] = rootView.getWindowToken();
+ hostTokenReady.countDown();
+ } else {
+ rootView.getViewTreeObserver().addOnWindowAttachListener(
+ new ViewTreeObserver.OnWindowAttachListener() {
+ @Override
+ public void onWindowAttached() {
+ tokens[0] = rootView.getWindowToken();
+ hostTokenReady.countDown();
+ }
+
+ @Override
+ public void onWindowDetached() {
+ }
+ });
+ }
+ });
+
+ assertTrue("Failed to wait for host to get added",
+ hostTokenReady.await(TIMEOUT_S, TimeUnit.SECONDS));
+
+ mInstrumentation.runOnMainSync(() -> {
+ WindowManager wm = mActivity.getSystemService(WindowManager.class);
+
+ View childView = new View(mActivity) {
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ tokens[1] = getWindowToken();
+ }
+ };
+ WindowManager.LayoutParams params = new WindowManager.LayoutParams();
+ params.token = tokens[0];
+ params.type = TYPE_APPLICATION_PANEL;
+ wm.addView(childView, params);
+ });
+
+ boolean[] foundTrusted = new boolean[2];
+
+ CtsWindowInfoUtils.waitForWindowInfos(
+ windowInfos -> {
+ for (var windowInfo : windowInfos) {
+ if (windowInfo.windowToken == tokens[0]
+ && windowInfo.isTrustedOverlay) {
+ foundTrusted[0] = true;
+ } else if (windowInfo.windowToken == tokens[1]
+ && windowInfo.isTrustedOverlay) {
+ foundTrusted[1] = true;
+ }
+ }
+ return foundTrusted[0] && foundTrusted[1];
+ }, TIMEOUT_S, TimeUnit.SECONDS);
+
+ if (!foundTrusted[0] || !foundTrusted[1]) {
+ CtsWindowInfoUtils.dumpWindowsOnScreen(TAG, mName.getMethodName());
+ }
+
+ assertTrue("Failed to find parent window or was not marked trusted", foundTrusted[0]);
+ assertEquals("Failed to find child window or was not marked trusted", expectedTrustedChild,
+ foundTrusted[1]);
+ }
+}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsHandlerThread.java b/services/usage/java/com/android/server/usage/UsageStatsHandlerThread.java
deleted file mode 100644
index 6801c94..0000000
--- a/services/usage/java/com/android/server/usage/UsageStatsHandlerThread.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2023 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.usage;
-
-import android.os.Handler;
-import android.os.HandlerExecutor;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Process;
-import android.os.Trace;
-
-import java.util.concurrent.Executor;
-
-/**
- * Shared singleton default priority thread for usage stats message handling.
- *
- * @see com.android.internal.os.BackgroundThread
- */
-public final class UsageStatsHandlerThread extends HandlerThread {
- private static final long SLOW_DISPATCH_THRESHOLD_MS = 10_000;
- private static final long SLOW_DELIVERY_THRESHOLD_MS = 30_000;
- private static UsageStatsHandlerThread sInstance;
- private static Handler sHandler;
- private static Executor sHandlerExecutor;
-
- private UsageStatsHandlerThread() {
- super("usagestats.default", Process.THREAD_PRIORITY_DEFAULT);
- }
-
- private static void ensureThreadLocked() {
- if (sInstance == null) {
- sInstance = new UsageStatsHandlerThread();
- sInstance.start();
- final Looper looper = sInstance.getLooper();
- looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER);
- looper.setSlowLogThresholdMs(
- SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
- sHandler = new Handler(sInstance.getLooper());
- sHandlerExecutor = new HandlerExecutor(sHandler);
- }
- }
-
- /** Returns the UsageStatsHandlerThread singleton */
- public static UsageStatsHandlerThread get() {
- synchronized (UsageStatsHandlerThread.class) {
- ensureThreadLocked();
- return sInstance;
- }
- }
-
- /** Returns the singleton handler for UsageStatsHandlerThread */
- public static Handler getHandler() {
- synchronized (UsageStatsHandlerThread.class) {
- ensureThreadLocked();
- return sHandler;
- }
- }
-
- /** Returns the singleton handler executor for UsageStatsHandlerThread */
- public static Executor getExecutor() {
- synchronized (UsageStatsHandlerThread.class) {
- ensureThreadLocked();
- return sHandlerExecutor;
- }
- }
-}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 18c960e..f3bf026 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -332,8 +332,7 @@
mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
mPackageManager = getContext().getPackageManager();
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
-
- mHandler = new H(UsageStatsHandlerThread.get().getLooper());
+ mHandler = new H(BackgroundThread.get().getLooper());
mIoHandler = new Handler(IoThread.get().getLooper(), mIoHandlerCallback);
mAppStandby = mInjector.getAppStandbyController(getContext());
@@ -495,9 +494,12 @@
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "loadPendingEvents");
loadPendingEventsLocked(userId, pendingEvents);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
- final LinkedList<Event> eventsInMem = mReportedEvents.get(userId);
- if (eventsInMem != null) {
- pendingEvents.addAll(eventsInMem);
+ synchronized (mReportedEvents) {
+ final LinkedList<Event> eventsInMem = mReportedEvents.get(userId);
+ if (eventsInMem != null) {
+ pendingEvents.addAll(eventsInMem);
+ mReportedEvents.remove(userId);
+ }
}
boolean needToFlush = !pendingEvents.isEmpty();
@@ -518,8 +520,7 @@
mIoHandler.obtainMessage(MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK,
userId, 0).sendToTarget();
- // Remove all the stats stored in memory and in system DE.
- mReportedEvents.remove(userId);
+ // Remove all the stats stored in system DE.
deleteRecursively(new File(Environment.getDataSystemDeDirectory(userId), "usagestats"));
// Force a flush to disk for the current user to ensure important events are persisted.
@@ -916,6 +917,7 @@
}
}
+ @GuardedBy({"mLock", "mReportedEvents"})
private void persistPendingEventsLocked(int userId) {
final LinkedList<Event> pendingEvents = mReportedEvents.get(userId);
if (pendingEvents == null || pendingEvents.isEmpty()) {
@@ -1019,7 +1021,7 @@
+ UserUsageStatsService.eventToString(event.mEventType);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, traceTag);
}
- synchronized (mLock) {
+ synchronized (mReportedEvents) {
LinkedList<Event> events = mReportedEvents.get(userId);
if (events == null) {
events = new LinkedList<>();
@@ -1943,16 +1945,19 @@
idpw.println();
}
} else {
- final LinkedList<Event> pendingEvents = mReportedEvents.get(userId);
- if (pendingEvents != null && !pendingEvents.isEmpty()) {
- final int eventCount = pendingEvents.size();
- idpw.println("Pending events: count=" + eventCount);
- idpw.increaseIndent();
- for (int idx = 0; idx < eventCount; idx++) {
- UserUsageStatsService.printEvent(idpw, pendingEvents.get(idx), true);
+ synchronized (mReportedEvents) {
+ final LinkedList<Event> pendingEvents = mReportedEvents.get(userId);
+ if (pendingEvents != null && !pendingEvents.isEmpty()) {
+ final int eventCount = pendingEvents.size();
+ idpw.println("Pending events: count=" + eventCount);
+ idpw.increaseIndent();
+ for (int idx = 0; idx < eventCount; idx++) {
+ UserUsageStatsService.printEvent(idpw, pendingEvents.get(idx),
+ true);
+ }
+ idpw.decreaseIndent();
+ idpw.println();
}
- idpw.decreaseIndent();
- idpw.println();
}
}
idpw.decreaseIndent();
diff --git a/tests/BatteryStatsPerfTest/Android.bp b/tests/BatteryStatsPerfTest/Android.bp
index 5233a5b..c2a7015 100644
--- a/tests/BatteryStatsPerfTest/Android.bp
+++ b/tests/BatteryStatsPerfTest/Android.bp
@@ -27,7 +27,7 @@
static_libs: [
"androidx.test.rules",
"apct-perftests-utils",
- "truth-prebuilt",
+ "truth",
],
platform_apis: true,
certificate: "platform",
diff --git a/tests/BinaryTransparencyHostTest/Android.bp b/tests/BinaryTransparencyHostTest/Android.bp
index 615990f..38cb9869 100644
--- a/tests/BinaryTransparencyHostTest/Android.bp
+++ b/tests/BinaryTransparencyHostTest/Android.bp
@@ -30,7 +30,7 @@
"compatibility-host-util",
],
static_libs: [
- "truth-prebuilt",
+ "truth",
],
data: [
":BinaryTransparencyTestApp",
diff --git a/tests/BlobStoreTestUtils/Android.bp b/tests/BlobStoreTestUtils/Android.bp
index c4faf7f..1fb73e2 100644
--- a/tests/BlobStoreTestUtils/Android.bp
+++ b/tests/BlobStoreTestUtils/Android.bp
@@ -22,12 +22,12 @@
}
java_library {
- name: "BlobStoreTestUtils",
- srcs: ["src/**/*.java"],
- static_libs: [
- "truth-prebuilt",
- "androidx.test.uiautomator_uiautomator",
- "androidx.test.ext.junit",
- ],
- sdk_version: "test_current",
+ name: "BlobStoreTestUtils",
+ srcs: ["src/**/*.java"],
+ static_libs: [
+ "truth",
+ "androidx.test.uiautomator_uiautomator",
+ "androidx.test.ext.junit",
+ ],
+ sdk_version: "test_current",
}
diff --git a/tests/ChoreographerTests/Android.bp b/tests/ChoreographerTests/Android.bp
index ca30267..5d49120 100644
--- a/tests/ChoreographerTests/Android.bp
+++ b/tests/ChoreographerTests/Android.bp
@@ -34,7 +34,7 @@
"androidx.test.rules",
"compatibility-device-util-axt",
"com.google.android.material_material",
- "truth-prebuilt",
+ "truth",
],
jni_libs: [
"libchoreographertests_jni",
diff --git a/tests/CtsSurfaceControlTestsStaging/Android.bp b/tests/CtsSurfaceControlTestsStaging/Android.bp
index 6809521..96e4a9e 100644
--- a/tests/CtsSurfaceControlTestsStaging/Android.bp
+++ b/tests/CtsSurfaceControlTestsStaging/Android.bp
@@ -37,7 +37,7 @@
"compatibility-device-util-axt",
"com.google.android.material_material",
"SurfaceFlingerProperties",
- "truth-prebuilt",
+ "truth",
],
resource_dirs: ["src/main/res"],
certificate: "platform",
diff --git a/tests/DynamicCodeLoggerIntegrationTests/Android.bp b/tests/DynamicCodeLoggerIntegrationTests/Android.bp
index 448d46f..3f2c808 100644
--- a/tests/DynamicCodeLoggerIntegrationTests/Android.bp
+++ b/tests/DynamicCodeLoggerIntegrationTests/Android.bp
@@ -47,7 +47,7 @@
static_libs: [
"androidx.test.rules",
- "truth-prebuilt",
+ "truth",
],
compile_multilib: "both",
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
index a2ae56e..82aa85d 100644
--- a/tests/FlickerTests/Android.bp
+++ b/tests/FlickerTests/Android.bp
@@ -236,7 +236,7 @@
static_libs: [
"flickerlib",
"flickerlib-helpers",
- "truth-prebuilt",
+ "truth",
"app-helpers-core",
],
}
@@ -255,7 +255,7 @@
"flickerlib",
"flickerlib-apphelpers",
"flickerlib-helpers",
- "truth-prebuilt",
+ "truth",
"app-helpers-core",
"wm-flicker-window-extensions",
],
diff --git a/tests/FsVerityTest/TEST_MAPPING b/tests/FsVerityTest/TEST_MAPPING
index 39944be..7d59d77 100644
--- a/tests/FsVerityTest/TEST_MAPPING
+++ b/tests/FsVerityTest/TEST_MAPPING
@@ -1,12 +1,7 @@
{
- "postsubmit": [
+ "presubmit": [
{
"name": "FsVerityTest"
- },
- // nextgen test only runs during postsubmit.
- {
- "name": "FsVerityTest",
- "keywords": ["nextgen"]
}
]
}
diff --git a/tests/Input/Android.bp b/tests/Input/Android.bp
index 365e00e..cf2d5d6 100644
--- a/tests/Input/Android.bp
+++ b/tests/Input/Android.bp
@@ -9,6 +9,10 @@
android_test {
name: "InputTests",
+ defaults: [
+ // For ExtendedMockito dependencies.
+ "modules-utils-testable-device-config-defaults",
+ ],
srcs: [
"src/**/*.java",
"src/**/*.kt",
@@ -35,7 +39,7 @@
"services.core.unboosted",
"testables",
"testng",
- "truth-prebuilt",
+ "truth",
],
libs: [
"android.test.mock",
diff --git a/tests/Input/src/com/android/server/input/FocusEventDebugViewTest.java b/tests/Input/src/com/android/server/input/FocusEventDebugViewTest.java
deleted file mode 100644
index 1b98887..0000000
--- a/tests/Input/src/com/android/server/input/FocusEventDebugViewTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2023 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.input;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.view.InputChannel;
-import android.view.InputDevice;
-import android.view.MotionEvent;
-import android.view.MotionEvent.PointerCoords;
-import android.view.MotionEvent.PointerProperties;
-import android.view.ViewConfiguration;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Build/Install/Run:
- * atest FocusEventDebugViewTest
- */
-@RunWith(AndroidJUnit4.class)
-public class FocusEventDebugViewTest {
-
- private FocusEventDebugView mFocusEventDebugView;
- private FocusEventDebugView.RotaryInputValueView mRotaryInputValueView;
- private FocusEventDebugView.RotaryInputGraphView mRotaryInputGraphView;
- private float mScaledVerticalScrollFactor;
-
- @Before
- public void setUp() throws Exception {
- Context context = InstrumentationRegistry.getContext();
- mScaledVerticalScrollFactor =
- ViewConfiguration.get(context).getScaledVerticalScrollFactor();
- InputManagerService mockService = mock(InputManagerService.class);
- when(mockService.monitorInput(anyString(), anyInt()))
- .thenReturn(InputChannel.openInputChannelPair("FocusEventDebugViewTest")[1]);
-
- mRotaryInputValueView = new FocusEventDebugView.RotaryInputValueView(context);
- mRotaryInputGraphView = new FocusEventDebugView.RotaryInputGraphView(context);
- mFocusEventDebugView = new FocusEventDebugView(context, mockService,
- () -> mRotaryInputValueView, () -> mRotaryInputGraphView);
- }
-
- @Test
- public void startsRotaryInputValueViewWithDefaultValue() {
- assertEquals("+0.0", mRotaryInputValueView.getText());
- }
-
- @Test
- public void startsRotaryInputGraphViewWithDefaultFrameCenter() {
- assertEquals(0, mRotaryInputGraphView.getFrameCenterPosition(), 0.01);
- }
-
- @Test
- public void handleRotaryInput_updatesRotaryInputValueViewWithScrollValue() {
- mFocusEventDebugView.handleUpdateShowRotaryInput(true);
-
- mFocusEventDebugView.handleRotaryInput(createRotaryMotionEvent(0.5f));
-
- assertEquals(String.format("+%.1f", 0.5f * mScaledVerticalScrollFactor),
- mRotaryInputValueView.getText());
- }
-
- @Test
- public void handleRotaryInput_translatesRotaryInputGraphViewWithHighScrollValue() {
- mFocusEventDebugView.handleUpdateShowRotaryInput(true);
-
- mFocusEventDebugView.handleRotaryInput(createRotaryMotionEvent(1000f));
-
- assertTrue(mRotaryInputGraphView.getFrameCenterPosition() > 0);
- }
-
- @Test
- public void updateActivityStatus_setsAndRemovesColorFilter() {
- // It should not be active initially.
- assertNull(mRotaryInputValueView.getBackground().getColorFilter());
-
- mRotaryInputValueView.updateActivityStatus(true);
- // It should be active after rotary input.
- assertNotNull(mRotaryInputValueView.getBackground().getColorFilter());
-
- mRotaryInputValueView.updateActivityStatus(false);
- // It should not be active after waiting for mUpdateActivityStatusCallback.
- assertNull(mRotaryInputValueView.getBackground().getColorFilter());
- }
-
- private MotionEvent createRotaryMotionEvent(float scrollAxisValue) {
- PointerCoords pointerCoords = new PointerCoords();
- pointerCoords.setAxisValue(MotionEvent.AXIS_SCROLL, scrollAxisValue);
- PointerProperties pointerProperties = new PointerProperties();
-
- return MotionEvent.obtain(
- /* downTime */ 0,
- /* eventTime */ 0,
- /* action */ MotionEvent.ACTION_SCROLL,
- /* pointerCount */ 1,
- /* pointerProperties */ new PointerProperties[] {pointerProperties},
- /* pointerCoords */ new PointerCoords[] {pointerCoords},
- /* metaState */ 0,
- /* buttonState */ 0,
- /* xPrecision */ 0,
- /* yPrecision */ 0,
- /* deviceId */ 0,
- /* edgeFlags */ 0,
- /* source */ InputDevice.SOURCE_ROTARY_ENCODER,
- /* flags */ 0
- );
- }
-}
diff --git a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
index b6477510..fa86e9c 100644
--- a/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyboardLayoutManagerTests.kt
@@ -32,11 +32,16 @@
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
import android.view.inputmethod.InputMethodSubtype
import androidx.test.core.R
import androidx.test.core.app.ApplicationProvider
+import com.android.dx.mockito.inline.extended.ExtendedMockito
+import com.android.internal.os.KeyboardConfiguredProto
+import com.android.internal.util.FrameworkStatsLog
+import com.android.modules.utils.testing.ExtendedMockitoRule
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
@@ -46,9 +51,9 @@
import org.junit.Before
import org.junit.Rule
import org.junit.Test
+import org.mockito.ArgumentMatchers
import org.mockito.Mock
import org.mockito.Mockito
-import org.mockito.junit.MockitoJUnit
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException
@@ -96,6 +101,9 @@
private const val ENGLISH_US_LAYOUT_NAME = "keyboard_layout_english_us"
private const val ENGLISH_UK_LAYOUT_NAME = "keyboard_layout_english_uk"
private const val VENDOR_SPECIFIC_LAYOUT_NAME = "keyboard_layout_vendorId:1,productId:1"
+ const val LAYOUT_TYPE_QWERTZ = 2
+ const val LAYOUT_TYPE_QWERTY = 1
+ const val LAYOUT_TYPE_DEFAULT = 0
}
private val ENGLISH_US_LAYOUT_DESCRIPTOR = createLayoutDescriptor(ENGLISH_US_LAYOUT_NAME)
@@ -103,8 +111,10 @@
private val VENDOR_SPECIFIC_LAYOUT_DESCRIPTOR =
createLayoutDescriptor(VENDOR_SPECIFIC_LAYOUT_NAME)
- @get:Rule
- val rule = MockitoJUnit.rule()!!
+ @JvmField
+ @Rule
+ val extendedMockitoRule = ExtendedMockitoRule.Builder(this)
+ .mockStatic(FrameworkStatsLog::class.java).build()!!
@Mock
private lateinit var iInputManager: IInputManager
@@ -145,7 +155,9 @@
override fun finishWrite(fos: FileOutputStream?, success: Boolean) {}
})
testLooper = TestLooper()
- keyboardLayoutManager = KeyboardLayoutManager(context, native, dataStore, testLooper.looper)
+ keyboardLayoutManager = Mockito.spy(
+ KeyboardLayoutManager(context, native, dataStore, testLooper.looper)
+ )
setupInputDevices()
setupBroadcastReceiver()
setupIme()
@@ -827,6 +839,100 @@
}
}
+ @Test
+ fun testConfigurationLogged_onInputDeviceAdded_VirtualKeyboardBasedSelection() {
+ val imeInfos = listOf(
+ 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",
+ KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_VIRTUAL_KEYBOARD,
+ "de-Latn",
+ LAYOUT_TYPE_QWERTZ))
+ )
+ }
+ }
+ }
+
+ @Test
+ fun testConfigurationLogged_onInputDeviceAdded_DeviceBasedSelection() {
+ val imeInfos = listOf(
+ 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)",
+ KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEVICE,
+ "de-Latn",
+ LAYOUT_TYPE_QWERTZ))
+ )
+ }
+ }
+ }
+
+ @Test
+ 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",
+ KeyboardMetricsCollector.LAYOUT_SELECTION_CRITERIA_DEFAULT,
+ KeyboardMetricsCollector.DEFAULT_LANGUAGE_TAG,
+ LAYOUT_TYPE_DEFAULT))
+ )
+ }
+ }
+ }
+
+ @Test
+ 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)
+ )
+ }, Mockito.times(0))
+ }
+ }
+
private fun assertCorrectLayout(
device: InputDevice,
imeSubtype: InputMethodSubtype,
@@ -842,18 +948,60 @@
}
private fun createImeSubtype(): InputMethodSubtype =
- InputMethodSubtype.InputMethodSubtypeBuilder().setSubtypeId(nextImeSubtypeId++).build()
+ createImeSubtypeForLanguageTagAndLayoutType(null, null)
private fun createImeSubtypeForLanguageTag(languageTag: String): InputMethodSubtype =
- InputMethodSubtype.InputMethodSubtypeBuilder().setSubtypeId(nextImeSubtypeId++)
- .setLanguageTag(languageTag).build()
+ createImeSubtypeForLanguageTagAndLayoutType(languageTag, null)
private fun createImeSubtypeForLanguageTagAndLayoutType(
- languageTag: String,
- layoutType: String
- ): InputMethodSubtype =
- InputMethodSubtype.InputMethodSubtypeBuilder().setSubtypeId(nextImeSubtypeId++)
- .setPhysicalKeyboardHint(ULocale.forLanguageTag(languageTag), layoutType).build()
+ languageTag: String?,
+ layoutType: String?
+ ): InputMethodSubtype {
+ val builder = InputMethodSubtype.InputMethodSubtypeBuilder()
+ .setSubtypeId(nextImeSubtypeId++)
+ .setIsAuxiliary(false)
+ .setSubtypeMode("keyboard")
+ if (languageTag != null && layoutType != null) {
+ builder.setPhysicalKeyboardHint(ULocale.forLanguageTag(languageTag), layoutType)
+ } else if (languageTag != null) {
+ builder.setLanguageTag(languageTag)
+ }
+ return builder.build()
+ }
+
+ private fun createByteArray(
+ expectedLanguageTag: String, expectedLayoutType: Int, expectedLayoutName: String,
+ expectedCriteria: Int, expectedImeLanguageTag: String, expectedImeLayoutType: Int): ByteArray {
+ val proto = ProtoOutputStream()
+ val keyboardLayoutConfigToken = proto.start(
+ KeyboardConfiguredProto.RepeatedKeyboardLayoutConfig.KEYBOARD_LAYOUT_CONFIG)
+ proto.write(
+ KeyboardConfiguredProto.KeyboardLayoutConfig.KEYBOARD_LANGUAGE_TAG,
+ expectedLanguageTag
+ )
+ proto.write(
+ KeyboardConfiguredProto.KeyboardLayoutConfig.KEYBOARD_LAYOUT_TYPE,
+ expectedLayoutType
+ )
+ proto.write(
+ KeyboardConfiguredProto.KeyboardLayoutConfig.KEYBOARD_LAYOUT_NAME,
+ expectedLayoutName
+ )
+ proto.write(
+ KeyboardConfiguredProto.KeyboardLayoutConfig.LAYOUT_SELECTION_CRITERIA,
+ expectedCriteria
+ )
+ proto.write(
+ KeyboardConfiguredProto.KeyboardLayoutConfig.IME_LANGUAGE_TAG,
+ expectedImeLanguageTag
+ )
+ proto.write(
+ KeyboardConfiguredProto.KeyboardLayoutConfig.IME_LAYOUT_TYPE,
+ expectedImeLayoutType
+ )
+ proto.end(keyboardLayoutConfigToken);
+ return proto.bytes
+ }
private fun hasLayout(layoutList: Array<KeyboardLayout>, layoutDesc: String): Boolean {
for (kl in layoutList) {
diff --git a/tests/Input/src/com/android/server/input/debug/FocusEventDebugViewTest.java b/tests/Input/src/com/android/server/input/debug/FocusEventDebugViewTest.java
new file mode 100644
index 0000000..ae7fb3b
--- /dev/null
+++ b/tests/Input/src/com/android/server/input/debug/FocusEventDebugViewTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2023 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.input.debug;
+
+import static org.mockito.Mockito.anyFloat;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.view.InputChannel;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+import android.view.MotionEvent.PointerCoords;
+import android.view.MotionEvent.PointerProperties;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.input.InputManagerService;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Build/Install/Run:
+ * atest FocusEventDebugViewTest
+ */
+@RunWith(AndroidJUnit4.class)
+public class FocusEventDebugViewTest {
+
+ private FocusEventDebugView mFocusEventDebugView;
+ private RotaryInputValueView mRotaryInputValueView;
+ private RotaryInputGraphView mRotaryInputGraphView;
+
+ @Before
+ public void setUp() throws Exception {
+ Context context = InstrumentationRegistry.getContext();
+ InputManagerService mockService = mock(InputManagerService.class);
+ when(mockService.monitorInput(anyString(), anyInt()))
+ .thenReturn(InputChannel.openInputChannelPair("FocusEventDebugViewTest")[1]);
+
+ mRotaryInputValueView = spy(new RotaryInputValueView(context));
+ mRotaryInputGraphView = spy(new RotaryInputGraphView(context));
+ mFocusEventDebugView = new FocusEventDebugView(context, mockService,
+ () -> mRotaryInputValueView, () -> mRotaryInputGraphView);
+ }
+
+ @Test
+ public void handleRotaryInput_sendsMotionEventWhenEnabled() {
+ mFocusEventDebugView.handleUpdateShowRotaryInput(true);
+
+ mFocusEventDebugView.handleRotaryInput(createRotaryMotionEvent(0.5f, 10L));
+
+ verify(mRotaryInputGraphView).addValue(0.5f, 10L);
+ verify(mRotaryInputValueView).updateValue(0.5f);
+ }
+
+ @Test
+ public void handleRotaryInput_doesNotSendMotionEventWhenDisabled() {
+ mFocusEventDebugView.handleUpdateShowRotaryInput(false);
+
+ mFocusEventDebugView.handleRotaryInput(createRotaryMotionEvent(0.5f, 10L));
+
+ verify(mRotaryInputGraphView, never()).addValue(anyFloat(), anyLong());
+ verify(mRotaryInputValueView, never()).updateValue(anyFloat());
+ }
+
+ private MotionEvent createRotaryMotionEvent(float scrollAxisValue, long eventTime) {
+ PointerCoords pointerCoords = new PointerCoords();
+ pointerCoords.setAxisValue(MotionEvent.AXIS_SCROLL, scrollAxisValue);
+ PointerProperties pointerProperties = new PointerProperties();
+
+ return MotionEvent.obtain(
+ /* downTime */ 0,
+ /* eventTime */ eventTime,
+ /* action */ MotionEvent.ACTION_SCROLL,
+ /* pointerCount */ 1,
+ /* pointerProperties */ new PointerProperties[] {pointerProperties},
+ /* pointerCoords */ new PointerCoords[] {pointerCoords},
+ /* metaState */ 0,
+ /* buttonState */ 0,
+ /* xPrecision */ 0,
+ /* yPrecision */ 0,
+ /* deviceId */ 0,
+ /* edgeFlags */ 0,
+ /* source */ InputDevice.SOURCE_ROTARY_ENCODER,
+ /* flags */ 0
+ );
+ }
+}
diff --git a/tests/Input/src/com/android/server/input/debug/RotaryInputGraphViewTest.java b/tests/Input/src/com/android/server/input/debug/RotaryInputGraphViewTest.java
new file mode 100644
index 0000000..af6ece4
--- /dev/null
+++ b/tests/Input/src/com/android/server/input/debug/RotaryInputGraphViewTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2023 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.input.debug;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Build/Install/Run:
+ * atest RotaryInputGraphViewTest
+ */
+@RunWith(AndroidJUnit4.class)
+public class RotaryInputGraphViewTest {
+
+ private RotaryInputGraphView mRotaryInputGraphView;
+
+ @Before
+ public void setUp() throws Exception {
+ Context context = InstrumentationRegistry.getContext();
+
+ mRotaryInputGraphView = new RotaryInputGraphView(context);
+ }
+
+ @Test
+ public void startsWithDefaultFrameCenter() {
+ assertEquals(0, mRotaryInputGraphView.getFrameCenterPosition(), 0.01);
+ }
+
+ @Test
+ public void addValue_translatesRotaryInputGraphViewWithHighScrollValue() {
+ final float scrollAxisValue = 1000f;
+ final long eventTime = 0;
+
+ mRotaryInputGraphView.addValue(scrollAxisValue, eventTime);
+
+ assertTrue(mRotaryInputGraphView.getFrameCenterPosition() > 0);
+ }
+}
diff --git a/tests/Input/src/com/android/server/input/debug/RotaryInputValueViewTest.java b/tests/Input/src/com/android/server/input/debug/RotaryInputValueViewTest.java
new file mode 100644
index 0000000..e5e3852
--- /dev/null
+++ b/tests/Input/src/com/android/server/input/debug/RotaryInputValueViewTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2023 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.input.debug;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import android.content.Context;
+import android.view.ViewConfiguration;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Locale;
+
+/**
+ * Build/Install/Run:
+ * atest RotaryInputValueViewTest
+ */
+@RunWith(AndroidJUnit4.class)
+public class RotaryInputValueViewTest {
+
+ private final Locale mDefaultLocale = Locale.getDefault();
+
+ private RotaryInputValueView mRotaryInputValueView;
+ private float mScaledVerticalScrollFactor;
+
+ @Before
+ public void setUp() throws Exception {
+ Context context = InstrumentationRegistry.getContext();
+ mScaledVerticalScrollFactor =
+ ViewConfiguration.get(context).getScaledVerticalScrollFactor();
+
+ mRotaryInputValueView = new RotaryInputValueView(context);
+ }
+
+ @Test
+ public void startsWithDefaultValue() {
+ assertEquals("+0.0", mRotaryInputValueView.getText().toString());
+ }
+
+ @Test
+ public void updateValue_updatesTextWithScrollValue() {
+ final float scrollAxisValue = 1000f;
+ final String expectedText = String.format(mDefaultLocale, "+%.1f",
+ scrollAxisValue * mScaledVerticalScrollFactor);
+
+ mRotaryInputValueView.updateValue(scrollAxisValue);
+
+ assertEquals(expectedText, mRotaryInputValueView.getText().toString());
+ }
+
+ @Test
+ public void updateActivityStatus_setsAndRemovesColorFilter() {
+ // It should not be active initially.
+ assertNull(mRotaryInputValueView.getBackground().getColorFilter());
+
+ mRotaryInputValueView.updateActivityStatus(true);
+ // It should be active after rotary input.
+ assertNotNull(mRotaryInputValueView.getBackground().getColorFilter());
+
+ mRotaryInputValueView.updateActivityStatus(false);
+ // It should not be active after waiting for mUpdateActivityStatusCallback.
+ assertNull(mRotaryInputValueView.getBackground().getColorFilter());
+ }
+}
diff --git a/tests/InputMethodStressTest/Android.bp b/tests/InputMethodStressTest/Android.bp
index 84845c6..58ceb3f 100644
--- a/tests/InputMethodStressTest/Android.bp
+++ b/tests/InputMethodStressTest/Android.bp
@@ -26,7 +26,7 @@
"compatibility-device-util-axt",
"platform-test-annotations",
"platform-test-rules",
- "truth-prebuilt",
+ "truth",
],
test_suites: [
"general-tests",
diff --git a/tests/InputScreenshotTest/Android.bp b/tests/InputScreenshotTest/Android.bp
index eee486f..15aaa46 100644
--- a/tests/InputScreenshotTest/Android.bp
+++ b/tests/InputScreenshotTest/Android.bp
@@ -29,7 +29,7 @@
"androidx.lifecycle_lifecycle-livedata-ktx",
"androidx.lifecycle_lifecycle-runtime-compose",
"androidx.navigation_navigation-compose",
- "truth-prebuilt",
+ "truth",
"androidx.compose.runtime_runtime",
"androidx.test.core",
"androidx.test.ext.junit",
@@ -47,7 +47,7 @@
"services.core.unboosted",
"testables",
"testng",
- "truth-prebuilt",
+ "truth",
],
libs: [
"android.test.mock",
diff --git a/tests/Internal/Android.bp b/tests/Internal/Android.bp
index ef45864..ddec8fa 100644
--- a/tests/Internal/Android.bp
+++ b/tests/Internal/Android.bp
@@ -19,7 +19,7 @@
"junit",
"androidx.test.rules",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
"platform-test-annotations",
],
java_resource_dirs: ["res"],
diff --git a/tests/LocalizationTest/Android.bp b/tests/LocalizationTest/Android.bp
index 4e0b0a8..909ca59 100644
--- a/tests/LocalizationTest/Android.bp
+++ b/tests/LocalizationTest/Android.bp
@@ -34,7 +34,7 @@
"androidx.test.ext.junit",
"androidx.test.rules",
"mockito-target-extended-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
jni_libs: [
// For mockito extended
diff --git a/tests/MidiTests/Android.bp b/tests/MidiTests/Android.bp
index 254770d..fcacab3 100644
--- a/tests/MidiTests/Android.bp
+++ b/tests/MidiTests/Android.bp
@@ -31,7 +31,7 @@
"mockito-target-inline-minus-junit4",
"platform-test-annotations",
"services.midi",
- "truth-prebuilt",
+ "truth",
],
jni_libs: ["libdexmakerjvmtiagent"],
certificate: "platform",
diff --git a/tests/PackageWatchdog/Android.bp b/tests/PackageWatchdog/Android.bp
index 1e1dc84..e0e6c4c 100644
--- a/tests/PackageWatchdog/Android.bp
+++ b/tests/PackageWatchdog/Android.bp
@@ -32,7 +32,7 @@
"androidx.test.rules",
"services.core",
"services.net",
- "truth-prebuilt",
+ "truth",
],
libs: ["android.test.runner"],
jni_libs: [
diff --git a/tests/PlatformCompatGating/Android.bp b/tests/PlatformCompatGating/Android.bp
index f0f9c4b..fd992cf 100644
--- a/tests/PlatformCompatGating/Android.bp
+++ b/tests/PlatformCompatGating/Android.bp
@@ -38,7 +38,7 @@
"androidx.test.ext.junit",
"mockito-target-minus-junit4",
"testng",
- "truth-prebuilt",
+ "truth",
"platform-compat-test-rules",
],
}
diff --git a/tests/PlatformCompatGating/test-rules/Android.bp b/tests/PlatformCompatGating/test-rules/Android.bp
index 5f91f9d0..f6a41c2 100644
--- a/tests/PlatformCompatGating/test-rules/Android.bp
+++ b/tests/PlatformCompatGating/test-rules/Android.bp
@@ -29,7 +29,7 @@
static_libs: [
"junit",
"androidx.test.core",
- "truth-prebuilt",
- "core-compat-test-rules"
+ "truth",
+ "core-compat-test-rules",
],
}
diff --git a/tests/SurfaceViewBufferTests/Android.bp b/tests/SurfaceViewBufferTests/Android.bp
index 38313f8..055d625 100644
--- a/tests/SurfaceViewBufferTests/Android.bp
+++ b/tests/SurfaceViewBufferTests/Android.bp
@@ -45,7 +45,7 @@
"kotlinx-coroutines-android",
"flickerlib",
"flickerlib-trace_processor_shell",
- "truth-prebuilt",
+ "truth",
"cts-wm-util",
"CtsSurfaceValidatorLib",
],
diff --git a/tests/TaskOrganizerTest/Android.bp b/tests/TaskOrganizerTest/Android.bp
index bf12f42..d2ade34 100644
--- a/tests/TaskOrganizerTest/Android.bp
+++ b/tests/TaskOrganizerTest/Android.bp
@@ -43,6 +43,6 @@
"kotlinx-coroutines-android",
"flickerlib",
"flickerlib-trace_processor_shell",
- "truth-prebuilt",
+ "truth",
],
}
diff --git a/tests/TelephonyCommonTests/Android.bp b/tests/TelephonyCommonTests/Android.bp
index 81ec265..b968e5d 100644
--- a/tests/TelephonyCommonTests/Android.bp
+++ b/tests/TelephonyCommonTests/Android.bp
@@ -32,11 +32,11 @@
static_libs: [
"mockito-target-extended",
"androidx.test.rules",
- "truth-prebuilt",
+ "truth",
"platform-test-annotations",
"androidx.core_core",
"androidx.fragment_fragment",
- "androidx.test.ext.junit"
+ "androidx.test.ext.junit",
],
jni_libs: ["libdexmakerjvmtiagent"],
diff --git a/tests/TrustTests/Android.bp b/tests/TrustTests/Android.bp
index c216bce..4e75a1d 100644
--- a/tests/TrustTests/Android.bp
+++ b/tests/TrustTests/Android.bp
@@ -28,7 +28,7 @@
"flag-junit",
"mockito-target-minus-junit4",
"servicestests-utils",
- "truth-prebuilt",
+ "truth",
],
libs: [
"android.test.runner",
diff --git a/tests/UpdatableSystemFontTest/Android.bp b/tests/UpdatableSystemFontTest/Android.bp
index 9bfcc18..ddb3649 100644
--- a/tests/UpdatableSystemFontTest/Android.bp
+++ b/tests/UpdatableSystemFontTest/Android.bp
@@ -30,7 +30,7 @@
"androidx.test.uiautomator_uiautomator",
"compatibility-device-util-axt",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
],
test_suites: [
"general-tests",
diff --git a/tests/UsbManagerTests/Android.bp b/tests/UsbManagerTests/Android.bp
index 97fbf5b..c02d8e9 100644
--- a/tests/UsbManagerTests/Android.bp
+++ b/tests/UsbManagerTests/Android.bp
@@ -31,7 +31,7 @@
"androidx.test.rules",
"mockito-target-inline-minus-junit4",
"platform-test-annotations",
- "truth-prebuilt",
+ "truth",
"UsbManagerTestLib",
],
jni_libs: ["libdexmakerjvmtiagent"],
diff --git a/tests/UsbManagerTests/lib/Android.bp b/tests/UsbManagerTests/lib/Android.bp
index 994484c..4e5a70fe 100644
--- a/tests/UsbManagerTests/lib/Android.bp
+++ b/tests/UsbManagerTests/lib/Android.bp
@@ -34,7 +34,7 @@
"services.core",
"services.net",
"services.usb",
- "truth-prebuilt",
+ "truth",
"androidx.core_core",
],
libs: [
diff --git a/tests/UsbTests/Android.bp b/tests/UsbTests/Android.bp
index c60c519..92c2711 100644
--- a/tests/UsbTests/Android.bp
+++ b/tests/UsbTests/Android.bp
@@ -34,7 +34,7 @@
"services.core",
"services.net",
"services.usb",
- "truth-prebuilt",
+ "truth",
"UsbManagerTestLib",
],
jni_libs: [
diff --git a/tests/componentalias/Android.bp b/tests/componentalias/Android.bp
index 01d34e4..39037f2 100644
--- a/tests/componentalias/Android.bp
+++ b/tests/componentalias/Android.bp
@@ -25,7 +25,7 @@
"androidx.test.rules",
"compatibility-device-util-axt",
"mockito-target-extended-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
libs: ["android.test.base"],
srcs: [
diff --git a/tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp b/tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp
index e7fb2de..b71e5c4 100644
--- a/tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp
+++ b/tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp
@@ -24,7 +24,7 @@
],
static_libs: [
"junit",
- "truth-prebuilt",
+ "truth",
"mockito",
// http://cs/h/googleplex-android/platform/superproject/main/+/main:platform_testing/libraries/annotations/src/android/platform/test/annotations/
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp b/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp
index 05d6a43..f9dc305 100644
--- a/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp
@@ -104,7 +104,7 @@
],
static_libs: [
"junit",
- "truth-prebuilt",
+ "truth",
// http://cs/h/googleplex-android/platform/superproject/main/+/main:platform_testing/libraries/annotations/src/android/platform/test/annotations/
"platform-test-annotations",
diff --git a/tools/processors/immutability/Android.bp b/tools/processors/immutability/Android.bp
index a7d69039..ecc283b 100644
--- a/tools/processors/immutability/Android.bp
+++ b/tools/processors/immutability/Android.bp
@@ -50,7 +50,7 @@
static_libs: [
"compile-testing-prebuilt",
- "truth-prebuilt",
+ "truth",
"junit",
"kotlin-reflect",
"ImmutabilityAnnotationProcessorHostLibrary",
diff --git a/tools/processors/intdef_mappings/Android.bp b/tools/processors/intdef_mappings/Android.bp
index 7059c52..9c755b7 100644
--- a/tools/processors/intdef_mappings/Android.bp
+++ b/tools/processors/intdef_mappings/Android.bp
@@ -38,7 +38,7 @@
static_libs: [
"compile-testing-prebuilt",
- "truth-prebuilt",
+ "truth",
"junit",
"guava",
"libintdef-annotation-processor",
diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp
index 7a29969..5a0f742 100644
--- a/wifi/tests/Android.bp
+++ b/wifi/tests/Android.bp
@@ -40,7 +40,7 @@
"frameworks-base-testutils",
"guava",
"mockito-target-minus-junit4",
- "truth-prebuilt",
+ "truth",
],
libs: [