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
This commit is contained in:
Robert Horvath
2021-11-12 15:23:53 +01:00
parent 287a3a7b94
commit 4845efb60d
6 changed files with 61 additions and 2 deletions

View File

@@ -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 {

View File

@@ -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.
*
* <p>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

View File

@@ -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;

View File

@@ -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,

View File

@@ -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");
}
}
}

View File

@@ -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);