From 4845efb60d530bed74de584c0dfbbb021c71fda0 Mon Sep 17 00:00:00 2001 From: Robert Horvath Date: Fri, 12 Nov 2021 15:23:53 +0100 Subject: [PATCH] Add TestApi wakelock flag to have system acquire wakelock Allows CTS tests to test power restrictions that disable wakelocks without the system suspending (since system-wakelocks are exempt). Bug: 190822356 Test: atest LowPowerStandbyTest Change-Id: I91f44ae93480be992151d845175606fb66ecb127 --- core/api/test-current.txt | 1 + core/java/android/os/PowerManager.java | 11 +++++++++ .../android/server/powermanagerservice.proto | 2 ++ .../server/power/PowerManagerService.java | 23 +++++++++++++++++-- .../com/android/server/power/WakeLockLog.java | 7 ++++++ .../android/server/power/WakeLockLogTest.java | 19 +++++++++++++++ 6 files changed, 61 insertions(+), 2 deletions(-) diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 2303ddb8428d6..471b14885b62b 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1714,6 +1714,7 @@ package android.os { public final class PowerManager { field public static final String ACTION_ENHANCED_DISCHARGE_PREDICTION_CHANGED = "android.os.action.ENHANCED_DISCHARGE_PREDICTION_CHANGED"; + field @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public static final int SYSTEM_WAKELOCK = -2147483648; // 0x80000000 } public class Process { diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index 87e488b892120..c0d4347e68574 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -215,6 +215,17 @@ public final class PowerManager { */ public static final int UNIMPORTANT_FOR_LOGGING = 0x40000000; + /** + * Wake lock flag: This wake lock should be held by the system. + * + *

Meant to allow tests to keep the device awake even when power restrictions are active. + * + * @hide + */ + @TestApi + @RequiresPermission(android.Manifest.permission.DEVICE_POWER) + public static final int SYSTEM_WAKELOCK = 0x80000000; + /** * Flag for {@link WakeLock#release WakeLock.release(int)}: Defer releasing a * {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK} wake lock until the proximity sensor diff --git a/core/proto/android/server/powermanagerservice.proto b/core/proto/android/server/powermanagerservice.proto index cd9c978d45d4c..d48ea3b8785cd 100644 --- a/core/proto/android/server/powermanagerservice.proto +++ b/core/proto/android/server/powermanagerservice.proto @@ -211,6 +211,8 @@ message WakeLockProto { // When this wake lock is released, poke the user activity timer // so the screen stays on for a little longer. optional bool is_on_after_release = 2; + // The wakelock is held by the system server on request by another app. + optional bool system_wakelock = 3; } optional .android.os.WakeLockLevelEnum lock_level = 1; diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 2e17c18adac0f..afadda792683c 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -5155,6 +5155,8 @@ public final class PowerManagerService extends SystemService (mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP)!=0); proto.write(WakeLockProto.WakeLockFlagsProto.IS_ON_AFTER_RELEASE, (mFlags & PowerManager.ON_AFTER_RELEASE)!=0); + proto.write(WakeLockProto.WakeLockFlagsProto.SYSTEM_WAKELOCK, + (mFlags & PowerManager.SYSTEM_WAKELOCK) != 0); proto.end(wakeLockFlagsToken); proto.write(WakeLockProto.IS_DISABLED, mDisabled); @@ -5201,6 +5203,9 @@ public final class PowerManagerService extends SystemService if ((mFlags & PowerManager.ON_AFTER_RELEASE) != 0) { result += " ON_AFTER_RELEASE"; } + if ((mFlags & PowerManager.SYSTEM_WAKELOCK) != 0) { + result += " SYSTEM_WAKELOCK"; + } return result; } } @@ -5362,8 +5367,22 @@ public final class PowerManagerService extends SystemService ws = null; } - final int uid = Binder.getCallingUid(); - final int pid = Binder.getCallingPid(); + int uid = Binder.getCallingUid(); + int pid = Binder.getCallingPid(); + + if ((flags & PowerManager.SYSTEM_WAKELOCK) != 0) { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, + null); + WorkSource workSource = new WorkSource(Binder.getCallingUid(), packageName); + if (ws != null && !ws.isEmpty()) { + workSource.add(ws); + } + ws = workSource; + + uid = Process.myUid(); + pid = Process.myPid(); + } + final long ident = Binder.clearCallingIdentity(); try { acquireWakeLockInternal(lock, displayId, flags, tag, packageName, ws, historyTag, diff --git a/services/core/java/com/android/server/power/WakeLockLog.java b/services/core/java/com/android/server/power/WakeLockLog.java index 88c9850966f1b..d20c7f1fe9c6c 100644 --- a/services/core/java/com/android/server/power/WakeLockLog.java +++ b/services/core/java/com/android/server/power/WakeLockLog.java @@ -106,6 +106,7 @@ final class WakeLockLog { */ private static final int FLAG_ON_AFTER_RELEASE = 0x8; private static final int FLAG_ACQUIRE_CAUSES_WAKEUP = 0x10; + private static final int FLAG_SYSTEM_WAKELOCK = 0x20; private static final int MASK_LOWER_6_BITS = 0x3F; private static final int MASK_LOWER_7_BITS = 0x7F; @@ -296,6 +297,9 @@ final class WakeLockLog { if ((flags & PowerManager.ON_AFTER_RELEASE) != 0) { newFlags |= FLAG_ON_AFTER_RELEASE; } + if ((flags & PowerManager.SYSTEM_WAKELOCK) != 0) { + newFlags |= FLAG_SYSTEM_WAKELOCK; + } return newFlags; } @@ -455,6 +459,9 @@ final class WakeLockLog { if ((flags & FLAG_ACQUIRE_CAUSES_WAKEUP) == FLAG_ACQUIRE_CAUSES_WAKEUP) { sb.append(",acq-causes-wake"); } + if ((flags & FLAG_SYSTEM_WAKELOCK) == FLAG_SYSTEM_WAKELOCK) { + sb.append(",system-wakelock"); + } } } diff --git a/services/tests/servicestests/src/com/android/server/power/WakeLockLogTest.java b/services/tests/servicestests/src/com/android/server/power/WakeLockLogTest.java index 09612e33b98ab..a73fcb89da27d 100644 --- a/services/tests/servicestests/src/com/android/server/power/WakeLockLogTest.java +++ b/services/tests/servicestests/src/com/android/server/power/WakeLockLogTest.java @@ -211,6 +211,25 @@ public class WakeLockLogTest { dumpLog(log, false)); } + @Test + public void testAddSystemWakelock() { + final int tagDatabaseSize = 6; + final int logSize = 10; + TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize)); + WakeLockLog log = new WakeLockLog(injectorSpy); + + when(injectorSpy.currentTimeMillis()).thenReturn(1000L); + log.onWakeLockAcquired("TagPartial", 101, + PowerManager.PARTIAL_WAKE_LOCK | PowerManager.SYSTEM_WAKELOCK); + + assertEquals("Wake Lock Log\n" + + " 01-01 00:00:01.000 - 101 - ACQ TagPartial (partial,system-wakelock)\n" + + " -\n" + + " Events: 1, Time-Resets: 0\n" + + " Buffer, Bytes used: 3\n", + dumpLog(log, false)); + } + private String dumpLog(WakeLockLog log, boolean includeTagDb) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw);