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

Commit 7124390f authored by Winson Chung's avatar Winson Chung
Browse files

Fixing crash when ActivityManager does not have a proper thumbnail

- Fixing issue with hw layers ref count not properly being incremented and decremented
- Preventing message handler from keeping a strong ref to the RecentsService
parent 04dfe0d2
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ public class Constants {
            // This disables the bitmap and icon caches to
            public static final boolean DisableBackgroundCache = false;

            public static final boolean TaskDataLoader = true;
            public static final boolean TaskDataLoader = false;
            public static final boolean SystemUIHandshake = false;
            public static final boolean TimeSystemCalls = false;
            public static final boolean Memory = false;
@@ -43,7 +43,7 @@ public class Constants {
            public static final boolean TouchEvents = false;
            public static final boolean MeasureAndLayout = false;
            public static final boolean Clipping = false;
            public static final boolean HwLayers = true;
            public static final boolean HwLayers = false;
        }

        public static class TaskStack {
+17 −4
Original line number Diff line number Diff line
@@ -30,18 +30,31 @@ import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.views.TaskStackView;
import com.android.systemui.recents.views.TaskViewTransform;

import java.lang.ref.WeakReference;


/* Service */
public class RecentsService extends Service {
    // XXX: This should be getting the message from recents definition
    final static int MSG_UPDATE_RECENTS_FOR_CONFIGURATION = 0;

    class MessageHandler extends Handler {
    /** This Handler should be static to prevent holding onto a reference to the service. */
    static class MessageHandler extends Handler {
        WeakReference<Context> mContext;

        MessageHandler(Context context) {
            // Keep a weak ref to the context instead of a strong ref
            mContext = new WeakReference<Context>(context);
        }

        @Override
        public void handleMessage(Message msg) {
            Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsService|handleMessage]", msg);
            Console.log(Constants.DebugFlags.App.SystemUIHandshake,
                    "[RecentsService|handleMessage]", msg);
            if (msg.what == MSG_UPDATE_RECENTS_FOR_CONFIGURATION) {
                Context context = RecentsService.this;
                Context context = mContext.get();
                if (context == null) return;

                RecentsTaskLoader.initialize(context);
                RecentsConfiguration.reinitialize(context);

@@ -70,7 +83,7 @@ public class RecentsService extends Service {
        }
    }

    Messenger mMessenger = new Messenger(new MessageHandler());
    Messenger mMessenger = new Messenger(new MessageHandler(this));

    @Override
    public void onCreate() {
+17 −7
Original line number Diff line number Diff line
@@ -162,6 +162,7 @@ class TaskResourceLoader implements Runnable {
                                    PackageManager.GET_META_DATA);
                            Drawable icon = info.loadIcon(pm);
                            if (!mCancelled) {
                                if (icon != null) {
                                    Console.log(Constants.DebugFlags.App.TaskDataLoader,
                                            "    [TaskResourceLoader|loadIcon]",
                                            icon);
@@ -169,6 +170,7 @@ class TaskResourceLoader implements Runnable {
                                    mIconCache.put(t.key, icon);
                                }
                            }
                        }
                        // Load the thumbnail
                        if (loadThumbnail == null) {
                            ActivityManager am = (ActivityManager)
@@ -387,7 +389,11 @@ public class RecentsTaskLoader {
                    }
                    if (task.icon == null) {
                        task.icon = info.loadIcon(pm);
                        if (task.icon != null) {
                            mIconCache.put(task.key, task.icon);
                        } else {
                            task.icon = mDefaultIcon;
                        }
                    }

                    // Load the thumbnail (if possible and not the foremost task, from the cache)
@@ -398,7 +404,11 @@ public class RecentsTaskLoader {
                        Console.log(Constants.DebugFlags.App.TaskDataLoader,
                                "[RecentsTaskLoader|loadingTaskThumbnail]");
                        task.thumbnail = am.getTaskTopThumbnail(t.id);
                        if (task.thumbnail != null) {
                            mThumbnailCache.put(task.key, task.thumbnail);
                        } else {
                            task.thumbnail = mDefaultThumbnail;
                        }
                    }

                    // Create as many tasks a we want to multiply by
+4 −2
Original line number Diff line number Diff line
@@ -90,7 +90,8 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        Console.log(Constants.DebugFlags.UI.MeasureAndLayout, "[RecentsView|measure]", "width: " + width + " height: " + height, Console.AnsiGreen);
        Console.log(Constants.DebugFlags.UI.MeasureAndLayout, "[RecentsView|measure]",
                "width: " + width + " height: " + height, Console.AnsiGreen);

        // We measure our stack views sans the status bar.  It will handle the nav bar itself.
        RecentsConfiguration config = RecentsConfiguration.getInstance();
@@ -111,7 +112,8 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        Console.log(Constants.DebugFlags.UI.MeasureAndLayout, "[RecentsView|layout]", new Rect(left, top, right, bottom) + " changed: " + changed, Console.AnsiGreen);
        Console.log(Constants.DebugFlags.UI.MeasureAndLayout, "[RecentsView|layout]",
                new Rect(left, top, right, bottom) + " changed: " + changed, Console.AnsiGreen);
        // We offset our stack views by the status bar height.  It will handle the nav bar itself.
        RecentsConfiguration config = RecentsConfiguration.getInstance();
        top += config.systemInsets.top;
+38 −24
Original line number Diff line number Diff line
@@ -243,10 +243,10 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
        int newScroll = Math.max(mMinScroll, Math.min(mMaxScroll, curScroll));
        if (newScroll != curScroll) {
            // Enable hw layers on the stack
            addHwLayersRefCount();
            addHwLayersRefCount("animateBoundScroll");

            // Abort any current animations
            mScroller.abortAnimation();
            abortScroller();
            if (mScrollAnimator != null) {
                mScrollAnimator.cancel();
                mScrollAnimator.removeAllListeners();
@@ -265,7 +265,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
                @Override
                public void onAnimationEnd(Animator animation) {
                    // Disable hw layers on the stack
                    decHwLayersRefCount();
                    decHwLayersRefCount("animateBoundScroll");
                }
            });
            mScrollAnimator.start();
@@ -280,6 +280,15 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
        }
    }

    void abortScroller() {
        if (!mScroller.isFinished()) {
            // Abort the scroller
            mScroller.abortAnimation();
            // And disable hw layers on the stack
            decHwLayersRefCount("flingScroll");
        }
    }

    /** Bounds the current scroll if necessary */
    public boolean boundScroll() {
        int curScroll = getStackScroll();
@@ -319,10 +328,10 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
    }

    /** Enables the hw layers and increments the hw layer requirement ref count */
    void addHwLayersRefCount() {
    void addHwLayersRefCount(String reason) {
        Console.log(Constants.DebugFlags.UI.HwLayers,
                "[TaskStackView|addHwLayersRefCount] refCount: " +
                        mHwLayersRefCount + "->" + (mHwLayersRefCount + 1));
                        mHwLayersRefCount + "->" + (mHwLayersRefCount + 1) + " " + reason);
        if (mHwLayersRefCount == 0) {
            // Enable hw layers on each of the children
            int childCount = getChildCount();
@@ -336,10 +345,10 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal

    /** Decrements the hw layer requirement ref count and disables the hw layers when we don't
        need them anymore. */
    void decHwLayersRefCount() {
    void decHwLayersRefCount(String reason) {
        Console.log(Constants.DebugFlags.UI.HwLayers,
                "[TaskStackView|decHwLayersRefCount] refCount: " +
                        mHwLayersRefCount + "->" + (mHwLayersRefCount - 1));
                        mHwLayersRefCount + "->" + (mHwLayersRefCount - 1) + " " + reason);
        mHwLayersRefCount--;
        if (mHwLayersRefCount == 0) {
            // Disable hw layers on each of the children
@@ -362,7 +371,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal

            // If we just finished scrolling, then disable the hw layers
            if (mScroller.isFinished()) {
                decHwLayersRefCount();
                decHwLayersRefCount("finishedFlingScroll");
            }
        }
    }
@@ -775,15 +784,13 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
                mActivePointerId = ev.getPointerId(0);
                mActiveTaskView = findViewAtPoint(mLastMotionX, mLastMotionY);
                // Stop the current scroll if it is still flinging
                mSv.mScroller.abortAnimation();
                mSv.abortScroller();
                mSv.abortBoundScrollAnimation();
                // Initialize the velocity tracker
                initOrResetVelocityTracker();
                mVelocityTracker.addMovement(ev);
                // Check if the scroller is finished yet
                mIsScrolling = !mSv.mScroller.isFinished();
                // Enable HW layers
                mSv.addHwLayersRefCount();
                break;
            }
            case MotionEvent.ACTION_MOVE: {
@@ -803,6 +810,8 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
                    if (parent != null) {
                        parent.requestDisallowInterceptTouchEvent(true);
                    }
                    // Enable HW layers
                    mSv.addHwLayersRefCount("stackScroll");
                }

                mLastMotionX = x;
@@ -813,14 +822,16 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
            case MotionEvent.ACTION_UP: {
                // Animate the scroll back if we've cancelled
                mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
                // Disable HW layers
                if (mIsScrolling) {
                    mSv.decHwLayersRefCount("stackScroll");
                }
                // Reset the drag state and the velocity tracker
                mIsScrolling = false;
                mActivePointerId = INACTIVE_POINTER_ID;
                mActiveTaskView = null;
                mTotalScrollMotion = 0;
                recycleVelocityTracker();
                // Disable HW layers
                mSv.decHwLayersRefCount();
                break;
            }
        }
@@ -858,7 +869,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
                mActivePointerId = ev.getPointerId(0);
                mActiveTaskView = findViewAtPoint(mLastMotionX, mLastMotionY);
                // Stop the current scroll if it is still flinging
                mSv.mScroller.abortAnimation();
                mSv.abortScroller();
                mSv.abortBoundScrollAnimation();
                // Initialize the velocity tracker
                initOrResetVelocityTracker();
@@ -889,7 +900,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
                            parent.requestDisallowInterceptTouchEvent(true);
                        }
                        // Enable HW layers
                        mSv.addHwLayersRefCount();
                        mSv.addHwLayersRefCount("stackScroll");
                    }
                }
                if (mIsScrolling) {
@@ -914,7 +925,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
                        "scroll: " + mSv.getStackScroll() + " velocity: " + velocity,
                            Console.AnsiGreen);
                    // Enable HW layers on the stack
                    mSv.addHwLayersRefCount();
                    mSv.addHwLayersRefCount("flingScroll");
                    // Fling scroll
                    mSv.mScroller.fling(0, mSv.getStackScroll(),
                            0, -velocity,
@@ -929,27 +940,30 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
                    mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
                }

                if (mIsScrolling) {
                    // Disable HW layers
                    mSv.decHwLayersRefCount("stackScroll");
                }
                mActivePointerId = INACTIVE_POINTER_ID;
                mIsScrolling = false;
                mTotalScrollMotion = 0;
                recycleVelocityTracker();
                // Disable HW layers
                mSv.decHwLayersRefCount();
                break;
            }
            case MotionEvent.ACTION_CANCEL: {
                if (mIsScrolling) {
                    // Disable HW layers
                    mSv.decHwLayersRefCount("stackScroll");
                }
                if (mSv.isScrollOutOfBounds()) {
                    // Animate the scroll back into bounds
                    // XXX: Make this animation a function of the velocity OR distance
                    mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
                }

                mActivePointerId = INACTIVE_POINTER_ID;
                mIsScrolling = false;
                mTotalScrollMotion = 0;
                recycleVelocityTracker();
                // Disable HW layers
                mSv.decHwLayersRefCount();
                break;
            }
        }
@@ -971,7 +985,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
    @Override
    public void onBeginDrag(View v) {
        // Enable HW layers
        mSv.addHwLayersRefCount();
        mSv.addHwLayersRefCount("swipeBegin");
        // Disallow parents from intercepting touch events
        final ViewParent parent = mSv.getParent();
        if (parent != null) {
@@ -1010,7 +1024,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
        }

        // Disable HW layers
        mSv.decHwLayersRefCount();
        mSv.decHwLayersRefCount("swipeComplete");
    }

    @Override
@@ -1021,6 +1035,6 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
    @Override
    public void onDragCancelled(View v) {
        // Disable HW layers
        mSv.decHwLayersRefCount();
        mSv.decHwLayersRefCount("swipeCancelled");
    }
}