Merge "Add WakeLock.setStateListener() API."
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -128,6 +128,7 @@ filegroup {
|
||||
"android/os/IThermalStatusListener.aidl",
|
||||
"android/os/IThermalService.aidl",
|
||||
"android/os/IPowerManager.aidl",
|
||||
"android/os/IWakeLockCallback.aidl",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
24
core/java/android/os/IWakeLockCallback.aidl
Normal file
24
core/java/android/os/IWakeLockCallback.aidl
Normal 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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user