Merge "Add WakeLock.setStateListener() API."

This commit is contained in:
Hui Yu
2022-02-01 01:01:06 +00:00
committed by Android (Google) Code Review
9 changed files with 318 additions and 62 deletions

View File

@@ -31738,9 +31738,14 @@ package android.os {
method public void release();
method public void release(int);
method public void setReferenceCounted(boolean);
method public void setStateListener(@NonNull java.util.concurrent.Executor, @Nullable android.os.PowerManager.WakeLockStateListener);
method public void setWorkSource(android.os.WorkSource);
}
public static interface PowerManager.WakeLockStateListener {
method public void onStateChanged(boolean);
}
public class Process {
ctor public Process();
method public static final long getElapsedCpuTime();

View File

@@ -128,6 +128,7 @@ filegroup {
"android/os/IThermalStatusListener.aidl",
"android/os/IThermalService.aidl",
"android/os/IPowerManager.aidl",
"android/os/IWakeLockCallback.aidl",
],
}

View File

@@ -21,15 +21,16 @@ import android.os.BatterySaverPolicyConfig;
import android.os.ParcelDuration;
import android.os.PowerSaveState;
import android.os.WorkSource;
import android.os.IWakeLockCallback;
/** @hide */
interface IPowerManager
{
void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, in WorkSource ws,
String historyTag, int displayId);
String historyTag, int displayId, IWakeLockCallback callback);
void acquireWakeLockWithUid(IBinder lock, int flags, String tag, String packageName,
int uidtoblame, int displayId);
int uidtoblame, int displayId, IWakeLockCallback callback);
@UnsupportedAppUsage
void releaseWakeLock(IBinder lock, int flags);
void updateWakeLockUids(IBinder lock, in int[] uids);
@@ -40,6 +41,7 @@ interface IPowerManager
boolean setPowerModeChecked(int mode, boolean enabled);
void updateWakeLockWorkSource(IBinder lock, in WorkSource ws, String historyTag);
void updateWakeLockCallback(IBinder lock, IWakeLockCallback callback);
boolean isWakeLockLevelSupported(int level);
void userActivity(int displayId, long time, int event, int flags);

View File

@@ -0,0 +1,24 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.os;
/**
* @hide
*/
oneway interface IWakeLockCallback {
oneway void onStateChanged(boolean enabled);
}

View File

