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

Commit 3c2bf54e authored by Garfield, Tan's avatar Garfield, Tan Committed by Garfield Tan
Browse files

Use pool for MotionInputEvents.

Bug: 28987543
Change-Id: I3128320a7d527fdd74ab80165b270be2e5e34476
(cherry picked from commit 2458a15aadca7902744cd7c5f3da8e0779e1e3b8)
parent e3c4e48b
Loading
Loading
Loading
Loading
+43 −6
Original line number Diff line number Diff line
@@ -16,8 +16,13 @@

package com.android.documentsui;

import static com.android.documentsui.Shared.DEBUG;

import android.graphics.Point;
import android.os.Looper;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.util.Pools;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
@@ -133,17 +138,49 @@ public final class Events {
    }

    public static final class MotionInputEvent implements InputEvent {
        private final MotionEvent mEvent;
        private final int mPosition;
        private static final String TAG = "MotionInputEvent";

        private static final Pools.SimplePool<MotionInputEvent> sPool = new Pools.SimplePool<>(1);

        private MotionEvent mEvent;
        private int mPosition;

        private MotionInputEvent() {
            if (DEBUG) Log.i(TAG, "Created a new instance.");
        }

        public static MotionInputEvent obtain(MotionEvent event, RecyclerView view) {
            // Make sure events are only used in main thread.
            assert(Looper.myLooper() == Looper.getMainLooper());

        public MotionInputEvent(MotionEvent event, RecyclerView view) {
            mEvent = event;
            MotionInputEvent instance = sPool.acquire();
            instance = (instance != null ? instance : new MotionInputEvent());

            instance.mEvent = event;

            // Consider determining position lazily as an optimization.
            View child = view.findChildViewUnder(mEvent.getX(), mEvent.getY());
            mPosition = (child!= null)
            View child = view.findChildViewUnder(event.getX(), event.getY());
            instance.mPosition = (child != null)
                    ? view.getChildAdapterPosition(child)
                    : RecyclerView.NO_POSITION;

            return instance;
        }

        public void recycle() {
            // Make sure events are only used in main thread.
            assert(Looper.myLooper() == Looper.getMainLooper());

            mEvent = null;
            mPosition = -1;

            boolean released = sPool.release(this);
            // This assert is used to guarantee we won't generate too many instances that can't be
            // held in the pool, which indicates our pool size is too small.
            //
            // Right now one instance is enough because we expect all instances are only used in
            // main thread.
            assert(released);
        }

        @Override
+12 −6
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.android.documentsui.Events.MotionInputEvent;
import com.android.documentsui.RecentsProvider.RecentColumns;
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.DurableUtils;
@@ -140,13 +141,18 @@ public class RecentsCreateFragment extends Fragment {
            new RecyclerView.OnItemTouchListener() {
                @Override
                public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                    Events.MotionInputEvent event = new Events.MotionInputEvent(e, mRecView);
                    final MotionInputEvent event = MotionInputEvent.obtain(e, mRecView);
                    try {
                        if (event.isOverItem() && event.isActionUp()) {
                            final DocumentStack stack = mAdapter.getItem(event.getItemPosition());
                            ((BaseActivity) getActivity()).onStackPicked(stack);
                            return true;
                        }

                        return false;
                    } finally {
                        event.recycle();
                    }
                }

                @Override
+12 −2
Original line number Diff line number Diff line
@@ -85,12 +85,22 @@ public class BandController extends RecyclerView.OnScrollListener {
                new RecyclerView.OnItemTouchListener() {
                    @Override
                    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                        return handleEvent(new MotionInputEvent(e, view));
                        final MotionInputEvent event = MotionInputEvent.obtain(e, view);
                        try {
                            return handleEvent(event);
                        } finally {
                            event.recycle();
                        }
                    }
                    @Override
                    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
                        if (Events.isMouseEvent(e)) {
                            processInputEvent(new MotionInputEvent(e, view));
                            final MotionInputEvent event = MotionInputEvent.obtain(e, view);
                            try {
                                processInputEvent(event);
                            } finally {
                                event.recycle();
                            }
                        }
                    }
                    @Override
+21 −12
Original line number Diff line number Diff line
@@ -1634,8 +1634,9 @@ public class DirectoryFragment extends Fragment
            // Single tap logic:
            // If the selection manager is active, it gets first whack at handling tap
            // events. Otherwise, tap events are routed to the target DocumentHolder.
            boolean handled = mSelectionManager.onSingleTapUp(
                        new MotionInputEvent(e, mRecView));
            final MotionInputEvent event = MotionInputEvent.obtain(e, mRecView);
            try {
                boolean handled = mSelectionManager.onSingleTapUp(event);

                if (handled) {
                    return handled;
@@ -1648,13 +1649,21 @@ public class DirectoryFragment extends Fragment
                }

                return handled;
            } finally {
                event.recycle();
            }
        }

        @Override
        public void onLongPress(MotionEvent e) {
            // Long-press events get routed directly to the selection manager. They can be
            // changed to route through the DocumentHolder if necessary.
            mSelectionManager.onLongPress(new MotionInputEvent(e, mRecView));
            final MotionInputEvent event = MotionInputEvent.obtain(e, mRecView);
            try {
                mSelectionManager.onLongPress(event);
            } finally {
                event.recycle();
            }
        }

        @Override