Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 27eb169d authored by Adrian Roos's avatar Adrian Roos Committed by Android (Google) Code Review
Browse files

Merge "Fix wake lock logic during Dream startup" into nyc-mr1-dev

parents 824fc384 9ede1d26
Loading
Loading
Loading
Loading
+83 −96
Original line number Original line Diff line number Diff line
@@ -27,6 +27,7 @@ import android.graphics.PixelFormat;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.PowerManager;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager;
@@ -192,9 +193,6 @@ public class DreamService extends Service implements Window.Callback {


    private boolean mDebug = false;
    private boolean mDebug = false;


    private PowerManager.WakeLock mWakeLock;
    private boolean mWakeLockAcquired;

    public DreamService() {
    public DreamService() {
        mSandman = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE));
        mSandman = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE));
    }
    }
@@ -789,8 +787,6 @@ public class DreamService extends Service implements Window.Callback {
    public void onCreate() {
    public void onCreate() {
        if (mDebug) Slog.v(TAG, "onCreate()");
        if (mDebug) Slog.v(TAG, "onCreate()");
        super.onCreate();
        super.onCreate();
        mWakeLock = getSystemService(PowerManager.class)
                .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DreamService");
    }
    }


    /**
    /**
@@ -830,21 +826,9 @@ public class DreamService extends Service implements Window.Callback {
    @Override
    @Override
    public final IBinder onBind(Intent intent) {
    public final IBinder onBind(Intent intent) {
        if (mDebug) Slog.v(TAG, "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();
        return new DreamServiceWrapper();
    }
    }


    private void releaseWakeLockIfNeeded() {
        if (mWakeLockAcquired) {
            mWakeLock.release();
            mWakeLockAcquired = false;
        }
    }

    /**
    /**
     * Stops the dream and detaches from the window.
     * Stops the dream and detaches from the window.
     * <p>
     * <p>
@@ -921,8 +905,6 @@ public class DreamService extends Service implements Window.Callback {
        detach();
        detach();


        super.onDestroy();
        super.onDestroy();

        releaseWakeLockIfNeeded(); // for acquire in onBind()
    }
    }


    // end public api
    // end public api
@@ -961,9 +943,9 @@ public class DreamService extends Service implements Window.Callback {
     * Must run on mHandler.
     * Must run on mHandler.
     *
     *
     * @param windowToken A window token that will allow a window to be created in the correct layer.
     * @param windowToken A window token that will allow a window to be created in the correct layer.
     * @param started A callback that will be invoked once onDreamingStarted has completed.
     */
     */
    private final void attach(IBinder windowToken, boolean canDoze) {
    private final void attach(IBinder windowToken, boolean canDoze, IRemoteCallback started) {
        try {
        if (mWindowToken != null) {
        if (mWindowToken != null) {
            Slog.e(TAG, "attach() called when already attached with token=" + mWindowToken);
            Slog.e(TAG, "attach() called when already attached with token=" + mWindowToken);
            return;
            return;
@@ -990,10 +972,8 @@ public class DreamService extends Service implements Window.Callback {
            mWindow.setBackgroundDrawable(new ColorDrawable(0xFF000000));
            mWindow.setBackgroundDrawable(new ColorDrawable(0xFF000000));
            mWindow.setFormat(PixelFormat.OPAQUE);
            mWindow.setFormat(PixelFormat.OPAQUE);


                if (mDebug) {
            if (mDebug) Slog.v(TAG, String.format("Attaching window token: %s to window of type %s",
                    Slog.v(TAG, String.format("Attaching window token: %s to window of type %s",
                    windowToken, WindowManager.LayoutParams.TYPE_DREAM));
                    windowToken, WindowManager.LayoutParams.TYPE_DREAM));
                }


            WindowManager.LayoutParams lp = mWindow.getAttributes();
            WindowManager.LayoutParams lp = mWindow.getAttributes();
            lp.type = WindowManager.LayoutParams.TYPE_DREAM;
            lp.type = WindowManager.LayoutParams.TYPE_DREAM;
@@ -1033,19 +1013,25 @@ public class DreamService extends Service implements Window.Callback {
        // which is posted to the handler by addView, so we post onDreamingStarted
        // 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
        // to the handler also.  Need to watch out here in case detach occurs before
        // this callback is invoked.
        // this callback is invoked.
            mHandler.post(mWakeLock.wrap(() -> {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (mWindow != null || mWindowless) {
                if (mWindow != null || mWindowless) {
                    if (mDebug) {
                    if (mDebug) Slog.v(TAG, "Calling onDreamingStarted()");
                        Slog.v(TAG, "Calling onDreamingStarted()");
                    }
                    mStarted = true;
                    mStarted = true;
                    try {
                        onDreamingStarted();
                        onDreamingStarted();
                }
            }));
                    } finally {
                    } finally {
            releaseWakeLockIfNeeded(); // for acquire in onBind
                        try {
                            started.sendResult(null);
                        } catch (RemoteException e) {
                            throw e.rethrowFromSystemServer();
                        }
                        }
                    }
                    }
                }
            }
        });
    }


    private boolean getWindowFlagValue(int flag, boolean defaultValue) {
    private boolean getWindowFlagValue(int flag, boolean defaultValue) {
        return mWindow == null ? defaultValue : (mWindow.getAttributes().flags & flag) != 0;
        return mWindow == null ? defaultValue : (mWindow.getAttributes().flags & flag) != 0;
@@ -1116,11 +1102,12 @@ public class DreamService extends Service implements Window.Callback {


    private final class DreamServiceWrapper extends IDreamService.Stub {
    private final class DreamServiceWrapper extends IDreamService.Stub {
        @Override
        @Override
        public void attach(final IBinder windowToken, final boolean canDoze) {
        public void attach(final IBinder windowToken, final boolean canDoze,
                IRemoteCallback started) {
            mHandler.post(new Runnable() {
            mHandler.post(new Runnable() {
                @Override
                @Override
                public void run() {
                public void run() {
                    DreamService.this.attach(windowToken, canDoze);
                    DreamService.this.attach(windowToken, canDoze, started);
                }
                }
            });
            });
        }
        }
+3 −1
Original line number Original line Diff line number Diff line
@@ -16,11 +16,13 @@


package android.service.dreams;
package android.service.dreams;


import android.os.IRemoteCallback;

/**
/**
 * @hide
 * @hide
 */
 */
oneway interface IDreamService {
oneway interface IDreamService {
    void attach(IBinder windowToken, boolean canDoze);
    void attach(IBinder windowToken, boolean canDoze, IRemoteCallback started);
    void detach();
    void detach();
    void wakeUp();
    void wakeUp();
}
}
+7 −10
Original line number Original line Diff line number Diff line
@@ -159,9 +159,7 @@ public class DozeService extends DreamService {
        // Ask the host to get things ready to start dozing.
        // Ask the host to get things ready to start dozing.
        // Once ready, we call startDozing() at which point the CPU may suspend
        // Once ready, we call startDozing() at which point the CPU may suspend
        // and we will need to acquire a wakelock to do work.
        // and we will need to acquire a wakelock to do work.
        mHost.startDozing(new Runnable() {
        mHost.startDozing(mWakeLock.wrap(() -> {
            @Override
            public void run() {
            if (mDreaming) {
            if (mDreaming) {
                startDozing();
                startDozing();


@@ -169,8 +167,7 @@ public class DozeService extends DreamService {
                // wakelock whenever we are doing work.  Note that we never call
                // wakelock whenever we are doing work.  Note that we never call
                // stopDozing because can we just keep dozing until the bitter end.
                // stopDozing because can we just keep dozing until the bitter end.
            }
            }
            }
        }));
        });
    }
    }


    @Override
    @Override
+30 −17
Original line number Original line Diff line number Diff line
@@ -24,8 +24,10 @@ import android.content.Context;
import android.content.Intent;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.PowerManager;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.RemoteException;
import android.os.IBinder.DeathRecipient;
import android.os.IBinder.DeathRecipient;
@@ -253,7 +255,8 @@ final class DreamController {
    private void attach(IDreamService service) {
    private void attach(IDreamService service) {
        try {
        try {
            service.asBinder().linkToDeath(mCurrentDream, 0);
            service.asBinder().linkToDeath(mCurrentDream, 0);
            service.attach(mCurrentDream.mToken, mCurrentDream.mCanDoze);
            service.attach(mCurrentDream.mToken, mCurrentDream.mCanDoze,
                    mCurrentDream.mDreamingStartedCallback);
        } catch (RemoteException ex) {
        } catch (RemoteException ex) {
            Slog.e(TAG, "The dream service died unexpectedly.", ex);
            Slog.e(TAG, "The dream service died unexpectedly.", ex);
            stopDream(true /*immediate*/);
            stopDream(true /*immediate*/);
@@ -298,10 +301,10 @@ final class DreamController {
            mCanDoze = canDoze;
            mCanDoze = canDoze;
            mUserId  = userId;
            mUserId  = userId;
            mWakeLock = wakeLock;
            mWakeLock = wakeLock;
            // Hold the lock while we're waiting for the service to connect. Released either when
            // Hold the lock while we're waiting for the service to connect and start dreaming.
            // DreamService connects (and is then responsible for keeping the device awake) or
            // Released after the service has started dreaming, we stop dreaming, or it timed out.
            // dreaming stops.
            mWakeLock.acquire();
            mWakeLock.acquire();
            mHandler.postDelayed(mReleaseWakeLockIfNeeded, 10000);
        }
        }


        // May be called on any thread.
        // May be called on any thread.
@@ -324,25 +327,17 @@ final class DreamController {
            mHandler.post(new Runnable() {
            mHandler.post(new Runnable() {
                @Override
                @Override
                public void run() {
                public void run() {
                    try {
                    mConnected = true;
                    mConnected = true;
                    if (mCurrentDream == DreamRecord.this && mService == null) {
                    if (mCurrentDream == DreamRecord.this && mService == null) {
                        attach(IDreamService.Stub.asInterface(service));
                        attach(IDreamService.Stub.asInterface(service));
                        }
                        // Wake lock will be released once dreaming starts.
                    } finally {
                    } else {
                        releaseWakeLockIfNeeded();
                        releaseWakeLockIfNeeded();
                    }
                    }
                }
                }
            });
            });
        }
        }


        private void releaseWakeLockIfNeeded() {
            if (mWakeLock != null) {
                mWakeLock.release();
                mWakeLock = null;
            }
        }

        // May be called on any thread.
        // May be called on any thread.
        @Override
        @Override
        public void onServiceDisconnected(ComponentName name) {
        public void onServiceDisconnected(ComponentName name) {
@@ -356,5 +351,23 @@ final class DreamController {
                }
                }
            });
            });
        }
        }

        void releaseWakeLockIfNeeded() {
            if (mWakeLock != null) {
                mWakeLock.release();
                mWakeLock = null;
                mHandler.removeCallbacks(mReleaseWakeLockIfNeeded);
            }
        }

        final Runnable mReleaseWakeLockIfNeeded = this::releaseWakeLockIfNeeded;

        final IRemoteCallback mDreamingStartedCallback = new IRemoteCallback.Stub() {
            // May be called on any thread.
            @Override
            public void sendResult(Bundle data) throws RemoteException {
                mHandler.post(mReleaseWakeLockIfNeeded);
            }
        };
    }
    }
}
}
 No newline at end of file