@@ -2769,6 +2769,23 @@ public final class PowerManager {
*/
public static final int PRE_IDLE_TIMEOUT_MODE_SHORT = 2;
/**
* A listener interface to get notified when the wakelock is enabled/disabled.
*/
public interface WakeLockStateListener {
/**
* Frameworks could disable the wakelock because either device's power allowlist has
* changed, or the app's wakelock has exceeded its quota, or the app goes into cached
* state.
* <p>
* This callback is called whenever the wakelock's state has changed.
* </p>
*
* @param enabled true is enabled, false is disabled.
*/
void onStateChanged(boolean enabled);
}
/**
* A wake lock is a mechanism to indicate that your application needs
* to have the device stay on.
@@ -2800,6 +2817,8 @@ public final class PowerManager {
private String mHistoryTag;
private final String mTraceName;
private final int mDisplayId;
private WakeLockStateListener mListener;
private IWakeLockCallback mCallback;
private final Runnable mReleaser = () -> release(RELEASE_FLAG_TIMEOUT);
@@ -2890,7 +2909,7 @@ public final class PowerManager {
Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, mTraceName, 0);
try {
mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource,
mHistoryTag, mDisplayId);
mHistoryTag, mDisplayId, mCallback);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -3083,6 +3102,45 @@ public final class PowerManager {
}
};
}
/**
* Set the listener to get notified when the wakelock is enabled/disabled.
*
* @param executor {@link Executor} to handle listener callback.
* @param listener listener to be added, set the listener to null to cancel a listener.
*/
public void setStateListener(@NonNull @CallbackExecutor Executor executor,
@Nullable WakeLockStateListener listener) {
Preconditions.checkNotNull(executor, "executor cannot be null");
synchronized (mToken) {
if (listener != mListener) {
mListener = listener;
if (listener != null) {
mCallback = new IWakeLockCallback.Stub() {
public void onStateChanged(boolean enabled) {
final long token = Binder.clearCallingIdentity();
try {
executor.execute(() -> {
listener.onStateChanged(enabled);
});
} finally {
Binder.restoreCallingIdentity(token);
}
}
};
} else {
mCallback = null;
}
if (mHeld) {
try {
mService.updateWakeLockCallback(mToken, mCallback);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
}
}
}
/**

View File

@@ -33,6 +33,7 @@ import android.metrics.LogMaker;
import android.net.Uri;
import android.os.BatteryStats;
import android.os.Handler;
import android.os.IWakeLockCallback;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
@@ -215,14 +216,15 @@ public class Notifier {
* Called when a wake lock is acquired.
*/
public void onWakeLockAcquired(int flags, String tag, String packageName,
int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
IWakeLockCallback callback) {
if (DEBUG) {
Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag
+ "\", packageName=" + packageName
+ ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
+ ", workSource=" + workSource);
}
notifyWakeLockListener(callback, true);
final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
if (monitorType >= 0) {
try {
@@ -300,8 +302,9 @@ public class Notifier {
*/
public void onWakeLockChanging(int flags, String tag, String packageName,
int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
int newFlags, String newTag, String newPackageName, int newOwnerUid,
int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {
IWakeLockCallback callback, int newFlags, String newTag, String newPackageName,
int newOwnerUid, int newOwnerPid, WorkSource newWorkSource, String newHistoryTag,
IWakeLockCallback newCallback) {
final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
@@ -323,10 +326,16 @@ public class Notifier {
} catch (RemoteException ex) {
// Ignore
}
} else {
onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag);
} else if (!PowerManagerService.isSameCallback(callback, newCallback)) {
onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag,
null /* Do not notify the old callback */);
onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid,
newWorkSource, newHistoryTag);
newWorkSource, newHistoryTag, newCallback /* notify the new callback */);
} else {
onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource, historyTag,
callback);
onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid,
newWorkSource, newHistoryTag, newCallback);
}
}
@@ -334,14 +343,15 @@ public class Notifier {
* Called when a wake lock is released.
*/
public void onWakeLockReleased(int flags, String tag, String packageName,
int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
IWakeLockCallback callback) {
if (DEBUG) {
Slog.d(TAG, "onWakeLockReleased: flags=" + flags + ", tag=\"" + tag
+ "\", packageName=" + packageName
+ ", ownerUid=" + ownerUid + ", ownerPid=" + ownerPid
+ ", workSource=" + workSource);
}
notifyWakeLockListener(callback, false);
final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
if (monitorType >= 0) {
try {
@@ -859,6 +869,18 @@ public class Notifier {
return enabled && dndOff;
}
private void notifyWakeLockListener(IWakeLockCallback callback, boolean isEnabled) {
if (callback != null) {
mHandler.post(() -> {
try {
callback.onStateChanged(isEnabled);
} catch (RemoteException e) {
throw new IllegalArgumentException("Wakelock.mCallback is already dead.", e);
}
});
}
}
private final class NotifierHandler extends Handler {
public NotifierHandler(Looper looper) {

View File

@@ -66,6 +66,7 @@ import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.IBinder;
import android.os.IPowerManager;
import android.os.IWakeLockCallback;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelDuration;
@@ -1436,7 +1437,8 @@ public final class PowerManagerService extends SystemService
}
private void acquireWakeLockInternal(IBinder lock, int displayId, int flags, String tag,
String packageName, WorkSource ws, String historyTag, int uid, int pid) {
String packageName, WorkSource ws, String historyTag, int uid, int pid,
@Nullable IWakeLockCallback callback) {
synchronized (mLock) {
if (displayId != Display.INVALID_DISPLAY) {
final DisplayInfo displayInfo =
@@ -1460,11 +1462,12 @@ public final class PowerManagerService extends SystemService
boolean notifyAcquire;
if (index >= 0) {
wakeLock = mWakeLocks.get(index);
if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {
if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid, callback)) {
// Update existing wake lock. This shouldn't happen but is harmless.
notifyWakeLockChangingLocked(wakeLock, flags, tag, packageName,
uid, pid, ws, historyTag);
wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid);
uid, pid, ws, historyTag, callback);
wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid,
callback);
}
notifyAcquire = false;
} else {
@@ -1476,12 +1479,7 @@ public final class PowerManagerService extends SystemService
}
state.mNumWakeLocks++;
wakeLock = new WakeLock(lock, displayId, flags, tag, packageName, ws, historyTag,
uid, pid, state);
try {
lock.linkToDeath(wakeLock, 0);
} catch (RemoteException ex) {
throw new IllegalArgumentException("Wake lock is already dead.");
}
uid, pid, state, callback);
mWakeLocks.add(wakeLock);
setWakeLockDisabledStateLocked(wakeLock);
notifyAcquire = true;
@@ -1576,11 +1574,8 @@ public final class PowerManagerService extends SystemService
mRequestWaitForNegativeProximity = true;
}
try {
wakeLock.mLock.unlinkToDeath(wakeLock, 0);
} catch (NoSuchElementException e) {
Slog.wtf(TAG, "Failed to unlink wakelock", e);
}
wakeLock.unlinkToDeath();
wakeLock.setDisabled(true);
removeWakeLockLocked(wakeLock, index);
}
}
@@ -1650,13 +1645,41 @@ public final class PowerManagerService extends SystemService
if (!wakeLock.hasSameWorkSource(ws)) {
notifyWakeLockChangingLocked(wakeLock, wakeLock.mFlags, wakeLock.mTag,
wakeLock.mPackageName, wakeLock.mOwnerUid, wakeLock.mOwnerPid,
ws, historyTag);
ws, historyTag, null);
wakeLock.mHistoryTag = historyTag;
wakeLock.updateWorkSource(ws);
}
}
}
private void updateWakeLockCallbackInternal(IBinder lock, IWakeLockCallback callback,
int callingUid) {
synchronized (mLock) {
int index = findWakeLockIndexLocked(lock);
if (index < 0) {
if (DEBUG_SPEW) {
Slog.d(TAG, "updateWakeLockCallbackInternal: lock=" + Objects.hashCode(lock)
+ " [not found]");
}
throw new IllegalArgumentException("Wake lock not active: " + lock
+ " from uid " + callingUid);
}
WakeLock wakeLock = mWakeLocks.get(index);
if (DEBUG_SPEW) {
Slog.d(TAG, "updateWakeLockCallbackInternal: lock=" + Objects.hashCode(lock)
+ " [" + wakeLock.mTag + "]");
}
if (!isSameCallback(callback, wakeLock.mCallback)) {
notifyWakeLockChangingLocked(wakeLock, wakeLock.mFlags, wakeLock.mTag,
wakeLock.mPackageName, wakeLock.mOwnerUid, wakeLock.mOwnerPid,
wakeLock.mWorkSource, wakeLock.mHistoryTag, callback);
wakeLock.mCallback = callback;
}
}
}
@GuardedBy("mLock")
private int findWakeLockIndexLocked(IBinder lock) {
final int count = mWakeLocks.size();
@@ -1684,7 +1707,7 @@ public final class PowerManagerService extends SystemService
wakeLock.mNotifiedAcquired = true;
mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource,
wakeLock.mHistoryTag);
wakeLock.mHistoryTag, wakeLock.mCallback);
restartNofifyLongTimerLocked(wakeLock);
}
}
@@ -1726,11 +1749,13 @@ public final class PowerManagerService extends SystemService
@GuardedBy("mLock")
private void notifyWakeLockChangingLocked(WakeLock wakeLock, int flags, String tag,
String packageName, int uid, int pid, WorkSource ws, String historyTag) {
String packageName, int uid, int pid, WorkSource ws, String historyTag,
IWakeLockCallback callback) {
if (mSystemReady && wakeLock.mNotifiedAcquired) {
mNotifier.onWakeLockChanging(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource,
wakeLock.mHistoryTag, flags, tag, packageName, uid, pid, ws, historyTag);
wakeLock.mHistoryTag, wakeLock.mCallback, flags, tag, packageName, uid, pid, ws,
historyTag, callback);
notifyWakeLockLongFinishedLocked(wakeLock);
// Changing the wake lock will count as releasing the old wake lock(s) and
// acquiring the new ones... we do this because otherwise once a wakelock
@@ -1747,7 +1772,7 @@ public final class PowerManagerService extends SystemService
wakeLock.mAcquireTime = 0;
mNotifier.onWakeLockReleased(wakeLock.mFlags, wakeLock.mTag,
wakeLock.mPackageName, wakeLock.mOwnerUid, wakeLock.mOwnerPid,
wakeLock.mWorkSource, wakeLock.mHistoryTag);
wakeLock.mWorkSource, wakeLock.mHistoryTag, wakeLock.mCallback);
notifyWakeLockLongFinishedLocked(wakeLock);
}
}
@@ -4045,10 +4070,7 @@ public final class PowerManagerService extends SystemService
}
}
}
if (wakeLock.mDisabled != disabled) {
wakeLock.mDisabled = disabled;
return true;
}
return wakeLock.setDisabled(disabled);
}
return false;
}
@@ -5041,10 +5063,11 @@ public final class PowerManagerService extends SystemService
public boolean mNotifiedAcquired;
public boolean mNotifiedLong;
public boolean mDisabled;
public IWakeLockCallback mCallback;
public WakeLock(IBinder lock, int displayId, int flags, String tag, String packageName,
WorkSource workSource, String historyTag, int ownerUid, int ownerPid,
UidState uidState) {
UidState uidState, @Nullable IWakeLockCallback callback) {
mLock = lock;
mDisplayId = displayId;
mFlags = flags;
@@ -5055,15 +5078,43 @@ public final class PowerManagerService extends SystemService
mOwnerUid = ownerUid;
mOwnerPid = ownerPid;
mUidState = uidState;
mCallback = callback;
linkToDeath();
}
@Override
public void binderDied() {
unlinkToDeath();
PowerManagerService.this.handleWakeLockDeath(this);
}
private void linkToDeath() {
try {
mLock.linkToDeath(this, 0);
} catch (RemoteException e) {
throw new IllegalArgumentException("Wakelock.mLock is already dead.");
}
}
@GuardedBy("mLock")
void unlinkToDeath() {
try {
mLock.unlinkToDeath(this, 0);
} catch (NoSuchElementException e) {
Slog.wtf(TAG, "Failed to unlink Wakelock.mLock", e);
}
}
public boolean setDisabled(boolean disabled) {
if (mDisabled != disabled) {
mDisabled = disabled;
return true;
} else {
return false;
}
}
public boolean hasSameProperties(int flags, String tag, WorkSource workSource,
int ownerUid, int ownerPid) {
int ownerUid, int ownerPid, IWakeLockCallback callback) {
return mFlags == flags
&& mTag.equals(tag)
&& hasSameWorkSource(workSource)
@@ -5072,7 +5123,8 @@ public final class PowerManagerService extends SystemService
}
public void updateProperties(int flags, String tag, String packageName,
WorkSource workSource, String historyTag, int ownerUid, int ownerPid) {
WorkSource workSource, String historyTag, int ownerUid, int ownerPid,
IWakeLockCallback callback) {
if (!mPackageName.equals(packageName)) {
throw new IllegalStateException("Existing wake lock package name changed: "
+ mPackageName + " to " + packageName);
@@ -5089,6 +5141,7 @@ public final class PowerManagerService extends SystemService
mTag = tag;
updateWorkSource(workSource);
mHistoryTag = historyTag;
mCallback = callback;
}
public boolean hasSameWorkSource(WorkSource workSource) {
@@ -5307,11 +5360,12 @@ public final class PowerManagerService extends SystemService
@Override // Binder call
public void acquireWakeLockWithUid(IBinder lock, int flags, String tag,
String packageName, int uid, int displayId) {
String packageName, int uid, int displayId, IWakeLockCallback callback) {
if (uid < 0) {
uid = Binder.getCallingUid();
}
acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid), null, displayId);
acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid), null,
displayId, callback);
}
@Override // Binder call
@@ -5346,7 +5400,8 @@ public final class PowerManagerService extends SystemService
@Override // Binder call
public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,
WorkSource ws, String historyTag, int displayId) {
WorkSource ws, String historyTag, int displayId,
@Nullable IWakeLockCallback callback) {
if (lock == null) {
throw new IllegalArgumentException("lock must not be null");
}
@@ -5386,7 +5441,7 @@ public final class PowerManagerService extends SystemService
final long ident = Binder.clearCallingIdentity();
try {
acquireWakeLockInternal(lock, displayId, flags, tag, packageName, ws, historyTag,
uid, pid);
uid, pid, callback);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -5395,7 +5450,8 @@ public final class PowerManagerService extends SystemService
@Override // Binder call
public void acquireWakeLockAsync(IBinder lock, int flags, String tag, String packageName,
WorkSource ws, String historyTag) {
acquireWakeLock(lock, flags, tag, packageName, ws, historyTag, Display.INVALID_DISPLAY);
acquireWakeLock(lock, flags, tag, packageName, ws, historyTag, Display.INVALID_DISPLAY,
null);
}
@Override // Binder call
@@ -5462,6 +5518,23 @@ public final class PowerManagerService extends SystemService
}
}
@Override // Binder call
public void updateWakeLockCallback(IBinder lock, IWakeLockCallback callback) {
if (lock == null) {
throw new IllegalArgumentException("lock must not be null");
}
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
final int callingUid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
updateWakeLockCallbackInternal(lock, callback, callingUid);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
@Override // Binder call
public boolean isWakeLockLevelSupported(int level) {
final long ident = Binder.clearCallingIdentity();
@@ -6510,4 +6583,15 @@ public final class PowerManagerService extends SystemService
}
};
static boolean isSameCallback(IWakeLockCallback callback1,
IWakeLockCallback callback2) {
if (callback1 == callback2) {
return true;
}
if (callback1 != null && callback2 != null
&& callback1.asBinder() == callback2.asBinder()) {
return true;
}
return false;
}
}

