Loading core/java/android/os/PowerManager.java +29 −0 Original line number Diff line number Diff line Loading @@ -1358,5 +1358,34 @@ public final class PowerManager { + " held=" + mHeld + ", refCount=" + mCount + "}"; } } /** * Wraps a Runnable such that this method immediately acquires the wake lock and then * once the Runnable is done the wake lock is released. * * <p>Example: * * <pre> * mHandler.post(mWakeLock.wrap(() -> { * // do things on handler, lock is held while we're waiting for this * // to get scheduled and until the runnable is done executing. * }); * </pre> * * <p>Note: you must make sure that the Runnable eventually gets executed, otherwise you'll * leak the wakelock! * * @hide */ public Runnable wrap(Runnable r) { acquire(); return () -> { try { r.run(); } finally { release(); } }; } } } core/java/android/service/dreams/DreamService.java +92 −68 Original line number Diff line number Diff line Loading @@ -192,6 +192,9 @@ public class DreamService extends Service implements Window.Callback { private boolean mDebug = false; private PowerManager.WakeLock mWakeLock; private boolean mWakeLockAcquired; public DreamService() { mSandman = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE)); } Loading Loading @@ -786,6 +789,8 @@ public class DreamService extends Service implements Window.Callback { public void onCreate() { if (mDebug) Slog.v(TAG, "onCreate()"); super.onCreate(); mWakeLock = getSystemService(PowerManager.class) .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DreamService"); } /** Loading Loading @@ -825,9 +830,21 @@ public class DreamService extends Service implements Window.Callback { @Override public final IBinder onBind(Intent intent) { if (mDebug) Slog.v(TAG, "onBind() intent = " + intent); // Need to stay awake until we dispatch onDreamingStarted. This is released either in // attach() or onDestroy(). mWakeLock.acquire(5000); mWakeLockAcquired = true; return new DreamServiceWrapper(); } private void releaseWakeLockIfNeeded() { if (mWakeLockAcquired) { mWakeLock.release(); mWakeLockAcquired = false; } } /** * Stops the dream and detaches from the window. * <p> Loading Loading @@ -904,6 +921,8 @@ public class DreamService extends Service implements Window.Callback { detach(); super.onDestroy(); releaseWakeLockIfNeeded(); // for acquire in onBind() } // end public api Loading Loading @@ -944,6 +963,7 @@ public class DreamService extends Service implements Window.Callback { * @param windowToken A window token that will allow a window to be created in the correct layer. */ private final void attach(IBinder windowToken, boolean canDoze) { try { if (mWindowToken != null) { Slog.e(TAG, "attach() called when already attached with token=" + mWindowToken); return; Loading @@ -970,8 +990,10 @@ public class DreamService extends Service implements Window.Callback { mWindow.setBackgroundDrawable(new ColorDrawable(0xFF000000)); mWindow.setFormat(PixelFormat.OPAQUE); if (mDebug) Slog.v(TAG, String.format("Attaching window token: %s to window of type %s", if (mDebug) { Slog.v(TAG, String.format("Attaching window token: %s to window of type %s", windowToken, WindowManager.LayoutParams.TYPE_DREAM)); } WindowManager.LayoutParams lp = mWindow.getAttributes(); lp.type = WindowManager.LayoutParams.TYPE_DREAM; Loading Loading @@ -1011,16 +1033,18 @@ public class DreamService extends Service implements Window.Callback { // which is posted to the handler by addView, so we post onDreamingStarted // to the handler also. Need to watch out here in case detach occurs before // this callback is invoked. mHandler.post(new Runnable() { @Override public void run() { mHandler.post(mWakeLock.wrap(() -> { if (mWindow != null || mWindowless) { if (mDebug) Slog.v(TAG, "Calling onDreamingStarted()"); if (mDebug) { Slog.v(TAG, "Calling onDreamingStarted()"); } mStarted = true; onDreamingStarted(); } })); } finally { releaseWakeLockIfNeeded(); // for acquire in onBind } }); } private boolean getWindowFlagValue(int flag, boolean defaultValue) { Loading services/core/java/com/android/server/dreams/DreamController.java +26 −7 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.content.ServiceConnection; import android.os.Binder; import android.os.Handler; import android.os.IBinder; import android.os.PowerManager; import android.os.RemoteException; import android.os.IBinder.DeathRecipient; import android.os.SystemClock; Loading Loading @@ -116,19 +117,19 @@ final class DreamController { } public void startDream(Binder token, ComponentName name, boolean isTest, boolean canDoze, int userId) { boolean isTest, boolean canDoze, int userId, PowerManager.WakeLock wakeLock) { stopDream(true /*immediate*/); Trace.traceBegin(Trace.TRACE_TAG_POWER, "startDream"); try { // Close the notification shade. Don't need to send to all, but better to be explicit. // Close the notification shade. No need to send to all, but better to be explicit. mContext.sendBroadcastAsUser(mCloseNotificationShadeIntent, UserHandle.ALL); Slog.i(TAG, "Starting dream: name=" + name + ", isTest=" + isTest + ", canDoze=" + canDoze + ", userId=" + userId); mCurrentDream = new DreamRecord(token, name, isTest, canDoze, userId); mCurrentDream = new DreamRecord(token, name, isTest, canDoze, userId, wakeLock); mDreamStartTime = SystemClock.elapsedRealtime(); MetricsLogger.visible(mContext, Loading Loading @@ -230,6 +231,7 @@ final class DreamController { if (oldDream.mBound) { mContext.unbindService(oldDream); } oldDream.releaseWakeLockIfNeeded(); try { mIWindowManager.removeWindowToken(oldDream.mToken); Loading Loading @@ -280,6 +282,7 @@ final class DreamController { public final boolean mCanDoze; public final int mUserId; public PowerManager.WakeLock mWakeLock; public boolean mBound; public boolean mConnected; public IDreamService mService; Loading @@ -288,12 +291,17 @@ final class DreamController { public boolean mWakingGently; public DreamRecord(Binder token, ComponentName name, boolean isTest, boolean canDoze, int userId) { boolean isTest, boolean canDoze, int userId, PowerManager.WakeLock wakeLock) { mToken = token; mName = name; mIsTest = isTest; mCanDoze = canDoze; mUserId = userId; mWakeLock = wakeLock; // Hold the lock while we're waiting for the service to connect. Released either when // DreamService connects (and is then responsible for keeping the device awake) or // dreaming stops. mWakeLock.acquire(); } // May be called on any thread. Loading @@ -316,14 +324,25 @@ final class DreamController { mHandler.post(new Runnable() { @Override public void run() { try { mConnected = true; if (mCurrentDream == DreamRecord.this && mService == null) { attach(IDreamService.Stub.asInterface(service)); } } finally { releaseWakeLockIfNeeded(); } } }); } private void releaseWakeLockIfNeeded() { if (mWakeLock != null) { mWakeLock.release(); mWakeLock = null; } } // May be called on any thread. @Override public void onServiceDisconnected(ComponentName name) { Loading services/core/java/com/android/server/dreams/DreamManagerService.java +4 −6 Original line number Diff line number Diff line Loading @@ -370,12 +370,10 @@ public final class DreamManagerService extends SystemService { mCurrentDreamCanDoze = canDoze; mCurrentDreamUserId = userId; mHandler.post(new Runnable() { @Override public void run() { mController.startDream(newToken, name, isTest, canDoze, userId); } }); PowerManager.WakeLock wakeLock = mPowerManager .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "startDream"); mHandler.post(wakeLock.wrap( () -> mController.startDream(newToken, name, isTest, canDoze, userId, wakeLock))); } private void stopDreamLocked(final boolean immediate) { Loading Loading
core/java/android/os/PowerManager.java +29 −0 Original line number Diff line number Diff line Loading @@ -1358,5 +1358,34 @@ public final class PowerManager { + " held=" + mHeld + ", refCount=" + mCount + "}"; } } /** * Wraps a Runnable such that this method immediately acquires the wake lock and then * once the Runnable is done the wake lock is released. * * <p>Example: * * <pre> * mHandler.post(mWakeLock.wrap(() -> { * // do things on handler, lock is held while we're waiting for this * // to get scheduled and until the runnable is done executing. * }); * </pre> * * <p>Note: you must make sure that the Runnable eventually gets executed, otherwise you'll * leak the wakelock! * * @hide */ public Runnable wrap(Runnable r) { acquire(); return () -> { try { r.run(); } finally { release(); } }; } } }
core/java/android/service/dreams/DreamService.java +92 −68 Original line number Diff line number Diff line Loading @@ -192,6 +192,9 @@ public class DreamService extends Service implements Window.Callback { private boolean mDebug = false; private PowerManager.WakeLock mWakeLock; private boolean mWakeLockAcquired; public DreamService() { mSandman = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE)); } Loading Loading @@ -786,6 +789,8 @@ public class DreamService extends Service implements Window.Callback { public void onCreate() { if (mDebug) Slog.v(TAG, "onCreate()"); super.onCreate(); mWakeLock = getSystemService(PowerManager.class) .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DreamService"); } /** Loading Loading @@ -825,9 +830,21 @@ public class DreamService extends Service implements Window.Callback { @Override public final IBinder onBind(Intent intent) { if (mDebug) Slog.v(TAG, "onBind() intent = " + intent); // Need to stay awake until we dispatch onDreamingStarted. This is released either in // attach() or onDestroy(). mWakeLock.acquire(5000); mWakeLockAcquired = true; return new DreamServiceWrapper(); } private void releaseWakeLockIfNeeded() { if (mWakeLockAcquired) { mWakeLock.release(); mWakeLockAcquired = false; } } /** * Stops the dream and detaches from the window. * <p> Loading Loading @@ -904,6 +921,8 @@ public class DreamService extends Service implements Window.Callback { detach(); super.onDestroy(); releaseWakeLockIfNeeded(); // for acquire in onBind() } // end public api Loading Loading @@ -944,6 +963,7 @@ public class DreamService extends Service implements Window.Callback { * @param windowToken A window token that will allow a window to be created in the correct layer. */ private final void attach(IBinder windowToken, boolean canDoze) { try { if (mWindowToken != null) { Slog.e(TAG, "attach() called when already attached with token=" + mWindowToken); return; Loading @@ -970,8 +990,10 @@ public class DreamService extends Service implements Window.Callback { mWindow.setBackgroundDrawable(new ColorDrawable(0xFF000000)); mWindow.setFormat(PixelFormat.OPAQUE); if (mDebug) Slog.v(TAG, String.format("Attaching window token: %s to window of type %s", if (mDebug) { Slog.v(TAG, String.format("Attaching window token: %s to window of type %s", windowToken, WindowManager.LayoutParams.TYPE_DREAM)); } WindowManager.LayoutParams lp = mWindow.getAttributes(); lp.type = WindowManager.LayoutParams.TYPE_DREAM; Loading Loading @@ -1011,16 +1033,18 @@ public class DreamService extends Service implements Window.Callback { // which is posted to the handler by addView, so we post onDreamingStarted // to the handler also. Need to watch out here in case detach occurs before // this callback is invoked. mHandler.post(new Runnable() { @Override public void run() { mHandler.post(mWakeLock.wrap(() -> { if (mWindow != null || mWindowless) { if (mDebug) Slog.v(TAG, "Calling onDreamingStarted()"); if (mDebug) { Slog.v(TAG, "Calling onDreamingStarted()"); } mStarted = true; onDreamingStarted(); } })); } finally { releaseWakeLockIfNeeded(); // for acquire in onBind } }); } private boolean getWindowFlagValue(int flag, boolean defaultValue) { Loading
services/core/java/com/android/server/dreams/DreamController.java +26 −7 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.content.ServiceConnection; import android.os.Binder; import android.os.Handler; import android.os.IBinder; import android.os.PowerManager; import android.os.RemoteException; import android.os.IBinder.DeathRecipient; import android.os.SystemClock; Loading Loading @@ -116,19 +117,19 @@ final class DreamController { } public void startDream(Binder token, ComponentName name, boolean isTest, boolean canDoze, int userId) { boolean isTest, boolean canDoze, int userId, PowerManager.WakeLock wakeLock) { stopDream(true /*immediate*/); Trace.traceBegin(Trace.TRACE_TAG_POWER, "startDream"); try { // Close the notification shade. Don't need to send to all, but better to be explicit. // Close the notification shade. No need to send to all, but better to be explicit. mContext.sendBroadcastAsUser(mCloseNotificationShadeIntent, UserHandle.ALL); Slog.i(TAG, "Starting dream: name=" + name + ", isTest=" + isTest + ", canDoze=" + canDoze + ", userId=" + userId); mCurrentDream = new DreamRecord(token, name, isTest, canDoze, userId); mCurrentDream = new DreamRecord(token, name, isTest, canDoze, userId, wakeLock); mDreamStartTime = SystemClock.elapsedRealtime(); MetricsLogger.visible(mContext, Loading Loading @@ -230,6 +231,7 @@ final class DreamController { if (oldDream.mBound) { mContext.unbindService(oldDream); } oldDream.releaseWakeLockIfNeeded(); try { mIWindowManager.removeWindowToken(oldDream.mToken); Loading Loading @@ -280,6 +282,7 @@ final class DreamController { public final boolean mCanDoze; public final int mUserId; public PowerManager.WakeLock mWakeLock; public boolean mBound; public boolean mConnected; public IDreamService mService; Loading @@ -288,12 +291,17 @@ final class DreamController { public boolean mWakingGently; public DreamRecord(Binder token, ComponentName name, boolean isTest, boolean canDoze, int userId) { boolean isTest, boolean canDoze, int userId, PowerManager.WakeLock wakeLock) { mToken = token; mName = name; mIsTest = isTest; mCanDoze = canDoze; mUserId = userId; mWakeLock = wakeLock; // Hold the lock while we're waiting for the service to connect. Released either when // DreamService connects (and is then responsible for keeping the device awake) or // dreaming stops. mWakeLock.acquire(); } // May be called on any thread. Loading @@ -316,14 +324,25 @@ final class DreamController { mHandler.post(new Runnable() { @Override public void run() { try { mConnected = true; if (mCurrentDream == DreamRecord.this && mService == null) { attach(IDreamService.Stub.asInterface(service)); } } finally { releaseWakeLockIfNeeded(); } } }); } private void releaseWakeLockIfNeeded() { if (mWakeLock != null) { mWakeLock.release(); mWakeLock = null; } } // May be called on any thread. @Override public void onServiceDisconnected(ComponentName name) { Loading
services/core/java/com/android/server/dreams/DreamManagerService.java +4 −6 Original line number Diff line number Diff line Loading @@ -370,12 +370,10 @@ public final class DreamManagerService extends SystemService { mCurrentDreamCanDoze = canDoze; mCurrentDreamUserId = userId; mHandler.post(new Runnable() { @Override public void run() { mController.startDream(newToken, name, isTest, canDoze, userId); } }); PowerManager.WakeLock wakeLock = mPowerManager .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "startDream"); mHandler.post(wakeLock.wrap( () -> mController.startDream(newToken, name, isTest, canDoze, userId, wakeLock))); } private void stopDreamLocked(final boolean immediate) { Loading