summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/statsd/Android.bp3
-rw-r--r--api/current.txt5
-rw-r--r--api/lint-baseline.txt3
-rwxr-xr-xapi/system-current.txt4
-rw-r--r--api/test-current.txt4
-rw-r--r--core/java/android/app/AppOpsManager.java167
-rw-r--r--core/java/android/companion/IFindDeviceCallback.aidl4
-rw-r--r--core/java/android/content/pm/CrossProfileAppsInternal.java10
-rw-r--r--core/java/android/os/PowerManager.java60
-rw-r--r--core/java/android/view/ViewRootImpl.java5
-rw-r--r--core/java/android/widget/Magnifier.java3
-rw-r--r--core/jni/android_view_SurfaceControl.cpp1
-rw-r--r--core/proto/android/stats/devicepolicy/device_policy_enums.proto3
-rw-r--r--core/res/res/drawable/ic_work_apps_off.xml8
-rw-r--r--core/res/res/values/vendor_allowed_personal_apps_org_owned_device.xml23
-rw-r--r--media/java/android/media/MediaFormat.java32
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java10
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java7
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java112
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/Assert.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinatorTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapperTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListenerTest.java9
-rw-r--r--packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java2
-rw-r--r--services/core/java/com/android/server/pm/CrossProfileAppsService.java2
-rw-r--r--services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java61
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java114
-rw-r--r--services/core/java/com/android/server/power/batterysaver/BatterySaverController.java84
-rw-r--r--services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java41
-rw-r--r--services/tests/servicestests/src/com/android/server/power/NotifierTest.java14
-rw-r--r--services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java66
-rw-r--r--services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/StubTransaction.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java1
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRuleTest.java74
-rw-r--r--telephony/java/android/service/carrier/CarrierService.java8
66 files changed, 713 insertions, 360 deletions
diff --git a/apex/statsd/Android.bp b/apex/statsd/Android.bp
index c8aa526254b8..0e9311034ee0 100644
--- a/apex/statsd/Android.bp
+++ b/apex/statsd/Android.bp
@@ -27,6 +27,7 @@ apex_defaults {
"framework-statsd",
"service-statsd",
],
+ compile_multilib: "both",
// prebuilts: ["my_prebuilt"],
name: "com.android.os.statsd-defaults",
key: "com.android.os.statsd.key",
@@ -72,4 +73,4 @@ cc_library_shared {
"com.android.os.statsd",
"test_com.android.os.statsd",
],
-} \ No newline at end of file
+}
diff --git a/api/current.txt b/api/current.txt
index 62d9bf779750..140b6ae51a80 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4351,7 +4351,7 @@ package android.app {
public class AppOpsManager {
method @Deprecated public int checkOp(@NonNull String, int, @NonNull String);
method @Deprecated public int checkOpNoThrow(@NonNull String, int, @NonNull String);
- method public void checkPackage(int, @NonNull String);
+ method @Deprecated public void checkPackage(int, @NonNull String);
method @Deprecated public void finishOp(@NonNull String, int, @NonNull String);
method public void finishOp(@NonNull String, int, @NonNull String, @Nullable String);
method public boolean isOpActive(@NonNull String, int, @NonNull String);
@@ -4364,7 +4364,7 @@ package android.app {
method @Deprecated public int noteProxyOpNoThrow(@NonNull String, @NonNull String);
method @Deprecated public int noteProxyOpNoThrow(@NonNull String, @Nullable String, int);
method public int noteProxyOpNoThrow(@NonNull String, @Nullable String, int, @Nullable String, @Nullable String);
- method public static String permissionToOp(String);
+ method @Nullable public static String permissionToOp(@NonNull String);
method public void setNotedAppOpsCollector(@Nullable android.app.AppOpsManager.AppOpsCollector);
method @Deprecated public int startOp(@NonNull String, int, @NonNull String);
method public int startOp(@NonNull String, int, @Nullable String, @Nullable String, @Nullable String);
@@ -72093,6 +72093,7 @@ package java.time.chrono {
method public static java.time.chrono.JapaneseEra[] values();
field public static final java.time.chrono.JapaneseEra HEISEI;
field public static final java.time.chrono.JapaneseEra MEIJI;
+ field public static final java.time.chrono.JapaneseEra REIWA;
field public static final java.time.chrono.JapaneseEra SHOWA;
field public static final java.time.chrono.JapaneseEra TAISHO;
}
diff --git a/api/lint-baseline.txt b/api/lint-baseline.txt
index 2a8f04fe54b6..569e838ea177 100644
--- a/api/lint-baseline.txt
+++ b/api/lint-baseline.txt
@@ -561,6 +561,9 @@ MissingNullability: android.media.MediaMetadataRetriever#getFrameAtTime(long, in
MissingNullability: android.media.MediaMetadataRetriever#getScaledFrameAtTime(long, int, int, int, android.media.MediaMetadataRetriever.BitmapParams):
+
+MissingNullability: java.time.chrono.JapaneseEra#REIWA:
+ Missing nullability on field `REIWA` in class `class java.time.chrono.JapaneseEra`
RequiresPermission: android.accounts.AccountManager#getAccountsByTypeAndFeatures(String, String[], android.accounts.AccountManagerCallback<android.accounts.Account[]>, android.os.Handler):
diff --git a/api/system-current.txt b/api/system-current.txt
index a8c24534dc12..79a9b2196295 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -371,8 +371,8 @@ package android.app {
method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[]);
method public static int opToDefaultMode(@NonNull String);
method @Nullable public static String opToPermission(@NonNull String);
- method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(String, int, String, int);
- method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setUidMode(String, int, int);
+ method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(@NonNull String, int, @Nullable String, int);
+ method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setUidMode(@NonNull String, int, int);
field public static final String OPSTR_ACCEPT_HANDOVER = "android:accept_handover";
field public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
field public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
diff --git a/api/test-current.txt b/api/test-current.txt
index 79d29f6e906f..957794cac057 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -180,8 +180,8 @@ package android.app {
method @RequiresPermission("android.permission.MANAGE_APPOPS") public void resetHistoryParameters();
method @RequiresPermission("android.permission.MANAGE_APPOPS") public void setHistoryParameters(int, long, int);
method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(int, int, String, int);
- method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(String, int, String, int);
- method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setUidMode(String, int, int);
+ method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(@NonNull String, int, @Nullable String, int);
+ method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setUidMode(@NonNull String, int, int);
method public static int strOpToOp(@NonNull String);
field public static final int HISTORICAL_MODE_DISABLED = 0; // 0x0
field public static final int HISTORICAL_MODE_ENABLED_ACTIVE = 1; // 0x1
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index f6bbc6824e71..9ed479840750 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -97,15 +97,77 @@ import java.util.function.Consumer;
import java.util.function.Supplier;
/**
- * AppOps are mappings of [package/uid, op-name] -> [mode]. The list of existing appops is defined
- * by the system and cannot be amended by apps. Only system apps can change appop-modes.
+ * App-ops are used for two purposes: Access control and tracking.
*
- * <p>Beside a mode the system tracks when an op was {@link #noteOp noted}. The tracked data can
- * only be read by system components.
+ * <p>App-ops cover a wide variety of functionality from helping with runtime permissions access
+ * control and tracking to battery consumption tracking.
*
- * <p>Installed apps can usually only listen to changes and events on their own ops. E.g.
- * {@link AppOpsCollector} allows to get a callback each time an app called {@link #noteOp} or
- * {@link #startOp} for an op belonging to the app.
+ * <h2>Access control</h2>
+ *
+ * <p>App-ops can either be controlled for each uid or for each package. Which one is used depends
+ * on the API provider maintaining this app-op. For any security or privacy related app-op the
+ * provider needs to control the app-op for per uid as all security and privacy is based on uid in
+ * Android.
+ *
+ * <p>To control access the app-op can be set to a mode to:
+ * <dl>
+ * <dt>{@link #MODE_DEFAULT}
+ * <dd>Default behavior, might differ from app-op or app-op
+ * <dt>{@link #MODE_ALLOWED}
+ * <dd>Allow the access
+ * <dt>{@link #MODE_IGNORED}
+ * <dd>Don't allow the access, i.e. don't perform the requested action or return no or dummy
+ * data
+ * <dt>{@link #MODE_ERRORED}
+ * <dd>Throw a {@link SecurityException} on access. This can be suppressed by using a
+ * {@code ...noThrow} method to check the mode
+ * </dl>
+ *
+ * <p>API providers need to check the mode returned by {@link #noteOp} if they are are allowing
+ * access to operations gated by the app-op. {@link #unsafeCheckOp} should be used to check the
+ * mode if no access is granted. E.g. this can be used for displaying app-op state in the UI or
+ * when checking the state before later calling {@link #noteOp} anyway.
+ *
+ * <p>If an operation refers to a time span (e.g. a audio-recording session) the API provider
+ * should use {@link #startOp} and {@link #finishOp} instead of {@link #noteOp}.
+ *
+ * <h3>Runtime permissions and app-ops</h3>
+ *
+ * <p>Each platform defined runtime permission (beside background modifiers) has an associated app
+ * op which is used for tracking but also to allow for silent failures. I.e. if the runtime
+ * permission is denied the caller gets a {@link SecurityException}, but if the permission is
+ * granted and the app-op is {@link #MODE_IGNORED} then the callers gets dummy behavior, e.g.
+ * location callbacks would not happen.
+ *
+ * <h3>App-op permissions</h3>
+ *
+ * <p>App-ops permissions are platform defined permissions that can be overridden. The security
+ * check for app-op permissions should by {@link #MODE_DEFAULT default} check the permission grant
+ * state. If the app-op state is set to {@link #MODE_ALLOWED} or {@link #MODE_IGNORED} the app-op
+ * state should be checked instead of the permission grant state.
+ *
+ * <p>This functionality allows to grant access by default to apps fulfilling the requirements for
+ * a certain permission level. Still the behavior can be overridden when needed.
+ *
+ * <h2>Tracking</h2>
+ *
+ * <p>App-ops track many important events, including all accesses to runtime permission protected
+ * APIs. This is done by tracking when an app-op was {@link #noteOp noted} or
+ * {@link #startOp started}. The tracked data can only be read by system components.
+ *
+ * <p><b>Only {@link #noteOp}/{@link #startOp} are tracked; {@link #unsafeCheckOp} is not tracked.
+ * Hence it is important to eventually call {@link #noteOp} or {@link #startOp} when providing
+ * access to protected operations or data.</b>
+ *
+ * <p>Some apps are forwarding access to other apps. E.g. an app might get the location from the
+ * system's location provider and then send the location further to a 3rd app. In this case the
+ * app passing on the data needs to call {@link #noteProxyOp} to signal the access proxying. This
+ * might also make sense inside of a single app if the access is forwarded between two features of
+ * the app.
+ *
+ * <p>An app can register an {@link AppOpsCollector} to get informed about what accesses the
+ * system is tracking for it. As each runtime permission has an associated app-op this API is
+ * particularly useful for an app that want to find unexpected private data accesses.
*/
@SystemService(Context.APP_OPS_SERVICE)
public class AppOpsManager {
@@ -121,28 +183,6 @@ public class AppOpsManager {
@EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
public static final long CALL_BACK_ON_CHANGED_LISTENER_WITH_SWITCHED_OP_CHANGE = 148180766L;
- /**
- * <p>App ops allows callers to:</p>
- *
- * <ul>
- * <li> Note when operations are happening, and find out if they are allowed for the current
- * caller.</li>
- * <li> Disallow specific apps from doing specific operations.</li>
- * <li> Collect all of the current information about operations that have been executed or
- * are not being allowed.</li>
- * <li> Monitor for changes in whether an operation is allowed.</li>
- * </ul>
- *
- * <p>Each operation is identified by a single integer; these integers are a fixed set of
- * operations, enumerated by the OP_* constants.
- *
- * <p></p>When checking operations, the result is a "mode" integer indicating the current
- * setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute
- * the operation but fake its behavior enough so that the caller doesn't crash),
- * MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls
- * will do this for you).
- */
-
final Context mContext;
@UnsupportedAppUsage
@@ -1093,7 +1133,7 @@ public class AppOpsManager {
/** Required to draw on top of other apps. */
public static final String OPSTR_SYSTEM_ALERT_WINDOW
= "android:system_alert_window";
- /** Required to write/modify/update system settingss. */
+ /** Required to write/modify/update system settings. */
public static final String OPSTR_WRITE_SETTINGS
= "android:write_settings";
/** @hide Get device accounts. */
@@ -6115,7 +6155,7 @@ public class AppOpsManager {
*/
public interface OnOpActiveChangedListener {
/**
- * Called when the active state of an app op changes.
+ * Called when the active state of an app-op changes.
*
* @param op The operation that changed.
* @param packageName The package performing the operation.
@@ -6406,7 +6446,7 @@ public class AppOpsManager {
@SystemApi
@TestApi
@RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
- public void setUidMode(String appOp, int uid, @Mode int mode) {
+ public void setUidMode(@NonNull String appOp, int uid, @Mode int mode) {
try {
mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode);
} catch (RemoteException e) {
@@ -6461,7 +6501,8 @@ public class AppOpsManager {
@TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
- public void setMode(String op, int uid, String packageName, @Mode int mode) {
+ public void setMode(@NonNull String op, int uid, @Nullable String packageName,
+ @Mode int mode) {
try {
mService.setMode(strOpToOp(op), uid, packageName, mode);
} catch (RemoteException e) {
@@ -6504,16 +6545,17 @@ public class AppOpsManager {
}
/**
- * Gets the app op name associated with a given permission.
- * The app op name is one of the public constants defined
+ * Gets the app-op name associated with a given permission.
+ *
+ * <p>The app-op name is one of the public constants defined
* in this class such as {@link #OPSTR_COARSE_LOCATION}.
* This API is intended to be used for mapping runtime
- * permissions to the corresponding app op.
+ * permissions to the corresponding app-op.
*
* @param permission The permission.
- * @return The app op associated with the permission or null.
+ * @return The app-op associated with the permission or {@code null}.
*/
- public static String permissionToOp(String permission) {
+ public static @Nullable String permissionToOp(@NonNull String permission) {
final Integer opCode = sPermToOp.get(permission);
if (opCode == null) {
return null;
@@ -6631,7 +6673,7 @@ public class AppOpsManager {
}
/**
- * Start watching for changes to the active state of app ops. An app op may be
+ * Start watching for changes to the active state of app-ops. An app-op may be
* long running and it has a clear start and stop delimiters. If an op is being
* started or stopped by any package you will get a callback. To change the
* watched ops for a registered callback you need to unregister and register it
@@ -6690,7 +6732,7 @@ public class AppOpsManager {
}
/**
- * Stop watching for changes to the active state of an app op. An app op may be
+ * Stop watching for changes to the active state of an app-op. An app-op may be
* long running and it has a clear start and stop delimiters. Unregistering a
* non-registered callback has no effect.
*
@@ -6921,7 +6963,8 @@ public class AppOpsManager {
* @param op The operation to note. One of the OPSTR_* constants.
* @param uid The user id of the application attempting to perform the operation.
* @param packageName The name of the application attempting to perform the operation.
- * @param featureId The feature in the app or {@code null} for default feature
+ * @param featureId The {@link Context#createFeatureContext feature} in the package or {@code
+ * null} for default feature
* @param message A message describing the reason the op was noted
*
* @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
@@ -6996,6 +7039,8 @@ public class AppOpsManager {
* @param op The operation to note. One of the OPSTR_* constants.
* @param uid The user id of the application attempting to perform the operation.
* @param packageName The name of the application attempting to perform the operation.
+ * @param featureId The {@link Context#createFeatureContext feature} in the package or {@code
+ * null} for default feature
* @param message A message describing the reason the op was noted
*
* @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
@@ -7003,8 +7048,8 @@ public class AppOpsManager {
* causing the app to crash).
*/
public int noteOpNoThrow(@NonNull String op, int uid, @NonNull String packageName,
- @Nullable String feature, @Nullable String message) {
- return noteOpNoThrow(strOpToOp(op), uid, packageName, feature, message);
+ @Nullable String featureId, @Nullable String message) {
+ return noteOpNoThrow(strOpToOp(op), uid, packageName, featureId, message);
}
/**
@@ -7273,11 +7318,9 @@ public class AppOpsManager {
}
/**
- * Do a quick check to validate if a package name belongs to a UID.
- *
- * @throws SecurityException if the package name doesn't belong to the given
- * UID, or if ownership cannot be verified.
+ * @deprecated Use {@link PackageManager#getPackageUid} instead
*/
+ @Deprecated
public void checkPackage(int uid, @NonNull String packageName) {
try {
if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
@@ -7396,7 +7439,8 @@ public class AppOpsManager {
* @param op The operation to start. One of the OPSTR_* constants.
* @param uid The user id of the application attempting to perform the operation.
* @param packageName The name of the application attempting to perform the operation.
- * @param featureId The feature in the app or {@code null} for default feature
+ * @param featureId The {@link Context#createFeatureContext feature} in the package or {@code
+ * null} for default feature
* @param message Description why op was started
*
* @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
@@ -7587,7 +7631,8 @@ public class AppOpsManager {
}
/**
- * Checks whether the given op for a package is active.
+ * Checks whether the given op for a package is active, i.e. did someone call {@link #startOp}
+ * without {@link #finishOp} yet.
* <p>
* If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS}
* permission you can query only for your UID.
@@ -7917,18 +7962,19 @@ public class AppOpsManager {
}
/**
- * Callback an app can choose to {@link #setNotedAppOpsCollector register} to monitor it's noted
- * appops. I.e. each time any app calls {@link #noteOp} or {@link #startOp} one of the callback
- * methods of this object is called.
+ * Callback an app can {@link #setNotedAppOpsCollector register} to monitor the app-ops the
+ * system has tracked for it. I.e. each time any app calls {@link #noteOp} or {@link #startOp}
+ * one of the callback methods of this object is called.
*
- * <p><b>Only appops related to dangerous permissions are collected.</b>
+ * <p><b>There will be a callback for all app-ops related to runtime permissions, but not
+ * necessarily for all other app-ops.
*
* <pre>
* setNotedAppOpsCollector(new AppOpsCollector() {
* ArraySet<Pair<String, String>> opsNotedForThisProcess = new ArraySet<>();
*
* private synchronized void addAccess(String op, String accessLocation) {
- * // Ops are often noted when permission protected APIs were called.
+ * // Ops are often noted when runtime permission protected APIs were called.
* // In this case permissionToOp() allows to resolve the permission<->op
* opsNotedForThisProcess.add(new Pair(accessType, accessLocation));
* }
@@ -7970,20 +8016,21 @@ public class AppOpsManager {
}
/**
- * Called when an app-op was noted for this package inside of a two-way binder-call.
+ * Called when an app-op was {@link #noteOp noted} for this package inside of a synchronous
+ * API call, i.e. a API call that returned data or waited until the action was performed.
*
- * <p>Called on the calling thread just after executing the binder-call. This allows
- * the app to e.g. collect stack traces to figure out where the access came from.
+ * <p>Called on the calling thread before the API returns. This allows the app to e.g.
+ * collect stack traces to figure out where the access came from.
*
* @param op The op noted
*/
public abstract void onNoted(@NonNull SyncNotedAppOp op);
/**
- * Called when this app noted an app-op for its own package.
+ * Called when this app noted an app-op for its own package,
*
- * <p>Called on the thread the noted the op. This allows the app to e.g. collect stack
- * traces to figure out where the access came from.
+ * <p>This is very similar to {@link #onNoted} only that the tracking was not caused by the
+ * API provider in a separate process, but by one in the app's own process.
*
* @param op The op noted
*/
diff --git a/core/java/android/companion/IFindDeviceCallback.aidl b/core/java/android/companion/IFindDeviceCallback.aidl
index 4e9fa19e5ce5..405277b50f5b 100644
--- a/core/java/android/companion/IFindDeviceCallback.aidl
+++ b/core/java/android/companion/IFindDeviceCallback.aidl
@@ -21,6 +21,6 @@ import android.app.PendingIntent;
/** @hide */
interface IFindDeviceCallback {
@UnsupportedAppUsage
- void onSuccess(in PendingIntent launcher);
- void onFailure(in CharSequence reason);
+ oneway void onSuccess(in PendingIntent launcher);
+ oneway void onFailure(in CharSequence reason);
}
diff --git a/core/java/android/content/pm/CrossProfileAppsInternal.java b/core/java/android/content/pm/CrossProfileAppsInternal.java
index 9ff441741bed..16a749fa360a 100644
--- a/core/java/android/content/pm/CrossProfileAppsInternal.java
+++ b/core/java/android/content/pm/CrossProfileAppsInternal.java
@@ -17,6 +17,9 @@
package android.content.pm;
import android.annotation.UserIdInt;
+import android.os.UserHandle;
+
+import java.util.List;
/**
* Exposes internal methods from {@link com.android.server.pm.CrossProfileAppsServiceImpl} to other
@@ -52,4 +55,11 @@ public abstract class CrossProfileAppsInternal {
*/
public abstract boolean verifyUidHasInteractAcrossProfilePermission(String packageName,
int uid);
+
+ /**
+ * Returns the list of target user profiles for the given package on the given user. See {@link
+ * CrossProfileApps#getTargetUserProfiles()}.
+ */
+ public abstract List<UserHandle> getTargetUserProfiles(
+ String packageName, @UserIdInt int userId);
}
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 267613f0af83..a8fa6db232a2 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -26,6 +26,7 @@ import android.annotation.SdkConstant;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.app.PropertyInvalidatedCache;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.service.dreams.Sandman;
@@ -877,6 +878,39 @@ public final class PowerManager {
}
}
+ private static final String CACHE_KEY_IS_POWER_SAVE_MODE_PROPERTY =
+ "cache_key.is_power_save_mode";
+
+ private static final String CACHE_KEY_IS_INTERACTIVE_PROPERTY = "cache_key.is_interactive";
+
+ private static final int MAX_CACHE_ENTRIES = 1;
+
+ private PropertyInvalidatedCache<Void, Boolean> mPowerSaveModeCache =
+ new PropertyInvalidatedCache<Void, Boolean>(MAX_CACHE_ENTRIES,
+ CACHE_KEY_IS_POWER_SAVE_MODE_PROPERTY) {
+ @Override
+ protected Boolean recompute(Void query) {
+ try {
+ return mService.isPowerSaveMode();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ };
+
+ private PropertyInvalidatedCache<Void, Boolean> mInteractiveCache =
+ new PropertyInvalidatedCache<Void, Boolean>(MAX_CACHE_ENTRIES,
+ CACHE_KEY_IS_INTERACTIVE_PROPERTY) {
+ @Override
+ protected Boolean recompute(Void query) {
+ try {
+ return mService.isInteractive();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ };
+
final Context mContext;
@UnsupportedAppUsage
final IPowerManager mService;
@@ -1440,11 +1474,7 @@ public final class PowerManager {
* @see android.content.Intent#ACTION_SCREEN_OFF
*/
public boolean isInteractive() {
- try {
- return mService.isInteractive();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return mInteractiveCache.query(null);
}
/**
@@ -1504,11 +1534,7 @@ public final class PowerManager {
* @return Returns true if currently in low power mode, else false.
*/
public boolean isPowerSaveMode() {
- try {
- return mService.isPowerSaveMode();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return mPowerSaveModeCache.query(null);
}
/**
@@ -2508,4 +2534,18 @@ public final class PowerManager {
};
}
}
+
+ /**
+ * @hide
+ */
+ public static void invalidatePowerSaveModeCaches() {
+ PropertyInvalidatedCache.invalidateCache(CACHE_KEY_IS_POWER_SAVE_MODE_PROPERTY);
+ }
+
+ /**
+ * @hide
+ */
+ public static void invalidateIsInteractiveCaches() {
+ PropertyInvalidatedCache.invalidateCache(CACHE_KEY_IS_INTERACTIVE_PROPERTY);
+ }
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 44ab596b93ee..330e6c137f8b 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -9566,7 +9566,10 @@ public final class ViewRootImpl implements ViewParent,
return mRtBLASTSyncTransaction;
}
- SurfaceControl getRenderSurfaceControl() {
+ /**
+ * @hide
+ */
+ public SurfaceControl getRenderSurfaceControl() {
if (mUseBLASTAdapter) {
return mBlastSurfaceControl;
} else {
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index a6a5ec55b972..47ea1cbade93 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -1257,7 +1257,8 @@ public final class Magnifier {
return;
}
// Show or move the window at the content draw frame.
- mTransaction.deferTransactionUntilSurface(mSurfaceControl, mSurface, frame);
+ mTransaction.deferTransactionUntil(mSurfaceControl, mSurfaceControl,
+ frame);
if (updateWindowPosition) {
mTransaction.setPosition(mSurfaceControl, pendingX, pendingY);
}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index ce9a048f8006..3f81b112d9f1 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -236,7 +236,6 @@ static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
static void nativeRelease(JNIEnv* env, jclass clazz, jlong nativeObject) {
sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject));
- ctrl->release();
ctrl->decStrong((void *)nativeCreate);
}
diff --git a/core/proto/android/stats/devicepolicy/device_policy_enums.proto b/core/proto/android/stats/devicepolicy/device_policy_enums.proto
index a4e2193115a2..782b2694c453 100644
--- a/core/proto/android/stats/devicepolicy/device_policy_enums.proto
+++ b/core/proto/android/stats/devicepolicy/device_policy_enums.proto
@@ -176,4 +176,7 @@ enum EventId {
IS_MANAGED_PROFILE = 149;
START_ACTIVITY_BY_INTENT = 150;
BIND_CROSS_PROFILE_SERVICE = 151;
+ PROVISIONING_DPC_SETUP_STARTED = 152;
+ PROVISIONING_DPC_SETUP_COMPLETED = 153;
+ PROVISIONING_ORGANIZATION_OWNED_MANAGED_PROFILE = 154;
}
diff --git a/core/res/res/drawable/ic_work_apps_off.xml b/core/res/res/drawable/ic_work_apps_off.xml
index e91806f199df..f62eb2769bef 100644
--- a/core/res/res/drawable/ic_work_apps_off.xml
+++ b/core/res/res/drawable/ic_work_apps_off.xml
@@ -1,4 +1,4 @@
-<vector android:height="32dp" android:viewportHeight="24"
- android:viewportWidth="24" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
- <path android:fillColor="@color/resolver_empty_state_icon" android:pathData="M22,7.95c0.05,-1.11 -0.84,-2 -1.95,-1.95L16,6L16,3.95c0,-1.11 -0.84,-2 -1.95,-1.95h-4C8.94,1.95 8,2.84 8,3.95v0.32l14,14L22,7.95zM14,6h-4L10,4h4v2zM21.54,20.28l-7.56,-7.56v0.01l-1.7,-1.7h0.01L7.21,5.95 3.25,1.99 1.99,3.27 4.69,6h-0.64c-1.11,0 -1.99,0.86 -1.99,1.97l-0.01,11.02c0,1.11 0.89,2.01 2,2.01h15.64l2.05,2.02L23,21.75l-1.46,-1.47z"/>
-</vector>
+<vector android:height="32dp" android:viewportHeight="24.0"
+ android:viewportWidth="24.0" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@color/resolver_empty_state_icon" android:pathData="M20,6h-4L16,4c0,-1.11 -0.89,-2 -2,-2h-4c-1.11,0 -2,0.89 -2,2v1.17L10.83,8L20,8v9.17l1.98,1.98c0,-0.05 0.02,-0.1 0.02,-0.16L22,8c0,-1.11 -0.89,-2 -2,-2zM14,6h-4L10,4h4v2zM19,19L8,8 6,6 2.81,2.81 1.39,4.22 3.3,6.13C2.54,6.41 2.01,7.14 2.01,8L2,19c0,1.11 0.89,2 2,2h14.17l1.61,1.61 1.41,-1.41 -0.37,-0.37L19,19zM4,19L4,8h1.17l11,11L4,19z"/>
+</vector> \ No newline at end of file
diff --git a/core/res/res/values/vendor_allowed_personal_apps_org_owned_device.xml b/core/res/res/values/vendor_allowed_personal_apps_org_owned_device.xml
new file mode 100644
index 000000000000..0435c301a2da
--- /dev/null
+++ b/core/res/res/values/vendor_allowed_personal_apps_org_owned_device.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources>
+ <!-- A list of apps to be allowed in the personal profile of an organization-owned device. -->
+ <string-array translatable="false" name="vendor_allowed_personal_apps_org_owned_device">
+ </string-array>
+</resources>
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index b57182e03675..5832fc172498 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -656,16 +656,20 @@ public final class MediaFormat {
public static final String KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT = "aac-max-output-channel_count";
/**
- * A key describing a gain to be applied so that the output loudness matches the
- * Target Reference Level. This is typically used to normalize loudness across program items.
- * The gain is derived as the difference between the Target Reference Level and the
- * Program Reference Level. The latter can be given in the bitstream and indicates the actual
- * loudness value of the program item.
+ * A key describing the Target Reference Level (Target Loudness).
+ * <p>For normalizing loudness across program items, a gain is applied to the audio output so
+ * that the output loudness matches the Target Reference Level. The gain is derived as the
+ * difference between the Target Reference Level and the Program Reference Level (Program
+ * Loudness). The latter can be given in the bitstream and indicates the actual loudness value
+ * of the program item.</p>
* <p>The Target Reference Level controls loudness normalization for both MPEG-4 DRC and
* MPEG-D DRC.
* <p>The value is given as an integer value between
* 40 and 127, and is calculated as -4 * Target Reference Level in LKFS.
* Therefore, it represents the range of -10 to -31.75 LKFS.
+ * <p>For MPEG-4 DRC, a value of -1 switches off loudness normalization and DRC processing.</p>
+ * <p>For MPEG-D DRC, a value of -1 switches off loudness normalization only. For DRC processing
+ * options of MPEG-D DRC, see {@link #KEY_AAC_DRC_EFFECT_TYPE}</p>
* <p>The default value on mobile devices is 64 (-16 LKFS).
* <p>This key is only used during decoding.
*/
@@ -686,7 +690,7 @@ public final class MediaFormat {
* <tr><th>6</th><th>General compression</th></tr>
* </table>
* <p>The value -1 (Off) disables DRC processing, while loudness normalization may still be
- * active and dependent on KEY_AAC_DRC_TARGET_REFERENCE_LEVEL.<br>
+ * active and dependent on {@link #KEY_AAC_DRC_TARGET_REFERENCE_LEVEL}.<br>
* The value 0 (None) automatically enables DRC processing if necessary to prevent signal
* clipping<br>
* The value 6 (General compression) can be used for enabling MPEG-D DRC without particular
@@ -703,8 +707,8 @@ public final class MediaFormat {
* 0 and 127, which is calculated as -4 * Encoded Target Level in LKFS.
* If the Encoded Target Level is unknown, the value can be set to -1.
* <p>The default value is -1 (unknown).
- * <p>The value is ignored when heavy compression is used (see
- * {@link #KEY_AAC_DRC_HEAVY_COMPRESSION}).
+ * <p>The value is ignored when heavy compression (see {@link #KEY_AAC_DRC_HEAVY_COMPRESSION})
+ * or MPEG-D DRC is used.
* <p>This key is only used during decoding.
*/
public static final String KEY_AAC_ENCODED_TARGET_LEVEL = "aac-encoded-target-level";
@@ -745,17 +749,17 @@ public final class MediaFormat {
public static final String KEY_AAC_DRC_ATTENUATION_FACTOR = "aac-drc-cut-level";
/**
- * A key describing the selection of the heavy compression profile for DRC.
- * Two separate DRC gain sequences can be transmitted in one bitstream: MPEG-4 DRC light
- * compression, and DVB-specific heavy compression. When selecting the application of the heavy
- * compression, one of the sequences is selected:
+ * A key describing the selection of the heavy compression profile for MPEG-4 DRC.
+ * <p>Two separate DRC gain sequences can be transmitted in one bitstream: light compression
+ * and heavy compression. When selecting the application of the heavy compression, one of
+ * the sequences is selected:
* <ul>
* <li>0 enables light compression,</li>
* <li>1 enables heavy compression instead.
* </ul>
- * Note that only light compression offers the features of scaling of DRC gains
+ * Note that heavy compression doesn't offer the features of scaling of DRC gains
* (see {@link #KEY_AAC_DRC_BOOST_FACTOR} and {@link #KEY_AAC_DRC_ATTENUATION_FACTOR} for the
- * boost and attenuation factors, and frequency-selective (multiband) DRC.
+ * boost and attenuation factors), and frequency-selective (multiband) DRC.
* Light compression usually contains clipping prevention for stereo downmixing while heavy
* compression, if additionally provided in the bitstream, is usually stronger, and contains
* clipping prevention for stereo and mono downmixing.
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
index e80b43739557..7dcf4b0c11ae 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
@@ -24,6 +24,7 @@ import android.os.Handler.Callback;
import android.os.Message;
import android.os.Trace;
import android.view.Surface;
+import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewRootImpl;
@@ -39,7 +40,7 @@ public class SyncRtSurfaceTransactionApplierCompat {
private static final int MSG_UPDATE_SEQUENCE_NUMBER = 0;
- private final Surface mTargetSurface;
+ private final SurfaceControl mBarrierSurfaceControl;
private final ViewRootImpl mTargetViewRootImpl;
private final Handler mApplyHandler;
@@ -52,7 +53,8 @@ public class SyncRtSurfaceTransactionApplierCompat {
*/
public SyncRtSurfaceTransactionApplierCompat(View targetView) {
mTargetViewRootImpl = targetView != null ? targetView.getViewRootImpl() : null;
- mTargetSurface = mTargetViewRootImpl != null ? mTargetViewRootImpl.mSurface : null;
+ mBarrierSurfaceControl = mTargetViewRootImpl != null
+ ? mTargetViewRootImpl.getRenderSurfaceControl() : null;
mApplyHandler = new Handler(new Callback() {
@Override
@@ -91,7 +93,7 @@ public class SyncRtSurfaceTransactionApplierCompat {
mTargetViewRootImpl.registerRtFrameCallback(new HardwareRenderer.FrameDrawingCallback() {
@Override
public void onFrameDraw(long frame) {
- if (mTargetSurface == null || !mTargetSurface.isValid()) {
+ if (mBarrierSurfaceControl == null || !mBarrierSurfaceControl.isValid()) {
Message.obtain(mApplyHandler, MSG_UPDATE_SEQUENCE_NUMBER, toApplySeqNo, 0)
.sendToTarget();
return;
@@ -102,7 +104,7 @@ public class SyncRtSurfaceTransactionApplierCompat {
SyncRtSurfaceTransactionApplierCompat.SurfaceParams surfaceParams =
params[i];
SurfaceControlCompat surface = surfaceParams.surface;
- t.deferTransactionUntil(surface, mTargetSurface, frame);
+ t.deferTransactionUntil(surface, mBarrierSurfaceControl, frame);
applyParams(t, surfaceParams);
}
t.setEarlyWakeup();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
index 073688b0bf8c..8f4926fe14a3 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TransactionCompat.java
@@ -20,6 +20,7 @@ import android.graphics.Matrix;
import android.graphics.Rect;
import android.view.Surface;
import android.view.SurfaceControl.Transaction;
+import android.view.SurfaceControl;
public class TransactionCompat {
@@ -87,8 +88,8 @@ public class TransactionCompat {
}
public TransactionCompat deferTransactionUntil(SurfaceControlCompat surfaceControl,
- Surface barrier, long frameNumber) {
- mTransaction.deferTransactionUntilSurface(surfaceControl.mSurfaceControl, barrier,
+ SurfaceControl barrier, long frameNumber) {
+ mTransaction.deferTransactionUntil(surfaceControl.mSurfaceControl, barrier,
frameNumber);
return this;
}
@@ -102,4 +103,4 @@ public class TransactionCompat {
mTransaction.setColor(surfaceControl.mSurfaceControl, color);
return this;
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index e5f6d3c90eb7..9ba3860f4fb8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -95,6 +95,7 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.util.Assert;
import com.google.android.collect.Lists;
@@ -341,7 +342,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@Override
public void onTrustChanged(boolean enabled, int userId, int flags) {
- checkIsHandlerThread();
+ Assert.isMainThread();
mUserHasTrust.put(userId, enabled);
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -360,7 +361,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void handleSimSubscriptionInfoChanged() {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (DEBUG_SIM_STATES) {
Log.v(TAG, "onSubscriptionInfoChanged()");
List<SubscriptionInfo> sil = mSubscriptionManager
@@ -403,7 +404,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void callbacksRefreshCarrierInfo() {
- checkIsHandlerThread();
+ Assert.isMainThread();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -466,7 +467,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@Override
public void onTrustManagedChanged(boolean managed, int userId) {
- checkIsHandlerThread();
+ Assert.isMainThread();
mUserTrustIsManaged.put(userId, managed);
mUserTrustIsUsuallyManaged.put(userId, mTrustManager.isTrustUsuallyManaged(userId));
for (int i = 0; i < mCallbacks.size(); i++) {
@@ -523,7 +524,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@VisibleForTesting
protected void onFingerprintAuthenticated(int userId) {
- checkIsHandlerThread();
+ Assert.isMainThread();
Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
mUserFingerprintAuthenticated.put(userId, true);
// Update/refresh trust state only if user can skip bouncer
@@ -549,7 +550,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void handleFingerprintAuthFailed() {
- checkIsHandlerThread();
+ Assert.isMainThread();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -561,7 +562,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void handleFingerprintAcquired(int acquireInfo) {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
return;
}
@@ -599,7 +600,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void handleFingerprintHelp(int msgId, String helpString) {
- checkIsHandlerThread();
+ Assert.isMainThread();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -618,7 +619,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
};
private void handleFingerprintError(int msgId, String errString) {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED && mHandler.hasCallbacks(
mCancelNotReceived)) {
mHandler.removeCallbacks(mCancelNotReceived);
@@ -671,7 +672,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void notifyFingerprintRunningStateChanged() {
- checkIsHandlerThread();
+ Assert.isMainThread();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -684,7 +685,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@VisibleForTesting
protected void onFaceAuthenticated(int userId) {
Trace.beginSection("KeyGuardUpdateMonitor#onFaceAuthenticated");
- checkIsHandlerThread();
+ Assert.isMainThread();
mUserFaceAuthenticated.put(userId, true);
// Update/refresh trust state only if user can skip bouncer
if (getUserCanSkipBouncer(userId)) {
@@ -710,7 +711,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void handleFaceAuthFailed() {
- checkIsHandlerThread();
+ Assert.isMainThread();
setFaceRunningState(BIOMETRIC_STATE_STOPPED);
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -723,7 +724,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void handleFaceAcquired(int acquireInfo) {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (acquireInfo != FaceManager.FACE_ACQUIRED_GOOD) {
return;
}
@@ -767,7 +768,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void handleFaceHelp(int msgId, String helpString) {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (DEBUG_FACE) Log.d(TAG, "Face help received: " + helpString);
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -787,7 +788,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
};
private void handleFaceError(int msgId, String errString) {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (DEBUG_FACE) Log.d(TAG, "Face error received: " + errString);
if (msgId == FaceManager.FACE_ERROR_CANCELED && mHandler.hasCallbacks(mCancelNotReceived)) {
mHandler.removeCallbacks(mCancelNotReceived);
@@ -842,7 +843,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void notifyFaceRunningStateChanged() {
- checkIsHandlerThread();
+ Assert.isMainThread();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -853,7 +854,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void handleFaceUnlockStateChanged(boolean running, int userId) {
- checkIsHandlerThread();
+ Assert.isMainThread();
mUserFaceUnlockRunning.put(userId, running);
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -965,7 +966,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* Cached version of {@link TrustManager#isTrustUsuallyManaged(int)}.
*/
public boolean isTrustUsuallyManaged(int userId) {
- checkIsHandlerThread();
+ Assert.isMainThread();
return mUserTrustIsUsuallyManaged.get(userId);
}
@@ -996,7 +997,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void notifyStrongAuthStateChanged(int userId) {
- checkIsHandlerThread();
+ Assert.isMainThread();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -1010,7 +1011,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void dispatchErrorMessage(CharSequence message) {
- checkIsHandlerThread();
+ Assert.isMainThread();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -1323,7 +1324,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
protected void handleStartedWakingUp() {
Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
- checkIsHandlerThread();
+ Assert.isMainThread();
updateBiometricListeningState();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -1335,7 +1336,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
protected void handleStartedGoingToSleep(int arg1) {
- checkIsHandlerThread();
+ Assert.isMainThread();
mLockIconPressed = false;
clearBiometricRecognized();
for (int i = 0; i < mCallbacks.size(); i++) {
@@ -1349,7 +1350,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
protected void handleFinishedGoingToSleep(int arg1) {
- checkIsHandlerThread();
+ Assert.isMainThread();
mGoingToSleep = false;
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -1361,7 +1362,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void handleScreenTurnedOn() {
- checkIsHandlerThread();
+ Assert.isMainThread();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -1373,7 +1374,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private void handleScreenTurnedOff() {
final String tag = "KeyguardUpdateMonitor#handleScreenTurnedOff";
DejankUtils.startDetectingBlockingIpcs(tag);
- checkIsHandlerThread();
+ Assert.isMainThread();
mHardwareFingerprintUnavailableRetryCount = 0;
mHardwareFaceUnavailableRetryCount = 0;
for (int i = 0; i < mCallbacks.size(); i++) {
@@ -1386,7 +1387,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void handleDreamingStateChanged(int dreamStart) {
- checkIsHandlerThread();
+ Assert.isMainThread();
mIsDreaming = dreamStart == 1;
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -1398,7 +1399,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void handleUserInfoChanged(int userId) {
- checkIsHandlerThread();
+ Assert.isMainThread();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -1408,7 +1409,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void handleUserUnlocked(int userId) {
- checkIsHandlerThread();
+ Assert.isMainThread();
mUserIsUnlocked.put(userId, true);
mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
for (int i = 0; i < mCallbacks.size(); i++) {
@@ -1420,20 +1421,22 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void handleUserStopped(int userId) {
- checkIsHandlerThread();
+ Assert.isMainThread();
mUserIsUnlocked.put(userId, mUserManager.isUserUnlocked(userId));
}
@VisibleForTesting
void handleUserRemoved(int userId) {
- checkIsHandlerThread();
+ Assert.isMainThread();
mUserIsUnlocked.delete(userId);
mUserTrustIsUsuallyManaged.delete(userId);
}
@VisibleForTesting
@Inject
- protected KeyguardUpdateMonitor(Context context, @Main Looper mainLooper,
+ protected KeyguardUpdateMonitor(
+ Context context,
+ @Main Looper mainLooper,
BroadcastDispatcher broadcastDispatcher,
DumpController dumpController) {
mContext = context;
@@ -1962,7 +1965,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper.
*/
public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (hasLockscreenWallpaper != mHasLockscreenWallpaper) {
mHasLockscreenWallpaper = hasLockscreenWallpaper;
for (int i = 0; i < mCallbacks.size(); i++) {
@@ -1985,7 +1988,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* Handle {@link #MSG_DPM_STATE_CHANGED}
*/
private void handleDevicePolicyManagerStateChanged(int userId) {
- checkIsHandlerThread();
+ Assert.isMainThread();
updateFingerprintListeningState();
updateSecondaryLockscreenRequirement(userId);
for (int i = 0; i < mCallbacks.size(); i++) {
@@ -2000,7 +2003,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* Handle {@link #MSG_USER_SWITCHING}
*/
private void handleUserSwitching(int userId, IRemoteCallback reply) {
- checkIsHandlerThread();
+ Assert.isMainThread();
mUserTrustIsUsuallyManaged.put(userId, mTrustManager.isTrustUsuallyManaged(userId));
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -2018,7 +2021,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* Handle {@link #MSG_USER_SWITCH_COMPLETE}
*/
private void handleUserSwitchComplete(int userId) {
- checkIsHandlerThread();
+ Assert.isMainThread();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -2031,7 +2034,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* Handle {@link #MSG_DEVICE_PROVISIONED}
*/
private void handleDeviceProvisioned() {
- checkIsHandlerThread();
+ Assert.isMainThread();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -2049,7 +2052,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* Handle {@link #MSG_PHONE_STATE_CHANGED}
*/
private void handlePhoneStateChanged(String newState) {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
mPhoneState = TelephonyManager.CALL_STATE_IDLE;
@@ -2070,7 +2073,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* Handle {@link #MSG_RINGER_MODE_CHANGED}
*/
private void handleRingerModeChange(int mode) {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
mRingMode = mode;
for (int i = 0; i < mCallbacks.size(); i++) {
@@ -2085,7 +2088,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* Handle {@link #MSG_TIME_UPDATE}
*/
private void handleTimeUpdate() {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (DEBUG) Log.d(TAG, "handleTimeUpdate");
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -2099,7 +2102,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* Handle (@line #MSG_TIMEZONE_UPDATE}
*/
private void handleTimeZoneUpdate(String timeZone) {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (DEBUG) Log.d(TAG, "handleTimeZoneUpdate");
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -2115,7 +2118,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* Handle {@link #MSG_BATTERY_UPDATE}
*/
private void handleBatteryUpdate(BatteryStatus status) {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
mBatteryStatus = status;
@@ -2134,7 +2137,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
*/
@VisibleForTesting
void updateTelephonyCapable(boolean capable) {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (capable == mTelephonyCapable) {
return;
}
@@ -2152,7 +2155,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
*/
@VisibleForTesting
void handleSimStateChange(int subId, int slotId, int state) {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (DEBUG_SIM_STATES) {
Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
+ slotId + ", state=" + state + ")");
@@ -2236,7 +2239,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* <p>Needs to be called from the main thread.
*/
public void onKeyguardVisibilityChanged(boolean showing) {
- checkIsHandlerThread();
+ Assert.isMainThread();
Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
mKeyguardIsVisible = showing;
@@ -2279,7 +2282,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* @see #sendKeyguardBouncerChanged(boolean)
*/
private void handleKeyguardBouncerChanged(int bouncer) {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
boolean isBouncer = (bouncer == 1);
mBouncer = isBouncer;
@@ -2305,7 +2308,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
*/
private void handleReportEmergencyCallAction() {
- checkIsHandlerThread();
+ Assert.isMainThread();
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -2344,7 +2347,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* @param callback The callback to remove
*/
public void removeCallback(KeyguardUpdateMonitorCallback callback) {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (DEBUG) {
Log.v(TAG, "*** unregister callback for " + callback);
}
@@ -2359,7 +2362,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* @param callback The callback to register
*/
public void registerCallback(KeyguardUpdateMonitorCallback callback) {
- checkIsHandlerThread();
+ Assert.isMainThread();
if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
// Prevent adding duplicate callbacks
@@ -2448,7 +2451,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
if (!bypassHandler) {
mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
} else {
- checkIsHandlerThread();
+ Assert.isMainThread();
handleReportEmergencyCallAction();
}
}
@@ -2466,7 +2469,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
public void clearBiometricRecognized() {
- checkIsHandlerThread();
+ Assert.isMainThread();
mUserFingerprintAuthenticated.clear();
mUserFaceAuthenticated.clear();
mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FINGERPRINT);
@@ -2653,7 +2656,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void updateLogoutEnabled() {
- checkIsHandlerThread();
+ Assert.isMainThread();
boolean logoutEnabled = mDevicePolicyManager.isLogoutEnabled();
if (mLogoutEnabled != logoutEnabled) {
mLogoutEnabled = logoutEnabled;
@@ -2667,13 +2670,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
}
- private void checkIsHandlerThread() {
- if (!mHandler.getLooper().isCurrentThread()) {
- Log.wtfStack(TAG, "must call on mHandler's thread "
- + mHandler.getLooper().getThread() + ", not " + Thread.currentThread());
- }
- }
-
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("KeyguardUpdateMonitor state:");
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 3eac229af3f6..b03ba3c2a110 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
@@ -336,6 +336,10 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
return false;
}
+ boolean superPerformClick() {
+ return super.performClick();
+ }
+
/**
* Cancels the hotspot and makes the notification inactive.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
index 8465658079f1..2643ec975023 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
@@ -72,7 +72,8 @@ public class ActivatableNotificationViewController {
} else {
mView.makeInactive(true /* animate */);
}
- }, mView::performClick, mView::handleSlideBack, mFalsingManager::onNotificationDoubleTap);
+ }, mView::superPerformClick, mView::handleSlideBack,
+ mFalsingManager::onNotificationDoubleTap);
mView.setOnTouchListener(mTouchHandler);
mView.setTouchHandler(mTouchHandler);
mView.setOnDimmedListener(dimmed -> {
diff --git a/packages/SystemUI/src/com/android/systemui/util/Assert.java b/packages/SystemUI/src/com/android/systemui/util/Assert.java
index f6e921e628ba..3f05657ed09e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/Assert.java
+++ b/packages/SystemUI/src/com/android/systemui/util/Assert.java
@@ -24,12 +24,17 @@ import androidx.annotation.VisibleForTesting;
* Helper providing common assertions.
*/
public class Assert {
+ private static final Looper sMainLooper = Looper.getMainLooper();
+ private static Looper sTestLooper = null;
@VisibleForTesting
- public static Looper sMainLooper = Looper.getMainLooper();
+ public static void setTestableLooper(Looper testLooper) {
+ sTestLooper = testLooper;
+ }
public static void isMainThread() {
- if (!sMainLooper.isCurrentThread()) {
+ if (!sMainLooper.isCurrentThread()
+ && (sTestLooper == null || !sTestLooper.isCurrentThread())) {
throw new IllegalStateException("should be called from the main thread."
+ " sMainLooper.threadName=" + sMainLooper.getThread().getName()
+ " Thread.currentThread()=" + Thread.currentThread().getName());
@@ -37,7 +42,8 @@ public class Assert {
}
public static void isNotMainThread() {
- if (sMainLooper.isCurrentThread()) {
+ if (sMainLooper.isCurrentThread()
+ && (sTestLooper == null || sTestLooper.isCurrentThread())) {
throw new IllegalStateException("should not be called from the main thread.");
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java
index 082782d3092a..b6ca8d8e4afb 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPresentationTest.java
@@ -37,7 +37,7 @@ public class KeyguardPresentationTest extends SysuiTestCase {
@Test
public void testInflation_doesntCrash() {
mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
- com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
InjectionInflationController inflationController = new InjectionInflationController(
SystemUIFactory.getInstance().getRootComponent());
Context context = getContext();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
index 116f8fc7d3eb..462b0421e1ed 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
@@ -19,7 +19,6 @@ import android.graphics.Color;
import android.net.Uri;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.LayoutInflater;
@@ -51,7 +50,7 @@ public class KeyguardSliceViewTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
- com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
InjectionInflationController inflationController = new InjectionInflationController(
SystemUIFactory.getInstance().getRootComponent());
LayoutInflater layoutInflater = inflationController
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
index e4b83ccc5125..bc3c3d995ce6 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
@@ -20,14 +20,12 @@ import static org.mockito.Mockito.verify;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.LayoutInflater;
import com.android.systemui.R;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.util.Assert;
import com.android.systemui.util.InjectionInflationController;
import org.junit.Before;
@@ -50,7 +48,7 @@ public class KeyguardStatusViewTest extends SysuiTestCase {
@Before
public void setUp() {
- Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
InjectionInflationController inflationController = new InjectionInflationController(
SystemUIFactory.getInstance().getRootComponent());
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 7e4ba92301aa..befe3e12b64e 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -147,6 +147,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
context.addMockSystemService(SubscriptionManager.class, mSubscriptionManager);
mTestableLooper = TestableLooper.get(this);
+ allowTestableLooperAsMainThread();
mKeyguardUpdateMonitor = new TestableKeyguardUpdateMonitor(context);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java
index ffe8c285b4f1..471149c936e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ExpandHelperTest.java
@@ -23,7 +23,6 @@ import static org.mockito.Mockito.when;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import androidx.test.annotation.UiThreadTest;
@@ -33,7 +32,6 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
-import com.android.systemui.util.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -52,7 +50,7 @@ public class ExpandHelperTest extends SysuiTestCase {
public void setUp() throws Exception {
mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
mDependency.injectMockDependency(NotificationMediaManager.class);
- Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
Context context = getContext();
mRow = new NotificationTestHelper(context, mDependency).createRow();
mCallback = mock(ExpandHelper.Callback.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
index 8d11b54dacb2..c912b678ac09 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ForegroundServiceControllerTest.java
@@ -35,7 +35,6 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.os.Bundle;
import android.os.Handler;
-import android.os.Looper;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
@@ -75,8 +74,8 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
- // assume the TestLooper is the main looper for these tests
- com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ // allow the TestLooper to be asserted as the main thread these tests
+ allowTestableLooperAsMainThread();
MockitoAnnotations.initMocks(this);
mFsc = new ForegroundServiceController(mEntryManager, mAppOpsController, mMainHandler);
@@ -93,7 +92,7 @@ public class ForegroundServiceControllerTest extends SysuiTestCase {
public void testAppOpsChangedCalledFromBgThread() {
try {
// WHEN onAppOpChanged is called from a different thread than the MainLooper
- com.android.systemui.util.Assert.sMainLooper = Looper.getMainLooper();
+ disallowTestableLooperAsMainThread();
NotificationEntry entry = createFgEntry();
mFsc.onAppOpChanged(
AppOpsManager.OP_CAMERA,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java b/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java
index fc331d6adccc..689eed9e2a61 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java
@@ -77,7 +77,7 @@ public class ImageWallpaperTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
- com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
MockitoAnnotations.initMocks(this);
mEventCountdown = new CountDownLatch(1);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index c85d600e8447..7ac5443d67d0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -25,6 +25,7 @@ import android.os.MessageQueue;
import android.os.ParcelFileDescriptor;
import android.testing.DexmakerShareClassLoaderRule;
import android.testing.LeakCheck;
+import android.testing.TestableLooper;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
@@ -32,7 +33,6 @@ import androidx.test.InstrumentationRegistry;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.util.Assert;
import org.junit.After;
import org.junit.Before;
@@ -86,11 +86,24 @@ public abstract class SysuiTestCase {
public void SysuiTeardown() {
InstrumentationRegistry.registerInstance(mRealInstrumentation,
InstrumentationRegistry.getArguments());
- // Reset the assert's main looper.
- Assert.sMainLooper = Looper.getMainLooper();
+ // Reset the assert's testable looper to null.
+ disallowTestableLooperAsMainThread();
SystemUIFactory.cleanup();
}
+ /**
+ * Tests are run on the TestableLooper; however, there are parts of SystemUI that assert that
+ * the code is run from the main looper. Therefore, we allow the TestableLooper to pass these
+ * assertions since in a test, the TestableLooper is essentially the MainLooper.
+ */
+ protected void allowTestableLooperAsMainThread() {
+ com.android.systemui.util.Assert.setTestableLooper(TestableLooper.get(this).getLooper());
+ }
+
+ protected void disallowTestableLooperAsMainThread() {
+ com.android.systemui.util.Assert.setTestableLooper(null);
+ }
+
protected LeakCheck getLeakCheck() {
return null;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index 60163f26bb2b..8e87e0a802ef 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -54,7 +54,6 @@ import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectio
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
-import com.android.systemui.util.Assert;
import com.google.android.collect.Lists;
@@ -90,7 +89,7 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase {
public void setUp() {
MockitoAnnotations.initMocks(this);
mTestableLooper = TestableLooper.get(this);
- Assert.sMainLooper = mTestableLooper.getLooper();
+ allowTestableLooperAsMainThread();
mHandler = Handler.createAsync(mTestableLooper.getLooper());
mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java
index 9d667a9a91c8..0a38f163cfba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AboveShelfObserverTest.java
@@ -21,7 +21,6 @@ import static org.mockito.Mockito.verify;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.widget.FrameLayout;
@@ -46,7 +45,7 @@ public class AboveShelfObserverTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
- com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
mNotificationTestHelper = new NotificationTestHelper(getContext(), mDependency);
mHostLayout = new FrameLayout(getContext());
mObserver = new AboveShelfObserver(mHostLayout);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index f1fba792a882..0b17d1cf84bf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -98,7 +98,6 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.util.Assert;
import com.android.systemui.util.leak.LeakDetector;
import com.android.systemui.util.time.FakeSystemClock;
@@ -205,7 +204,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
mCountDownLatch = new CountDownLatch(1);
- Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
Handler.createAsync(TestableLooper.get(this).getLooper()));
when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
index 1116a333125e..97e0a3199e17 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
@@ -32,7 +32,6 @@ import android.content.pm.PackageManager;
import android.os.Bundle;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import androidx.test.annotation.UiThreadTest;
@@ -79,7 +78,7 @@ public class NotificationFilterTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
- com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
MockitoAnnotations.initMocks(this);
when(mMockStatusBarNotification.getUid()).thenReturn(UID_NORMAL);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
index 12e9d31fdd0c..605b59ef3974 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifCollectionTest.java
@@ -77,7 +77,6 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.No
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionLogger;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
-import com.android.systemui.util.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -129,7 +128,7 @@ public class NotifCollectionTest extends SysuiTestCase {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
when(mFeatureFlags.isNewNotifPipelineRenderingEnabled()).thenReturn(true);
when(mFeatureFlags.isNewNotifPipelineEnabled()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
index 27ca18cd8033..e570ab8d7f41 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilderTest.java
@@ -51,7 +51,6 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSection;
import com.android.systemui.statusbar.notification.collection.notifcollection.CollectionReadyForBuildListener;
-import com.android.systemui.util.Assert;
import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
@@ -101,7 +100,7 @@ public class ShadeListBuilderTest extends SysuiTestCase {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
mListBuilder = new ShadeListBuilder(mSystemClock, mLogger, mock(DumpController.class));
mListBuilder.setOnRenderListListener(mOnRenderListListener);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinatorTest.java
index eb1af7c82324..67b1aad94f51 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinatorTest.java
@@ -44,7 +44,6 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender;
-import com.android.systemui.util.Assert;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
@@ -84,7 +83,7 @@ public class ForegroundCoordinatorTest extends SysuiTestCase {
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
mForegroundCoordinator =
new ForegroundCoordinator(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index a8918103c4a2..e960185ebe3a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -39,7 +39,6 @@ import static org.mockito.Mockito.when;
import android.app.AppOpsManager;
import android.app.NotificationChannel;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.util.ArraySet;
import android.view.NotificationHeaderView;
@@ -79,7 +78,7 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
- com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
mNotificationTestHelper = new NotificationTestHelper(mContext, mDependency);
mGroupRow = mNotificationTestHelper.createGroup();
mGroupRow.setHeadsUpAnimatingAwayListener(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java
index a8c438a390ef..481bac2c19c6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java
@@ -49,7 +49,6 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.util.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -75,7 +74,7 @@ public class NotificationBlockingHelperManagerTest extends SysuiTestCase {
@Before
public void setUp() {
- Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
MockitoAnnotations.initMocks(this);
mDependency.injectMockDependency(BubbleController.class);
when(mGutsManager.openGuts(
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 bbb6723135a6..54c0bde13408 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
@@ -74,7 +74,6 @@ import com.android.systemui.statusbar.notification.row.NotificationGutsManager.O
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.util.Assert;
import org.junit.Before;
import org.junit.Ignore;
@@ -118,7 +117,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
@Before
public void setUp() {
mTestableLooper = TestableLooper.get(this);
- Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
mDependency.injectTestDependency(DeviceProvisionedController.class,
mDeviceProvisionedController);
mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java
index 0790cb7ca6c4..b661b28c42fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapperTest.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.notification.row.wrapper;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.View;
import android.widget.RemoteViews;
@@ -43,7 +42,7 @@ public class NotificationCustomViewWrapperTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
- com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
mRow = new NotificationTestHelper(mContext, mDependency).createRow();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java
index 038eff7fa5dc..69e4f2205c35 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapperTest.java
@@ -26,7 +26,6 @@ import android.media.MediaMetadata;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.View;
import android.widget.RemoteViews;
@@ -64,7 +63,7 @@ public class NotificationMediaTemplateViewWrapperTest extends SysuiTestCase {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapperTest.java
index 9567f3386dda..830e8d93196c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapperTest.java
@@ -20,7 +20,6 @@ import static org.mockito.Mockito.mock;
import android.content.Context;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.View;
import android.widget.LinearLayout;
@@ -31,7 +30,6 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
-import com.android.systemui.util.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -48,7 +46,7 @@ public class NotificationViewWrapperTest extends SysuiTestCase {
@Before
public void setup() throws Exception {
- Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
mView = mock(View.class);
mRow = new NotificationTestHelper(getContext(), mDependency).createRow();
mNotificationViewWrapper = new TestableNotificationViewWrapper(mContext, mView, mRow);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
index 1773175450ff..a2029c76bb55 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainerTest.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.notification.stack;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.NotificationHeaderView;
import android.view.View;
@@ -44,7 +43,7 @@ public class NotificationChildrenContainerTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
- com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
mNotificationTestHelper = new NotificationTestHelper(mContext, mDependency);
mGroup = mNotificationTestHelper.createGroup();
mChildrenContainer = mGroup.getChildrenContainer();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
index 2d1bc7890aed..ba2b94677814 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
@@ -24,7 +24,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import androidx.test.filters.SmallTest;
@@ -66,7 +65,7 @@ public class NotificationRoundnessManagerTest extends SysuiTestCase {
mRoundnessManager = new NotificationRoundnessManager(
mBypassController,
new NotificationSectionsFeatureManager(new DeviceConfigProxy(), mContext));
- com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
NotificationTestHelper testHelper = new NotificationTestHelper(getContext(), mDependency);
mFirst = testHelper.createRow();
mFirst.setHeadsUpAnimatingAwayListener(animatingAway
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 9ccee75a3d09..d768bc30175f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -144,7 +144,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@Before
@UiThreadTest
public void setUp() throws Exception {
- com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
mOriginalInterruptionModelSetting = Settings.Secure.getInt(mContext.getContentResolver(),
NOTIFICATION_NEW_INTERRUPTION_MODEL, 0);
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 f71d0fc4b43e..a74657e561aa 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
@@ -23,7 +23,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.View;
import android.widget.TextView;
@@ -69,7 +68,7 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
- com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
NotificationTestHelper testHelper = new NotificationTestHelper(getContext(), mDependency);
mFirst = testHelper.createRow();
mDependency.injectTestDependency(DarkIconDispatcher.class, mDarkIconDispatcher);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
index 67b8e07f2bec..35971bd4037c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
@@ -96,7 +96,7 @@ public class KeyguardBouncerTest extends SysuiTestCase {
@Before
public void setup() {
- com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
MockitoAnnotations.initMocks(this);
mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor);
mDependency.injectTestDependency(KeyguardSecurityModel.class, mKeyguardSecurityModel);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
index df622542e22c..86add98ab929 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java
@@ -43,7 +43,6 @@ import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
import com.android.systemui.statusbar.phone.LightBarController;
-import com.android.systemui.util.Assert;
import org.junit.After;
import org.junit.Before;
@@ -74,7 +73,7 @@ public class RemoteInputViewTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
- Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
MockitoAnnotations.initMocks(this);
mDependency.injectTestDependency(RemoteInputQuickSettingsDisabler.class,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListenerTest.java
index 20dcbb73c212..1ff9548486ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/wakelock/KeepAwakeAnimationListenerTest.java
@@ -21,14 +21,12 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import android.animation.Animator;
-import android.os.Looper;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.util.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -45,7 +43,7 @@ public class KeepAwakeAnimationListenerTest extends SysuiTestCase {
@Before
public void setup() {
- Assert.sMainLooper = TestableLooper.get(this).getLooper();
+ allowTestableLooperAsMainThread();
MockitoAnnotations.initMocks(this);
KeepAwakeAnimationListener.sWakeLock = mWakeLock;
mKeepAwakeAnimationListener = new KeepAwakeAnimationListener(getContext());
@@ -63,7 +61,10 @@ public class KeepAwakeAnimationListenerTest extends SysuiTestCase {
@Test(expected = IllegalStateException.class)
public void initThrows_onNonMainThread() {
- Assert.sMainLooper = Looper.getMainLooper();
+ disallowTestableLooperAsMainThread();
+
+ // we are creating the KeepAwakeAnimationListener from the TestableLooper, not the main
+ // looper, so we expect an IllegalStateException:
new KeepAwakeAnimationListener(getContext());
}
}
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
index bfa962a18c9a..fd9f7137c85d 100644
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
+++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
@@ -212,7 +212,7 @@ public class TetheringManager {
new Thread(() -> {
while (true) {
try {
- Thread.sleep(200);
+ Thread.sleep(CONNECTOR_POLL_INTERVAL_MILLIS);
} catch (InterruptedException e) {
// Not much to do here, the system needs to wait for the connector
}
diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsService.java b/services/core/java/com/android/server/pm/CrossProfileAppsService.java
index 027a302a325e..486282aa2c04 100644
--- a/services/core/java/com/android/server/pm/CrossProfileAppsService.java
+++ b/services/core/java/com/android/server/pm/CrossProfileAppsService.java
@@ -16,6 +16,7 @@
package com.android.server.pm;
import android.content.Context;
+import android.content.pm.CrossProfileAppsInternal;
import com.android.server.SystemService;
@@ -30,5 +31,6 @@ public class CrossProfileAppsService extends SystemService {
@Override
public void onStart() {
publishBinderService(Context.CROSS_PROFILE_APPS_SERVICE, mServiceImpl);
+ publishLocalService(CrossProfileAppsInternal.class, mServiceImpl.getLocalService());
}
}
diff --git a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
index a83102552ae4..ec9b37db3137 100644
--- a/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
+++ b/services/core/java/com/android/server/pm/CrossProfileAppsServiceImpl.java
@@ -67,6 +67,8 @@ import java.util.Objects;
public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
private static final String TAG = "CrossProfileAppsService";
+ private final LocalService mLocalService = new LocalService();
+
private Context mContext;
private Injector mInjector;
@@ -78,8 +80,6 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
CrossProfileAppsServiceImpl(Context context, Injector injector) {
mContext = context;
mInjector = injector;
-
- LocalServices.addService(CrossProfileAppsInternal.class, new LocalService());
}
@Override
@@ -209,7 +209,7 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
}
if (callerUserId != userId) {
- if (!hasInteractAcrossProfilesPermission(callingPackage)) {
+ if (!hasCallerGotInteractAcrossProfilesPermission(callingPackage)) {
throw new SecurityException("Attempt to launch activity without required "
+ android.Manifest.permission.INTERACT_ACROSS_PROFILES + " permission"
+ " or target user is not in the same profile group.");
@@ -280,20 +280,12 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
if (targetUserProfiles.isEmpty()) {
return false;
}
- return hasInteractAcrossProfilesPermission(callingPackage);
+ return hasCallerGotInteractAcrossProfilesPermission(callingPackage);
}
- private boolean hasInteractAcrossProfilesPermission(String callingPackage) {
- final int callingUid = mInjector.getCallingUid();
- final int callingPid = mInjector.getCallingPid();
- return isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, callingUid)
- || isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, callingUid)
- || PermissionChecker.checkPermissionForPreflight(
- mContext,
- Manifest.permission.INTERACT_ACROSS_PROFILES,
- callingPid,
- callingUid,
- callingPackage) == PermissionChecker.PERMISSION_GRANTED;
+ private boolean hasCallerGotInteractAcrossProfilesPermission(String callingPackage) {
+ return hasInteractAcrossProfilesPermission(
+ callingPackage, mInjector.getCallingUid(), mInjector.getCallingPid());
}
private boolean isCrossProfilePackageWhitelisted(String packageName) {
@@ -575,6 +567,10 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
setInteractAcrossProfilesAppOp(packageName, AppOpsManager.opToDefaultMode(op));
}
+ CrossProfileAppsInternal getLocalService() {
+ return mLocalService;
+ }
+
private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) {
return mInjector.withCleanCallingIdentity(() ->
mInjector.getUserManager().isSameProfileGroup(callerUserId, userId));
@@ -601,6 +597,20 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
-> mContext.getSystemService(UserManager.class).isManagedProfile(userId));
}
+ private boolean hasInteractAcrossProfilesPermission(String packageName, int uid, int pid) {
+ if (isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, uid)
+ || isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, uid)) {
+ return true;
+ }
+ return PermissionChecker.PERMISSION_GRANTED
+ == PermissionChecker.checkPermissionForPreflight(
+ mContext,
+ Manifest.permission.INTERACT_ACROSS_PROFILES,
+ pid,
+ uid,
+ packageName);
+ }
+
private static class InjectorImpl implements Injector {
private Context mContext;
@@ -740,9 +750,11 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
}
class LocalService extends CrossProfileAppsInternal {
+
@Override
- public boolean verifyPackageHasInteractAcrossProfilePermission(String packageName,
- @UserIdInt int userId) throws PackageManager.NameNotFoundException {
+ public boolean verifyPackageHasInteractAcrossProfilePermission(
+ String packageName, @UserIdInt int userId)
+ throws PackageManager.NameNotFoundException {
final int uid = Objects.requireNonNull(
mInjector.getPackageManager().getApplicationInfoAsUser(
Objects.requireNonNull(packageName), /* flags= */ 0, userId)).uid;
@@ -752,16 +764,13 @@ public class CrossProfileAppsServiceImpl extends ICrossProfileApps.Stub {
@Override
public boolean verifyUidHasInteractAcrossProfilePermission(String packageName, int uid) {
Objects.requireNonNull(packageName);
+ return hasInteractAcrossProfilesPermission(
+ packageName, uid, PermissionChecker.PID_UNKNOWN);
+ }
- return isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS_FULL, uid)
- || isPermissionGranted(Manifest.permission.INTERACT_ACROSS_USERS, uid)
- || isPermissionGranted(Manifest.permission.INTERACT_ACROSS_PROFILES, uid)
- || PermissionChecker.checkPermissionForPreflight(
- mContext,
- Manifest.permission.INTERACT_ACROSS_PROFILES,
- PermissionChecker.PID_UNKNOWN,
- uid,
- packageName) == PermissionChecker.PERMISSION_GRANTED;
+ @Override
+ public List<UserHandle> getTargetUserProfiles(String packageName, int userId) {
+ return getTargetUserProfilesUnchecked(packageName, userId);
}
}
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index a7b0d84ef040..8483c774cb8e 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -242,8 +242,8 @@ public final class PowerManagerService extends SystemService
private final ServiceThread mHandlerThread;
private final PowerManagerHandler mHandler;
private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
- private final BatterySaverPolicy mBatterySaverPolicy;
private final BatterySaverController mBatterySaverController;
+ private final BatterySaverPolicy mBatterySaverPolicy;
private final BatterySaverStateMachine mBatterySaverStateMachine;
private final BatterySavingStats mBatterySavingStats;
private final AttentionDetector mAttentionDetector;
@@ -275,7 +275,8 @@ public final class PowerManagerService extends SystemService
// Indicates whether the device is awake or asleep or somewhere in between.
// This is distinct from the screen power state, which is managed separately.
- private int mWakefulness;
+ // Do not access directly; always use {@link #setWakefulness} and {@link getWakefulness}.
+ private int mWakefulnessRaw;
private boolean mWakefulnessChanging;
// True if the sandman has just been summoned for the first time since entering the
@@ -764,6 +765,13 @@ public final class PowerManagerService extends SystemService
return new BatterySaverPolicy(lock, context, batterySavingStats);
}
+ BatterySaverController createBatterySaverController(
+ Object lock, Context context, BatterySaverPolicy batterySaverPolicy,
+ BatterySavingStats batterySavingStats) {
+ return new BatterySaverController(lock, context, BackgroundThread.get().getLooper(),
+ batterySaverPolicy, batterySavingStats);
+ }
+
NativeWrapper createNativeWrapper() {
return new NativeWrapper();
}
@@ -794,6 +802,10 @@ public final class PowerManagerService extends SystemService
}
};
}
+
+ void invalidateIsInteractiveCaches() {
+ PowerManager.invalidateIsInteractiveCaches();
+ }
}
final Constants mConstants;
@@ -833,9 +845,8 @@ public final class PowerManagerService extends SystemService
mBatterySavingStats = new BatterySavingStats(mLock);
mBatterySaverPolicy =
mInjector.createBatterySaverPolicy(mLock, mContext, mBatterySavingStats);
- mBatterySaverController = new BatterySaverController(mLock, mContext,
- BackgroundThread.get().getLooper(), mBatterySaverPolicy,
- mBatterySavingStats);
+ mBatterySaverController = mInjector.createBatterySaverController(mLock, mContext,
+ mBatterySaverPolicy, mBatterySavingStats);
mBatterySaverStateMachine = new BatterySaverStateMachine(
mLock, mContext, mBatterySaverController);
@@ -939,13 +950,14 @@ public final class PowerManagerService extends SystemService
mHalAutoSuspendModeEnabled = false;
mHalInteractiveModeEnabled = true;
- mWakefulness = WAKEFULNESS_AWAKE;
+ mWakefulnessRaw = WAKEFULNESS_AWAKE;
sQuiescent = mSystemProperties.get(SYSTEM_PROPERTY_QUIESCENT, "0").equals("1");
mNativeWrapper.nativeInit(this);
mNativeWrapper.nativeSetAutoSuspend(false);
mNativeWrapper.nativeSetInteractive(true);
mNativeWrapper.nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
+ mInjector.invalidateIsInteractiveCaches();
}
}
@@ -1567,8 +1579,8 @@ public final class PowerManagerService extends SystemService
mOverriddenTimeout = -1;
}
- if (mWakefulness == WAKEFULNESS_ASLEEP
- || mWakefulness == WAKEFULNESS_DOZING
+ if (getWakefulnessLocked() == WAKEFULNESS_ASLEEP
+ || getWakefulnessLocked() == WAKEFULNESS_DOZING
|| (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) {
return false;
}
@@ -1624,7 +1636,7 @@ public final class PowerManagerService extends SystemService
Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime + ", uid=" + reasonUid);
}
- if (eventTime < mLastSleepTime || mWakefulness == WAKEFULNESS_AWAKE
+ if (eventTime < mLastSleepTime || getWakefulnessLocked() == WAKEFULNESS_AWAKE
|| mForceSuspendActive || !mSystemReady) {
return false;
}
@@ -1634,7 +1646,7 @@ public final class PowerManagerService extends SystemService
Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp");
try {
Slog.i(TAG, "Waking up from "
- + PowerManagerInternal.wakefulnessToString(mWakefulness)
+ + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())
+ " (uid=" + reasonUid
+ ", reason=" + PowerManager.wakeReasonToString(reason)
+ ", details=" + details
@@ -1680,8 +1692,8 @@ public final class PowerManagerService extends SystemService
}
if (eventTime < mLastWakeTime
- || mWakefulness == WAKEFULNESS_ASLEEP
- || mWakefulness == WAKEFULNESS_DOZING
+ || getWakefulnessLocked() == WAKEFULNESS_ASLEEP
+ || getWakefulnessLocked() == WAKEFULNESS_DOZING
|| !mSystemReady
|| !mBootCompleted) {
return false;
@@ -1738,7 +1750,7 @@ public final class PowerManagerService extends SystemService
Slog.d(TAG, "napNoUpdateLocked: eventTime=" + eventTime + ", uid=" + uid);
}
- if (eventTime < mLastWakeTime || mWakefulness != WAKEFULNESS_AWAKE
+ if (eventTime < mLastWakeTime || getWakefulnessLocked() != WAKEFULNESS_AWAKE
|| !mBootCompleted || !mSystemReady) {
return false;
}
@@ -1762,7 +1774,7 @@ public final class PowerManagerService extends SystemService
+ ", uid=" + uid);
}
- if (eventTime < mLastWakeTime || mWakefulness == WAKEFULNESS_ASLEEP
+ if (eventTime < mLastWakeTime || getWakefulnessLocked() == WAKEFULNESS_ASLEEP
|| !mBootCompleted || !mSystemReady) {
return false;
}
@@ -1781,13 +1793,15 @@ public final class PowerManagerService extends SystemService
@VisibleForTesting
void setWakefulnessLocked(int wakefulness, int reason, long eventTime) {
- if (mWakefulness != wakefulness) {
- mWakefulness = wakefulness;
+ if (getWakefulnessLocked() != wakefulness) {
+ // Under lock, invalidate before set ensures caches won't return stale values.
+ mInjector.invalidateIsInteractiveCaches();
+ mWakefulnessRaw = wakefulness;
mWakefulnessChanging = true;
mDirty |= DIRTY_WAKEFULNESS;
// This is only valid while we are in wakefulness dozing. Set to false otherwise.
- mDozeStartInProgress &= (mWakefulness == WAKEFULNESS_DOZING);
+ mDozeStartInProgress &= (getWakefulnessLocked() == WAKEFULNESS_DOZING);
if (mNotifier != null) {
mNotifier.onWakefulnessChangeStarted(wakefulness, reason, eventTime);
@@ -1797,8 +1811,8 @@ public final class PowerManagerService extends SystemService
}
@VisibleForTesting
- int getWakefulness() {
- return mWakefulness;
+ int getWakefulnessLocked() {
+ return mWakefulnessRaw;
}
/**
@@ -1816,17 +1830,18 @@ public final class PowerManagerService extends SystemService
private void finishWakefulnessChangeIfNeededLocked() {
if (mWakefulnessChanging && mDisplayReady) {
- if (mWakefulness == WAKEFULNESS_DOZING
+ if (getWakefulnessLocked() == WAKEFULNESS_DOZING
&& (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
return; // wait until dream has enabled dozing
} else {
// Doze wakelock acquired (doze started) or device is no longer dozing.
mDozeStartInProgress = false;
}
- if (mWakefulness == WAKEFULNESS_DOZING || mWakefulness == WAKEFULNESS_ASLEEP) {
+ if (getWakefulnessLocked() == WAKEFULNESS_DOZING
+ || getWakefulnessLocked() == WAKEFULNESS_ASLEEP) {
logSleepTimeoutRecapturedLocked();
}
- if (mWakefulness == WAKEFULNESS_AWAKE) {
+ if (getWakefulnessLocked() == WAKEFULNESS_AWAKE) {
Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, 0);
final int latencyMs = (int) (SystemClock.uptimeMillis() - mLastWakeTime);
if (latencyMs >= SCREEN_ON_LATENCY_WARNING_MS) {
@@ -2006,7 +2021,7 @@ public final class PowerManagerService extends SystemService
}
// If already dreaming and becoming powered, then don't wake.
- if (mIsPowered && mWakefulness == WAKEFULNESS_DREAMING) {
+ if (mIsPowered && getWakefulnessLocked() == WAKEFULNESS_DREAMING) {
return false;
}
@@ -2016,7 +2031,7 @@ public final class PowerManagerService extends SystemService
}
// On Always On Display, SystemUI shows the charging indicator
- if (mAlwaysOnEnabled && mWakefulness == WAKEFULNESS_DOZING) {
+ if (mAlwaysOnEnabled && getWakefulnessLocked() == WAKEFULNESS_DOZING) {
return false;
}
@@ -2081,7 +2096,7 @@ public final class PowerManagerService extends SystemService
if (DEBUG_SPEW) {
Slog.d(TAG, "updateWakeLockSummaryLocked: mWakefulness="
- + PowerManagerInternal.wakefulnessToString(mWakefulness)
+ + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())
+ ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary));
}
}
@@ -2089,23 +2104,23 @@ public final class PowerManagerService extends SystemService
private int adjustWakeLockSummaryLocked(int wakeLockSummary) {
// Cancel wake locks that make no sense based on the current state.
- if (mWakefulness != WAKEFULNESS_DOZING) {
+ if (getWakefulnessLocked() != WAKEFULNESS_DOZING) {
wakeLockSummary &= ~(WAKE_LOCK_DOZE | WAKE_LOCK_DRAW);
}
- if (mWakefulness == WAKEFULNESS_ASLEEP
+ if (getWakefulnessLocked() == WAKEFULNESS_ASLEEP
|| (wakeLockSummary & WAKE_LOCK_DOZE) != 0) {
wakeLockSummary &= ~(WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
| WAKE_LOCK_BUTTON_BRIGHT);
- if (mWakefulness == WAKEFULNESS_ASLEEP) {
+ if (getWakefulnessLocked() == WAKEFULNESS_ASLEEP) {
wakeLockSummary &= ~WAKE_LOCK_PROXIMITY_SCREEN_OFF;
}
}
// Infer implied wake locks where necessary based on the current state.
if ((wakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) != 0) {
- if (mWakefulness == WAKEFULNESS_AWAKE) {
+ if (getWakefulnessLocked() == WAKEFULNESS_AWAKE) {
wakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_STAY_AWAKE;
- } else if (mWakefulness == WAKEFULNESS_DREAMING) {
+ } else if (getWakefulnessLocked() == WAKEFULNESS_DREAMING) {
wakeLockSummary |= WAKE_LOCK_CPU;
}
}
@@ -2213,9 +2228,9 @@ public final class PowerManagerService extends SystemService
mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
long nextTimeout = 0;
- if (mWakefulness == WAKEFULNESS_AWAKE
- || mWakefulness == WAKEFULNESS_DREAMING
- || mWakefulness == WAKEFULNESS_DOZING) {
+ if (getWakefulnessLocked() == WAKEFULNESS_AWAKE
+ || getWakefulnessLocked() == WAKEFULNESS_DREAMING
+ || getWakefulnessLocked() == WAKEFULNESS_DOZING) {
final long attentiveTimeout = getAttentiveTimeoutLocked();
final long sleepTimeout = getSleepTimeoutLocked(attentiveTimeout);
final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout,
@@ -2299,7 +2314,7 @@ public final class PowerManagerService extends SystemService
if (DEBUG_SPEW) {
Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
- + PowerManagerInternal.wakefulnessToString(mWakefulness)
+ + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())
+ ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
+ ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
}
@@ -2368,7 +2383,7 @@ public final class PowerManagerService extends SystemService
mInattentiveSleepWarningOverlayController.show();
nextTimeout = goToSleepTime;
} else {
- if (DEBUG && mWakefulness != WAKEFULNESS_ASLEEP) {
+ if (DEBUG && getWakefulnessLocked() != WAKEFULNESS_ASLEEP) {
Slog.i(TAG, "Going to sleep now due to long user inactivity");
}
}
@@ -2386,7 +2401,7 @@ public final class PowerManagerService extends SystemService
return false;
}
- if (mWakefulness != WAKEFULNESS_AWAKE) {
+ if (getWakefulnessLocked() != WAKEFULNESS_AWAKE) {
mInattentiveSleepWarningOverlayController.dismiss(false);
return true;
} else if (attentiveTimeout < 0 || isBeingKeptFromShowingInattentiveSleepWarningLocked()
@@ -2490,7 +2505,7 @@ public final class PowerManagerService extends SystemService
| DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
| DIRTY_DOCK_STATE | DIRTY_ATTENTIVE | DIRTY_SETTINGS
| DIRTY_SCREEN_BRIGHTNESS_BOOST)) != 0) {
- if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
+ if (getWakefulnessLocked() == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
if (DEBUG_SPEW) {
Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
}
@@ -2613,7 +2628,7 @@ public final class PowerManagerService extends SystemService
final int wakefulness;
synchronized (mLock) {
mSandmanScheduled = false;
- wakefulness = mWakefulness;
+ wakefulness = getWakefulnessLocked();
if (mSandmanSummoned && mDisplayReady) {
startDreaming = canDreamLocked() || canDozeLocked();
mSandmanSummoned = false;
@@ -2655,7 +2670,7 @@ public final class PowerManagerService extends SystemService
// If preconditions changed, wait for the next iteration to determine
// whether the dream should continue (or be restarted).
- if (mSandmanSummoned || mWakefulness != wakefulness) {
+ if (mSandmanSummoned || getWakefulnessLocked() != wakefulness) {
return; // wait for next cycle
}
@@ -2717,7 +2732,7 @@ public final class PowerManagerService extends SystemService
* Returns true if the device is allowed to dream in its current state.
*/
private boolean canDreamLocked() {
- if (mWakefulness != WAKEFULNESS_DREAMING
+ if (getWakefulnessLocked() != WAKEFULNESS_DREAMING
|| !mDreamsSupportedConfig
|| !mDreamsEnabledSetting
|| !mDisplayPowerRequest.isBrightOrDim()
@@ -2749,7 +2764,7 @@ public final class PowerManagerService extends SystemService
* Returns true if the device is allowed to doze in its current state.
*/
private boolean canDozeLocked() {
- return mWakefulness == WAKEFULNESS_DOZING;
+ return getWakefulnessLocked() == WAKEFULNESS_DOZING;
}
/**
@@ -2825,7 +2840,7 @@ public final class PowerManagerService extends SystemService
if (DEBUG_SPEW) {
Slog.d(TAG, "updateDisplayPowerStateLocked: mDisplayReady=" + mDisplayReady
+ ", policy=" + mDisplayPowerRequest.policy
- + ", mWakefulness=" + mWakefulness
+ + ", mWakefulness=" + getWakefulnessLocked()
+ ", mWakeLockSummary=0x" + Integer.toHexString(mWakeLockSummary)
+ ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
+ ", mBootCompleted=" + mBootCompleted
@@ -2871,11 +2886,11 @@ public final class PowerManagerService extends SystemService
@VisibleForTesting
int getDesiredScreenPolicyLocked() {
- if (mWakefulness == WAKEFULNESS_ASLEEP || sQuiescent) {
+ if (getWakefulnessLocked() == WAKEFULNESS_ASLEEP || sQuiescent) {
return DisplayPowerRequest.POLICY_OFF;
}
- if (mWakefulness == WAKEFULNESS_DOZING) {
+ if (getWakefulnessLocked() == WAKEFULNESS_DOZING) {
if ((mWakeLockSummary & WAKE_LOCK_DOZE) != 0) {
return DisplayPowerRequest.POLICY_DOZE;
}
@@ -3079,7 +3094,7 @@ public final class PowerManagerService extends SystemService
// Here we wait for mWakefulnessChanging to become false since the wakefulness
// transition to DOZING isn't considered "changed" until the doze wake lock is
// acquired.
- if (mWakefulness == WAKEFULNESS_DOZING && mDozeStartInProgress) {
+ if (getWakefulnessLocked() == WAKEFULNESS_DOZING && mDozeStartInProgress) {
return true;
}
@@ -3119,7 +3134,7 @@ public final class PowerManagerService extends SystemService
private boolean isInteractiveInternal() {
synchronized (mLock) {
- return PowerManagerInternal.isInteractive(mWakefulness);
+ return PowerManagerInternal.isInteractive(getWakefulnessLocked());
}
}
@@ -3495,7 +3510,7 @@ public final class PowerManagerService extends SystemService
private void boostScreenBrightnessInternal(long eventTime, int uid) {
synchronized (mLock) {
- if (!mSystemReady || mWakefulness == WAKEFULNESS_ASLEEP
+ if (!mSystemReady || getWakefulnessLocked() == WAKEFULNESS_ASLEEP
|| eventTime < mLastScreenBrightnessBoostTime) {
return;
}
@@ -3725,7 +3740,8 @@ public final class PowerManagerService extends SystemService
pw.println("Power Manager State:");
mConstants.dump(pw);
pw.println(" mDirty=0x" + Integer.toHexString(mDirty));
- pw.println(" mWakefulness=" + PowerManagerInternal.wakefulnessToString(mWakefulness));
+ pw.println(" mWakefulness="
+ + PowerManagerInternal.wakefulnessToString(getWakefulnessLocked()));
pw.println(" mWakefulnessChanging=" + mWakefulnessChanging);
pw.println(" mIsPowered=" + mIsPowered);
pw.println(" mPlugType=" + mPlugType);
@@ -3936,7 +3952,7 @@ public final class PowerManagerService extends SystemService
synchronized (mLock) {
mConstants.dumpProto(proto);
proto.write(PowerManagerServiceDumpProto.DIRTY, mDirty);
- proto.write(PowerManagerServiceDumpProto.WAKEFULNESS, mWakefulness);
+ proto.write(PowerManagerServiceDumpProto.WAKEFULNESS, getWakefulnessLocked());
proto.write(PowerManagerServiceDumpProto.IS_WAKEFULNESS_CHANGING, mWakefulnessChanging);
proto.write(PowerManagerServiceDumpProto.IS_POWERED, mIsPowered);
proto.write(PowerManagerServiceDumpProto.PLUG_TYPE, mPlugType);
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
index 4142e6ff4d69..beba106ca0a6 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
@@ -38,7 +38,6 @@ import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.Preconditions;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
import com.android.server.power.PowerManagerService;
@@ -76,11 +75,19 @@ public class BatterySaverController implements BatterySaverPolicyListener {
@GuardedBy("mLock")
private final ArrayList<LowPowerModeListener> mListeners = new ArrayList<>();
+ /**
+ * Do not access directly; always use {@link #setFullEnabledLocked}
+ * and {@link #getFullEnabledLocked}
+ */
@GuardedBy("mLock")
- private boolean mFullEnabled;
+ private boolean mFullEnabledRaw;
+ /**
+ * Do not access directly; always use {@link #setAdaptiveEnabledLocked} and
+ * {@link #getAdaptiveEnabledLocked}.
+ */
@GuardedBy("mLock")
- private boolean mAdaptiveEnabled;
+ private boolean mAdaptiveEnabledRaw;
@GuardedBy("mLock")
private boolean mIsPluggedIn;
@@ -208,6 +215,7 @@ public class BatterySaverController implements BatterySaverPolicyListener {
mPlugins = new Plugin[] {
new BatterySaverLocationPlugin(mContext)
};
+ PowerManager.invalidatePowerSaveModeCaches();
}
/**
@@ -294,10 +302,10 @@ public class BatterySaverController implements BatterySaverPolicyListener {
@VisibleForTesting
public void enableBatterySaver(boolean enable, int reason) {
synchronized (mLock) {
- if (mFullEnabled == enable) {
+ if (getFullEnabledLocked() == enable) {
return;
}
- mFullEnabled = enable;
+ setFullEnabledLocked(enable);
if (updatePolicyLevelLocked()) {
mHandler.postStateChanged(/*sendBroadcast=*/ true, reason);
@@ -306,9 +314,9 @@ public class BatterySaverController implements BatterySaverPolicyListener {
}
private boolean updatePolicyLevelLocked() {
- if (mFullEnabled) {
+ if (getFullEnabledLocked()) {
return mBatterySaverPolicy.setPolicyLevel(BatterySaverPolicy.POLICY_LEVEL_FULL);
- } else if (mAdaptiveEnabled) {
+ } else if (getAdaptiveEnabledLocked()) {
return mBatterySaverPolicy.setPolicyLevel(BatterySaverPolicy.POLICY_LEVEL_ADAPTIVE);
} else {
return mBatterySaverPolicy.setPolicyLevel(BatterySaverPolicy.POLICY_LEVEL_OFF);
@@ -321,8 +329,8 @@ public class BatterySaverController implements BatterySaverPolicyListener {
*/
public boolean isEnabled() {
synchronized (mLock) {
- return mFullEnabled
- || (mAdaptiveEnabled && mBatterySaverPolicy.shouldAdvertiseIsEnabled());
+ return getFullEnabledLocked() || (getAdaptiveEnabledLocked()
+ && mBatterySaverPolicy.shouldAdvertiseIsEnabled());
}
}
@@ -332,19 +340,19 @@ public class BatterySaverController implements BatterySaverPolicyListener {
*/
private boolean isPolicyEnabled() {
synchronized (mLock) {
- return mFullEnabled || mAdaptiveEnabled;
+ return getFullEnabledLocked() || getAdaptiveEnabledLocked();
}
}
boolean isFullEnabled() {
synchronized (mLock) {
- return mFullEnabled;
+ return getFullEnabledLocked();
}
}
boolean isAdaptiveEnabled() {
synchronized (mLock) {
- return mAdaptiveEnabled;
+ return getAdaptiveEnabledLocked();
}
}
@@ -375,10 +383,10 @@ public class BatterySaverController implements BatterySaverPolicyListener {
}
boolean setAdaptivePolicyEnabledLocked(boolean enabled, int reason) {
- if (mAdaptiveEnabled == enabled) {
+ if (getAdaptiveEnabledLocked() == enabled) {
return false;
}
- mAdaptiveEnabled = enabled;
+ setAdaptiveEnabledLocked(enabled);
if (updatePolicyLevelLocked()) {
mHandler.postStateChanged(/*sendBroadcast=*/ true, reason);
return true;
@@ -427,19 +435,19 @@ public class BatterySaverController implements BatterySaverPolicyListener {
final ArrayMap<String, String> fileValues;
synchronized (mLock) {
- enabled = mFullEnabled || mAdaptiveEnabled;
+ enabled = getFullEnabledLocked() || getAdaptiveEnabledLocked();
EventLogTags.writeBatterySaverMode(
mFullPreviouslyEnabled ? 1 : 0, // Previously off or on.
mAdaptivePreviouslyEnabled ? 1 : 0, // Previously off or on.
- mFullEnabled ? 1 : 0, // Now off or on.
- mAdaptiveEnabled ? 1 : 0, // Now off or on.
+ getFullEnabledLocked() ? 1 : 0, // Now off or on.
+ getAdaptiveEnabledLocked() ? 1 : 0, // Now off or on.
isInteractive ? 1 : 0, // Device interactive state.
enabled ? mBatterySaverPolicy.toEventLogString() : "",
reason);
- mFullPreviouslyEnabled = mFullEnabled;
- mAdaptivePreviouslyEnabled = mAdaptiveEnabled;
+ mFullPreviouslyEnabled = getFullEnabledLocked();
+ mAdaptivePreviouslyEnabled = getAdaptiveEnabledLocked();
listeners = mListeners.toArray(new LowPowerModeListener[0]);
@@ -518,10 +526,40 @@ public class BatterySaverController implements BatterySaverPolicyListener {
return;
}
mBatterySavingStats.transitionState(
- mFullEnabled ? BatterySaverState.ON :
- (mAdaptiveEnabled ? BatterySaverState.ADAPTIVE : BatterySaverState.OFF),
- isInteractive ? InteractiveState.INTERACTIVE : InteractiveState.NON_INTERACTIVE,
- dozeMode);
+ getFullEnabledLocked() ? BatterySaverState.ON :
+ (getAdaptiveEnabledLocked() ? BatterySaverState.ADAPTIVE :
+ BatterySaverState.OFF),
+ isInteractive ? InteractiveState.INTERACTIVE :
+ InteractiveState.NON_INTERACTIVE,
+ dozeMode);
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void setFullEnabledLocked(boolean value) {
+ if (mFullEnabledRaw == value) {
+ return;
}
+ PowerManager.invalidatePowerSaveModeCaches();
+ mFullEnabledRaw = value;
+ }
+
+ /** Non-blocking getter exists as a reminder not to directly modify the cached field */
+ private boolean getFullEnabledLocked() {
+ return mFullEnabledRaw;
+ }
+
+ @GuardedBy("mLock")
+ private void setAdaptiveEnabledLocked(boolean value) {
+ if (mAdaptiveEnabledRaw == value) {
+ return;
+ }
+ PowerManager.invalidatePowerSaveModeCaches();
+ mAdaptiveEnabledRaw = value;
+ }
+
+ /** Non-blocking getter exists as a reminder not to directly modify the cached field */
+ private boolean getAdaptiveEnabledLocked() {
+ return mAdaptiveEnabledRaw;
}
}
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
index 38bdc62c5761..233417da3e00 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
@@ -219,8 +219,12 @@ public class BatterySaverPolicy extends ContentObserver {
static final int POLICY_LEVEL_ADAPTIVE = 1;
static final int POLICY_LEVEL_FULL = 2;
+ /**
+ * Do not access directly; always use {@link #setPolicyLevel}
+ * and {@link #getPolicyLevelLocked}
+ */
@GuardedBy("mLock")
- private int mPolicyLevel = POLICY_LEVEL_OFF;
+ private int mPolicyLevelRaw = POLICY_LEVEL_OFF;
private final Context mContext;
private final ContentResolver mContentResolver;
@@ -290,6 +294,11 @@ public class BatterySaverPolicy extends ContentObserver {
return R.string.config_batterySaverDeviceSpecificConfig;
}
+ @VisibleForTesting
+ void invalidatePowerSaveModeCaches() {
+ PowerManager.invalidatePowerSaveModeCaches();
+ }
+
@Override
public void onChange(boolean selfChange, Uri uri) {
refreshSettings();
@@ -373,14 +382,14 @@ public class BatterySaverPolicy extends ContentObserver {
boolean changed = false;
Policy newFullPolicy = Policy.fromSettings(setting, deviceSpecificSetting,
DEFAULT_FULL_POLICY);
- if (mPolicyLevel == POLICY_LEVEL_FULL && !mFullPolicy.equals(newFullPolicy)) {
+ if (getPolicyLevelLocked() == POLICY_LEVEL_FULL && !mFullPolicy.equals(newFullPolicy)) {
changed = true;
}
mFullPolicy = newFullPolicy;
mDefaultAdaptivePolicy = Policy.fromSettings(adaptiveSetting, adaptiveDeviceSpecificSetting,
DEFAULT_ADAPTIVE_POLICY);
- if (mPolicyLevel == POLICY_LEVEL_ADAPTIVE
+ if (getPolicyLevelLocked() == POLICY_LEVEL_ADAPTIVE
&& !mAdaptivePolicy.equals(mDefaultAdaptivePolicy)) {
changed = true;
}
@@ -882,14 +891,14 @@ public class BatterySaverPolicy extends ContentObserver {
*/
boolean setPolicyLevel(@PolicyLevel int level) {
synchronized (mLock) {
- if (mPolicyLevel == level) {
+ if (getPolicyLevelLocked() == level) {
return false;
}
switch (level) {
case POLICY_LEVEL_FULL:
case POLICY_LEVEL_ADAPTIVE:
case POLICY_LEVEL_OFF:
- mPolicyLevel = level;
+ setPolicyLevelLocked(level);
break;
default:
Slog.wtf(TAG, "setPolicyLevel invalid level given: " + level);
@@ -911,7 +920,7 @@ public class BatterySaverPolicy extends ContentObserver {
}
mAdaptivePolicy = p;
- if (mPolicyLevel == POLICY_LEVEL_ADAPTIVE) {
+ if (getPolicyLevelLocked() == POLICY_LEVEL_ADAPTIVE) {
updatePolicyDependenciesLocked();
return true;
}
@@ -924,7 +933,7 @@ public class BatterySaverPolicy extends ContentObserver {
}
private Policy getCurrentPolicyLocked() {
- switch (mPolicyLevel) {
+ switch (getPolicyLevelLocked()) {
case POLICY_LEVEL_FULL:
return mFullPolicy;
case POLICY_LEVEL_ADAPTIVE:
@@ -985,7 +994,7 @@ public class BatterySaverPolicy extends ContentObserver {
pw.println(" value: " + mAdaptiveDeviceSpecificSettings);
pw.println(" mAccessibilityEnabled=" + mAccessibilityEnabled);
- pw.println(" mPolicyLevel=" + mPolicyLevel);
+ pw.println(" mPolicyLevel=" + getPolicyLevelLocked());
dumpPolicyLocked(pw, " ", "full", mFullPolicy);
dumpPolicyLocked(pw, " ", "default adaptive", mDefaultAdaptivePolicy);
@@ -1067,4 +1076,20 @@ public class BatterySaverPolicy extends ContentObserver {
updatePolicyDependenciesLocked();
}
}
+
+ /** Non-blocking getter exists as a reminder not to modify cached fields directly */
+ @GuardedBy("mLock")
+ private int getPolicyLevelLocked() {
+ return mPolicyLevelRaw;
+ }
+
+ @GuardedBy("mLock")
+ private void setPolicyLevelLocked(int level) {
+ if (mPolicyLevelRaw == level) {
+ return;
+ }
+ // Under lock, invalidate before set ensures caches won't return stale values.
+ invalidatePowerSaveModeCaches();
+ mPolicyLevelRaw = level;
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/power/NotifierTest.java b/services/tests/servicestests/src/com/android/server/power/NotifierTest.java
index 7666ab9ed5ae..1c2d8e80ea99 100644
--- a/services/tests/servicestests/src/com/android/server/power/NotifierTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/NotifierTest.java
@@ -45,6 +45,7 @@ import com.android.internal.app.IBatteryStats;
import com.android.internal.os.BatteryStatsImpl;
import com.android.server.LocalServices;
import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.power.batterysaver.BatterySaverController;
import com.android.server.power.batterysaver.BatterySaverPolicy;
import com.android.server.power.batterysaver.BatterySavingStats;
import com.android.server.statusbar.StatusBarManagerInternal;
@@ -61,6 +62,7 @@ public class NotifierTest {
private static final String SYSTEM_PROPERTY_QUIESCENT = "ro.boot.quiescent";
private static final int USER_ID = 0;
+ @Mock private BatterySaverController mBatterySaverControllerMock;
@Mock private BatterySaverPolicy mBatterySaverPolicyMock;
@Mock private PowerManagerService.NativeWrapper mNativeWrapperMock;
@Mock private Notifier mNotifierMock;
@@ -223,6 +225,13 @@ public class NotifierTest {
}
@Override
+ BatterySaverController createBatterySaverController(
+ Object lock, Context context, BatterySaverPolicy batterySaverPolicy,
+ BatterySavingStats batterySavingStats) {
+ return mBatterySaverControllerMock;
+ }
+
+ @Override
PowerManagerService.NativeWrapper createNativeWrapper() {
return mNativeWrapperMock;
}
@@ -247,6 +256,11 @@ public class NotifierTest {
public SystemPropertiesWrapper createSystemPropertiesWrapper() {
return mSystemPropertiesMock;
}
+
+ @Override
+ void invalidateIsInteractiveCaches() {
+ // Avoids an SELinux denial.
+ }
};
private void enableChargingFeedback(boolean chargingFeedbackEnabled, boolean dndOn) {
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 811089a45758..0ee2f55fbde0 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -81,6 +81,7 @@ import com.android.server.power.PowerManagerService.BatteryReceiver;
import com.android.server.power.PowerManagerService.Injector;
import com.android.server.power.PowerManagerService.NativeWrapper;
import com.android.server.power.PowerManagerService.UserSwitchedReceiver;
+import com.android.server.power.batterysaver.BatterySaverController;
import com.android.server.power.batterysaver.BatterySaverPolicy;
import com.android.server.power.batterysaver.BatterySavingStats;
@@ -106,6 +107,7 @@ public class PowerManagerServiceTest {
private static final float BRIGHTNESS_FACTOR = 0.7f;
private static final boolean BATTERY_SAVER_ENABLED = true;
+ @Mock private BatterySaverController mBatterySaverControllerMock;
@Mock private BatterySaverPolicy mBatterySaverPolicyMock;
@Mock private LightsManager mLightsManagerMock;
@Mock private DisplayManagerInternal mDisplayManagerInternalMock;
@@ -207,6 +209,13 @@ public class PowerManagerServiceTest {
}
@Override
+ BatterySaverController createBatterySaverController(
+ Object lock, Context context, BatterySaverPolicy batterySaverPolicy,
+ BatterySavingStats batterySavingStats) {
+ return mBatterySaverControllerMock;
+ }
+
+ @Override
NativeWrapper createNativeWrapper() {
return mNativeWrapperMock;
}
@@ -231,6 +240,11 @@ public class PowerManagerServiceTest {
public SystemPropertiesWrapper createSystemPropertiesWrapper() {
return mSystemPropertiesMock;
}
+
+ @Override
+ void invalidateIsInteractiveCaches() {
+ // Avoids an SELinux failure.
+ }
});
return mService;
}
@@ -369,7 +383,7 @@ public class PowerManagerServiceTest {
@Test
public void testWakefulnessAwake_InitialValue() throws Exception {
createService();
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
}
@Test
@@ -377,12 +391,12 @@ public class PowerManagerServiceTest {
createService();
// Start with AWAKE state
startSystem();
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
// Take a nap and verify.
mService.getBinderServiceInstance().goToSleep(SystemClock.uptimeMillis(),
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
}
@Test
@@ -399,21 +413,21 @@ public class PowerManagerServiceTest {
int flags = PowerManager.FULL_WAKE_LOCK;
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
null /* workSource */, null /* historyTag */);
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
// Ensure that the flag does *NOT* work with a partial wake lock.
flags = PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
null /* workSource */, null /* historyTag */);
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
// Verify that flag forces a wakeup when paired to a FULL_WAKE_LOCK
flags = PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
null /* workSource */, null /* historyTag */);
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
}
@@ -424,7 +438,7 @@ public class PowerManagerServiceTest {
forceSleep();
mService.getBinderServiceInstance().wakeUp(SystemClock.uptimeMillis(),
PowerManager.WAKE_REASON_UNKNOWN, "testing IPowerManager.wakeUp()", "pkg.name");
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
}
/**
@@ -445,7 +459,7 @@ public class PowerManagerServiceTest {
.thenReturn(false);
mService.readConfigurationLocked();
setPluggedIn(true);
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
when(mResourcesSpy.getBoolean(com.android.internal.R.bool.config_unplugTurnsOnScreen))
.thenReturn(true);
mService.readConfigurationLocked();
@@ -460,20 +474,20 @@ public class PowerManagerServiceTest {
when(mWirelessChargerDetectorMock.update(true /* isPowered */,
BatteryManager.BATTERY_PLUGGED_WIRELESS)).thenReturn(false);
setPluggedIn(true);
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
// Test 3:
// Do not wake up if the phone is being REMOVED from a wireless charger
when(mBatteryManagerInternalMock.getPlugType()).thenReturn(0);
setPluggedIn(false);
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
// Test 4:
// Do not wake if we are dreaming.
forceAwake(); // Needs to be awake first before it can dream.
forceDream();
setPluggedIn(true);
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_DREAMING);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
forceSleep();
// Test 5:
@@ -486,7 +500,7 @@ public class PowerManagerServiceTest {
com.android.internal.R.bool.config_allowTheaterModeWakeFromUnplug))
.thenReturn(false);
setPluggedIn(false);
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
Settings.Global.putInt(
mContextSpy.getContentResolver(), Settings.Global.THEATER_MODE_ON, 0);
mUserSwitchedReceiver.onReceive(mContextSpy, new Intent(Intent.ACTION_USER_SWITCHED));
@@ -499,14 +513,14 @@ public class PowerManagerServiceTest {
forceAwake();
forceDozing();
setPluggedIn(true);
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_DOZING);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
// Test 7:
// Finally, take away all the factors above and ensure the device wakes up!
forceAwake();
forceSleep();
setPluggedIn(false);
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
}
@Test
@@ -514,12 +528,12 @@ public class PowerManagerServiceTest {
createService();
// Start with AWAKE state
startSystem();
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
// Take a nap and verify.
mService.getBinderServiceInstance().goToSleep(SystemClock.uptimeMillis(),
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0);
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_DOZING);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
}
@Test
@@ -546,12 +560,12 @@ public class PowerManagerServiceTest {
mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
// Verify that we start awake
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
// Grab the wakefulness value when PowerManager finally calls into the
// native component to actually perform the suspend.
when(mNativeWrapperMock.nativeForceSuspend()).then(inv -> {
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
return true;
});
@@ -559,7 +573,7 @@ public class PowerManagerServiceTest {
assertThat(retval).isTrue();
// Still asleep when the function returns.
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
}
@Test
@@ -592,7 +606,7 @@ public class PowerManagerServiceTest {
mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
// Verify that we start awake
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
// Create a wakelock
mService.getBinderServiceInstance().acquireWakeLock(new Binder(), flags, tag, pkg,
@@ -647,7 +661,7 @@ public class PowerManagerServiceTest {
// Start with AWAKE state
startSystem();
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
assertTrue(isAcquired[0]);
// Take a nap and verify we no longer hold the blocker
@@ -657,7 +671,7 @@ public class PowerManagerServiceTest {
when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
mService.getBinderServiceInstance().goToSleep(SystemClock.uptimeMillis(),
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0);
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_DOZING);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
assertFalse(isAcquired[0]);
// Override the display state by DreamManager and verify is reacquires the blocker.
@@ -737,7 +751,7 @@ public class PowerManagerServiceTest {
createService();
startSystem();
SystemClock.sleep(20);
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
}
@FlakyTest
@@ -757,7 +771,7 @@ public class PowerManagerServiceTest {
null /* workSource */, null /* historyTag */);
SystemClock.sleep(11);
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
}
@Test
@@ -765,7 +779,7 @@ public class PowerManagerServiceTest {
createService();
startSystem();
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
verify(mNotifierMock, never()).onWakefulnessChangeStarted(anyInt(), anyInt(), anyLong());
}
@@ -784,7 +798,7 @@ public class PowerManagerServiceTest {
createService();
startSystem();
- assertThat(mService.getWakefulness()).isEqualTo(WAKEFULNESS_ASLEEP);
+ assertThat(mService.getWakefulnessLocked()).isEqualTo(WAKEFULNESS_ASLEEP);
verify(mNotifierMock).onWakefulnessChangeStarted(eq(WAKEFULNESS_ASLEEP), anyInt(),
anyLong());
}
diff --git a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java
index 98cfc41ccfa8..30ab9cd2f875 100644
--- a/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/batterysaver/BatterySaverPolicyTest.java
@@ -78,6 +78,11 @@ public class BatterySaverPolicyTest extends AndroidTestCase {
return mDeviceSpecificConfigResId;
}
+ @Override
+ void invalidatePowerSaveModeCaches() {
+ // Avoids an SELinux denial.
+ }
+
@VisibleForTesting
void onChange() {
onChange(true, null);
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index 70e5ee71b448..683fca46923f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -209,6 +209,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
}
@Test
+ @FlakyTest(bugId = 149760957)
public void testSizeCompatBounds() {
// Disable the real configuration resolving because we only simulate partial flow.
// TODO: Have test use full flow.
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java
index 8ac1d24333be..cc9173ad12ad 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyBuilderTest.java
@@ -40,6 +40,8 @@ import static java.util.stream.Collectors.toList;
import android.platform.test.annotations.Presubmit;
import android.view.SurfaceControl;
+import androidx.test.filters.FlakyTest;
+
import org.hamcrest.CustomTypeSafeMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
@@ -65,6 +67,7 @@ public class DisplayAreaPolicyBuilderTest {
private TestWindowManagerPolicy mPolicy = new TestWindowManagerPolicy(null, null);
@Test
+ @FlakyTest(bugId = 149760939)
public void testBuilder() {
WindowManagerService wms = mSystemServices.getWindowManagerService();
DisplayArea.Root root = new SurfacelessDisplayAreaRoot(wms);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index c19312debce3..ba577454f9d5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -599,6 +599,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
}
@Test
+ @FlakyTest(bugId = 149760800)
public void layoutWindowLw_withLongEdgeDisplayCutout() {
addLongEdgeDisplayCutout();
@@ -618,6 +619,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
}
@Test
+ @FlakyTest(bugId = 149760800)
public void layoutWindowLw_withLongEdgeDisplayCutout_never() {
addLongEdgeDisplayCutout();
diff --git a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
index eda1fb8839a5..b5663bd7e26b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
+++ b/services/tests/wmtests/src/com/android/server/wm/StubTransaction.java
@@ -255,4 +255,9 @@ public class StubTransaction extends SurfaceControl.Transaction {
int priority) {
return this;
}
+
+ @Override
+ public SurfaceControl.Transaction unsetColor(SurfaceControl sc) {
+ return this;
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 8ad75053060f..55d12dbd0abb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -137,6 +137,7 @@ public class SystemServicesTestRule implements TestRule {
}
throw t;
}
+ if (throwable != null) throw throwable;
}
}
};
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRuleTest.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRuleTest.java
new file mode 100644
index 000000000000..4056c7195c9b
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRuleTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static junit.framework.Assert.assertTrue;
+
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runners.model.Statement;
+
+import java.io.IOException;
+
+@Presubmit
+public class SystemServicesTestRuleTest {
+ @Rule
+ public ExpectedException mExpectedException = ExpectedException.none();
+
+ @Test
+ public void testRule_rethrows_unchecked_exceptions() throws Throwable {
+ final SystemServicesTestRule mWmsRule = new SystemServicesTestRule();
+ Statement statement = new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ throw new RuntimeException("A failing test!");
+ }
+ };
+ mExpectedException.expect(RuntimeException.class);
+ mWmsRule.apply(statement, null /* Description*/).evaluate();
+ }
+
+ @Test
+ public void testRule_rethrows_checked_exceptions() throws Throwable {
+ final SystemServicesTestRule mWmsRule = new SystemServicesTestRule();
+ Statement statement = new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ throw new IOException("A failing test!");
+ }
+ };
+ mExpectedException.expect(IOException.class);
+ mWmsRule.apply(statement, null /* Description*/).evaluate();
+ }
+
+ @Test
+ public void testRule_ranSuccessfully() throws Throwable {
+ final boolean[] testRan = {false};
+ final SystemServicesTestRule mWmsRule = new SystemServicesTestRule();
+ Statement statement = new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ testRan[0] = true;
+ }
+ };
+ mWmsRule.apply(statement, null /* Description*/).evaluate();
+ assertTrue(testRan[0]);
+ }
+}
diff --git a/telephony/java/android/service/carrier/CarrierService.java b/telephony/java/android/service/carrier/CarrierService.java
index eefc1b70bac9..d06ec11f3e61 100644
--- a/telephony/java/android/service/carrier/CarrierService.java
+++ b/telephony/java/android/service/carrier/CarrierService.java
@@ -25,6 +25,9 @@ import android.os.ResultReceiver;
import android.telephony.TelephonyRegistryManager;
import android.util.Log;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
/**
* A service that exposes carrier-specific functionality to the system.
* <p>
@@ -156,5 +159,10 @@ public abstract class CarrierService extends Service {
result.send(RESULT_ERROR, null);
}
}
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ CarrierService.this.dump(fd, pw, args);
+ }
}
}