View File

@@ -160,11 +160,11 @@ public class VirtualDeviceManagerServiceTest {
mDeviceImpl.onVirtualDisplayCreatedLocked(displayId);
verify(mIPowerManagerMock, never()).acquireWakeLock(any(Binder.class), anyInt(),
nullable(String.class), nullable(String.class), nullable(WorkSource.class),
nullable(String.class), anyInt());
nullable(String.class), anyInt(), eq(null));
TestableLooper.get(this).processAllMessages();
verify(mIPowerManagerMock, Mockito.times(1)).acquireWakeLock(any(Binder.class), anyInt(),
nullable(String.class), nullable(String.class), nullable(WorkSource.class),
nullable(String.class), eq(displayId));
nullable(String.class), eq(displayId), eq(null));
}
@Test
@@ -177,7 +177,7 @@ public class VirtualDeviceManagerServiceTest {
TestableLooper.get(this).processAllMessages();
verify(mIPowerManagerMock, Mockito.times(1)).acquireWakeLock(any(Binder.class), anyInt(),
nullable(String.class), nullable(String.class), nullable(WorkSource.class),
nullable(String.class), eq(displayId));
nullable(String.class), eq(displayId), eq(null));
}
@Test
@@ -196,7 +196,7 @@ public class VirtualDeviceManagerServiceTest {
verify(mIPowerManagerMock, Mockito.times(1)).acquireWakeLock(wakeLockCaptor.capture(),
anyInt(),
nullable(String.class), nullable(String.class), nullable(WorkSource.class),
nullable(String.class), eq(displayId));
nullable(String.class), eq(displayId), eq(null));
IBinder wakeLock = wakeLockCaptor.getValue();
mDeviceImpl.onVirtualDisplayRemovedLocked(displayId);
@@ -212,7 +212,7 @@ public class VirtualDeviceManagerServiceTest {
verify(mIPowerManagerMock, Mockito.times(1)).acquireWakeLock(wakeLockCaptor.capture(),
anyInt(),
nullable(String.class), nullable(String.class), nullable(WorkSource.class),
nullable(String.class), eq(displayId));
nullable(String.class), eq(displayId), eq(null));
IBinder wakeLock = wakeLockCaptor.getValue();
// Close the VirtualDevice without first notifying it of the VirtualDisplay removal.

