diff options
Diffstat (limited to 'quickstep/src/com/android/quickstep/MotionEventQueue.java')
-rw-r--r-- | quickstep/src/com/android/quickstep/MotionEventQueue.java | 85 |
1 files changed, 69 insertions, 16 deletions
diff --git a/quickstep/src/com/android/quickstep/MotionEventQueue.java b/quickstep/src/com/android/quickstep/MotionEventQueue.java index e3c3a1b89..fae9b66a2 100644 --- a/quickstep/src/com/android/quickstep/MotionEventQueue.java +++ b/quickstep/src/com/android/quickstep/MotionEventQueue.java @@ -18,6 +18,8 @@ package com.android.quickstep; import static android.view.MotionEvent.ACTION_CANCEL; import static android.view.MotionEvent.ACTION_MOVE; +import android.annotation.TargetApi; +import android.os.Build; import android.view.Choreographer; import android.view.MotionEvent; @@ -29,25 +31,64 @@ import java.util.function.Consumer; /** * Helper class for batching input events */ -public class MotionEventQueue implements Runnable { +@TargetApi(Build.VERSION_CODES.O) +public class MotionEventQueue { + + private final EventArray mEmptyArray = new EventArray(); + private final Object mExecutionLock = new Object(); // We use two arrays and swap the current index when one array is being consumed private final EventArray[] mArrays = new EventArray[] {new EventArray(), new EventArray()}; private int mCurrentIndex = 0; - private final Choreographer mChoreographer; - private final Consumer<MotionEvent> mConsumer; + private final Runnable mMainFrameCallback = this::frameCallbackForMainChoreographer; + private final Runnable mInterimFrameCallback = this::frameCallbackForInterimChoreographer; + + private final Choreographer mMainChoreographer; + + private Consumer<MotionEvent> mConsumer; + + private Choreographer mInterimChoreographer; + private Choreographer mCurrentChoreographer; + + private Runnable mCurrentRunnable; public MotionEventQueue(Choreographer choreographer, Consumer<MotionEvent> consumer) { - mChoreographer = choreographer; + mMainChoreographer = choreographer; mConsumer = consumer; + + mCurrentChoreographer = mMainChoreographer; + mCurrentRunnable = mMainFrameCallback; + } + + public void setConsumer(Consumer<MotionEvent> consumer) { + synchronized (mExecutionLock) { + mConsumer = consumer; + } + } + + public void setInterimChoreographer(Choreographer choreographer) { + synchronized (mExecutionLock) { + synchronized (mArrays) { + mInterimChoreographer = choreographer; + if (choreographer == null) { + mCurrentChoreographer = mMainChoreographer; + mCurrentRunnable = mMainFrameCallback; + } else { + mCurrentChoreographer = mInterimChoreographer; + mCurrentRunnable = mInterimFrameCallback; + } + + ChoreographerCompat.postInputFrame(mCurrentChoreographer, mCurrentRunnable); + } + } } public void queue(MotionEvent event) { synchronized (mArrays) { EventArray array = mArrays[mCurrentIndex]; if (array.isEmpty()) { - ChoreographerCompat.postInputFrame(mChoreographer, this); + ChoreographerCompat.postInputFrame(mCurrentChoreographer, mCurrentRunnable); } int eventAction = event.getAction(); @@ -61,21 +102,33 @@ public class MotionEventQueue implements Runnable { } } - @Override - public void run() { - EventArray array = swapAndGetCurrentArray(); - int size = array.size(); - for (int i = 0; i < size; i++) { - MotionEvent event = array.get(i); - mConsumer.accept(event); - event.recycle(); + private void frameCallbackForMainChoreographer() { + runFor(mMainChoreographer); + } + + private void frameCallbackForInterimChoreographer() { + runFor(mInterimChoreographer); + } + + private void runFor(Choreographer caller) { + synchronized (mExecutionLock) { + EventArray array = swapAndGetCurrentArray(caller); + int size = array.size(); + for (int i = 0; i < size; i++) { + MotionEvent event = array.get(i); + mConsumer.accept(event); + event.recycle(); + } + array.clear(); + array.lastEventAction = ACTION_CANCEL; } - array.clear(); - array.lastEventAction = ACTION_CANCEL; } - private EventArray swapAndGetCurrentArray() { + private EventArray swapAndGetCurrentArray(Choreographer caller) { synchronized (mArrays) { + if (caller != mCurrentChoreographer) { + return mEmptyArray; + } EventArray current = mArrays[mCurrentIndex]; mCurrentIndex = mCurrentIndex ^ 1; return current; |