diff options
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); + } } } |