View File

@@ -64,6 +64,7 @@ import android.os.BatterySaverPolicyConfig;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.IWakeLockCallback;
import android.os.Looper;
import android.os.PowerManager;
import android.os.PowerSaveState;
@@ -102,6 +103,7 @@ import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
@@ -479,21 +481,21 @@ public class PowerManagerServiceTest {
// First, ensure that a normal full wake lock does not cause a wakeup
int flags = PowerManager.FULL_WAKE_LOCK;
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY, null);
assertThat(mService.getGlobalWakefulnessLocked()).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 */, Display.INVALID_DISPLAY);
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY, null);
assertThat(mService.getGlobalWakefulnessLocked()).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 */, Display.INVALID_DISPLAY);
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY, null);
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
}
@@ -661,12 +663,12 @@ public class PowerManagerServiceTest {
wakelockMap.put((String) inv.getArguments()[1], (int) inv.getArguments()[0]);
return null;
}).when(mNotifierMock).onWakeLockAcquired(anyInt(), anyString(), anyString(), anyInt(),
anyInt(), any(), any());
anyInt(), any(), any(), any());
doAnswer(inv -> {
wakelockMap.remove((String) inv.getArguments()[1]);
return null;
}).when(mNotifierMock).onWakeLockReleased(anyInt(), anyString(), anyString(), anyInt(),
anyInt(), any(), any());
anyInt(), any(), any(), any());
//
// TEST STARTS HERE
@@ -679,7 +681,7 @@ public class PowerManagerServiceTest {
// Create a wakelock
mService.getBinderServiceInstance().acquireWakeLock(new Binder(), flags, tag, pkg,
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY, null);
assertThat(wakelockMap.get(tag)).isEqualTo(flags); // Verify wakelock is active.
// Confirm that the wakelocks have been disabled when the forceSuspend is in flight.
@@ -737,7 +739,7 @@ public class PowerManagerServiceTest {
// Take a nap and verify we no longer hold the blocker
int flags = PowerManager.DOZE_WAKE_LOCK;
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY, null);
when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
mService.getBinderServiceInstance().goToSleep(mClock.now(),
PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0);
@@ -893,7 +895,7 @@ public class PowerManagerServiceTest {
mService.getBinderServiceInstance().acquireWakeLock(token,
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg,
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY, null);
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
advanceTime(60);
@@ -919,7 +921,7 @@ public class PowerManagerServiceTest {
mService.getBinderServiceInstance().acquireWakeLock(token,
PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, tag, pkg,
null /* workSource */, null /* historyTag */, Display.DEFAULT_DISPLAY);
null /* workSource */, null /* historyTag */, Display.DEFAULT_DISPLAY, null);
advanceTime(1500);
mService.getBinderServiceInstance().releaseWakeLock(token, 0 /* flags */);
@@ -995,7 +997,7 @@ public class PowerManagerServiceTest {
mService.getBinderServiceInstance().acquireWakeLock(token,
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg,
null /* workSource */, null /* historyTag */, Display.DEFAULT_DISPLAY);
null /* workSource */, null /* historyTag */, Display.DEFAULT_DISPLAY, null);
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
@@ -1035,7 +1037,7 @@ public class PowerManagerServiceTest {
mService.getBinderServiceInstance().acquireWakeLock(token,
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg,
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY, null);
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
@@ -1076,7 +1078,7 @@ public class PowerManagerServiceTest {
mService.getBinderServiceInstance().acquireWakeLock(token,
PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg,
null /* workSource */, null /* historyTag */, nonDefaultDisplay);
null /* workSource */, null /* historyTag */, nonDefaultDisplay, null);
assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo(
WAKEFULNESS_AWAKE);
@@ -1640,7 +1642,65 @@ public class PowerManagerServiceTest {
IBinder token = new Binder();
String packageName = "pkg.name";
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY);
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY,
null /* callback */);
return mService.findWakeLockLocked(token);
}
/**
* Test IPowerManager.acquireWakeLock() with a IWakeLockCallback.
*/
@Test
public void testNotifyWakeLockCallback() {
createService();
startSystem();
final String tag = "wakelock1";
final String packageName = "pkg.name";
final IBinder token = new Binder();
final int flags = PowerManager.PARTIAL_WAKE_LOCK;
final IWakeLockCallback callback = Mockito.mock(IWakeLockCallback.class);
final IBinder callbackBinder = Mockito.mock(Binder.class);
when(callback.asBinder()).thenReturn(callbackBinder);
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY, callback);
verify(mNotifierMock).onWakeLockAcquired(anyInt(), eq(tag), eq(packageName), anyInt(),
anyInt(), any(), any(), same(callback));
mService.getBinderServiceInstance().releaseWakeLock(token, 0);
verify(mNotifierMock).onWakeLockReleased(anyInt(), eq(tag), eq(packageName), anyInt(),
anyInt(), any(), any(), same(callback));
}
/**
* Test IPowerManager.updateWakeLockCallback() with a new IWakeLockCallback.
*/
@Test
public void testNotifyWakeLockCallbackChange() {
createService();
startSystem();
final String tag = "wakelock1";
final String packageName = "pkg.name";
final IBinder token = new Binder();
int flags = PowerManager.PARTIAL_WAKE_LOCK;
final IWakeLockCallback callback1 = Mockito.mock(IWakeLockCallback.class);
final IBinder callbackBinder1 = Mockito.mock(Binder.class);
when(callback1.asBinder()).thenReturn(callbackBinder1);
mService.getBinderServiceInstance().acquireWakeLock(token, flags, tag, packageName,
null /* workSource */, null /* historyTag */, Display.INVALID_DISPLAY, callback1);
verify(mNotifierMock).onWakeLockAcquired(anyInt(), eq(tag), eq(packageName), anyInt(),
anyInt(), any(), any(), same(callback1));
final IWakeLockCallback callback2 = Mockito.mock(IWakeLockCallback.class);
final IBinder callbackBinder2 = Mockito.mock(Binder.class);
when(callback2.asBinder()).thenReturn(callbackBinder2);
mService.getBinderServiceInstance().updateWakeLockCallback(token, callback2);
verify(mNotifierMock).onWakeLockChanging(anyInt(), eq(tag), eq(packageName),
anyInt(), anyInt(), any(), any(), same(callback1),
anyInt(), eq(tag), eq(packageName), anyInt(), anyInt(), any(), any(),
same(callback2));
mService.getBinderServiceInstance().releaseWakeLock(token, 0);
verify(mNotifierMock).onWakeLockReleased(anyInt(), eq(tag), eq(packageName), anyInt(),
anyInt(), any(), any(), same(callback2));
}
}