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

Commit 006f567c authored by John Spurlock's avatar John Spurlock
Browse files

Kill dreams that do not create a timely service connection.

Implement a timeout between when the dream binds and
when the dream creates the service connection.  If
the connection is not created within a certain amount of
time, stop the dream.

This fixes the current bug where a dream that crashes in
onCreate (or the ctor) can put the dream controller in a
bad state until the screen is turned off.

The timeout is equal to the service restart delay in
activity manager (ActiveServices) to avoid restarting
(and recrashing).

Bug:7596707
Change-Id: I3e11efc6af0b79ec4cb0fbc94e4e109c7602ddac
parent 9f2532bf
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -44,6 +44,9 @@ import java.util.NoSuchElementException;
final class DreamController {
    private static final String TAG = "DreamController";

    // How long we wait for a newly bound dream to create the service connection
    private static final int DREAM_CONNECTION_TIMEOUT = 5 * 1000;

    private final Context mContext;
    private final Handler mHandler;
    private final Listener mListener;
@@ -58,6 +61,16 @@ final class DreamController {

    private DreamRecord mCurrentDream;

    private final Runnable mStopUnconnectedDreamRunnable = new Runnable() {
        @Override
        public void run() {
            if (mCurrentDream != null && mCurrentDream.mBound && !mCurrentDream.mConnected) {
                Slog.w(TAG, "Bound dream did not connect in the time allotted");
                stopDream();
            }
        }
    };

    public DreamController(Context context, Handler handler, Listener listener) {
        mContext = context;
        mHandler = handler;
@@ -116,6 +129,7 @@ final class DreamController {
        }

        mCurrentDream.mBound = true;
        mHandler.postDelayed(mStopUnconnectedDreamRunnable, DREAM_CONNECTION_TIMEOUT);
    }

    public void stopDream() {
@@ -128,6 +142,8 @@ final class DreamController {
        Slog.i(TAG, "Stopping dream: name=" + oldDream.mName
                + ", isTest=" + oldDream.mIsTest + ", userId=" + oldDream.mUserId);

        mHandler.removeCallbacks(mStopUnconnectedDreamRunnable);

        if (oldDream.mSentStartBroadcast) {
            mContext.sendBroadcastAsUser(mDreamingStoppedIntent, UserHandle.ALL);
        }
@@ -200,6 +216,7 @@ final class DreamController {
        public final int mUserId;

        public boolean mBound;
        public boolean mConnected;
        public IDreamService mService;
        public boolean mSentStartBroadcast;

@@ -231,6 +248,7 @@ final class DreamController {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mConnected = true;
                    if (mCurrentDream == DreamRecord.this && mService == null) {
                        attach(IDreamService.Stub.asInterface(service));
                    }