From 769b8638f970c6cf62abb7ac46f80211b7c3afb6 Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Mon, 4 Feb 2019 11:28:22 -0800 Subject: System gesture exclusion rects for Views Allow views to register a list of rects where the device's system UI should not intercept complex (read: down+move+up) gestures on specific sub-regions of the view. This should not be used for large-scale, full-view gesture recognition such as scrolling, but rather for specific areas such as SeekBar's scroll thumb or DrawerLayout's edge strip for swiping open a navigation drawer. Add ability for ViewTreeObserver to observe transformed exclusion rects Bug: 126360272 Test: atest android.view.cts.SystemGestureExclusionRectsTest Change-Id: If89b6f66637e40efa12955d6408f6e37b25cb46f --- graphics/java/android/graphics/RenderNode.java | 67 ++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) (limited to 'graphics/java/android') diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java index e98879d0c5bd..42b6acd3b25a 100644 --- a/graphics/java/android/graphics/RenderNode.java +++ b/graphics/java/android/graphics/RenderNode.java @@ -27,6 +27,8 @@ import android.view.RenderNodeAnimator; import android.view.Surface; import android.view.View; +import com.android.internal.util.ArrayUtils; + import dalvik.annotation.optimization.CriticalNative; import dalvik.annotation.optimization.FastNative; @@ -179,6 +181,10 @@ public final class RenderNode { private final AnimationHost mAnimationHost; private RecordingCanvas mCurrentRecordingCanvas; + // Will be null if not currently registered + @Nullable + private CompositePositionUpdateListener mCompositePositionUpdateListener; + /** * Creates a new RenderNode that can be used to record batches of * drawing operations, and store / apply render properties when drawn. @@ -248,15 +254,70 @@ public final class RenderNode { } + private static final class CompositePositionUpdateListener implements PositionUpdateListener { + private final PositionUpdateListener[] mListeners; + + CompositePositionUpdateListener(PositionUpdateListener... listeners) { + mListeners = listeners; + } + + public CompositePositionUpdateListener with(PositionUpdateListener listener) { + return new CompositePositionUpdateListener( + ArrayUtils.appendElement(PositionUpdateListener.class, mListeners, listener)); + } + + public CompositePositionUpdateListener without(PositionUpdateListener listener) { + return new CompositePositionUpdateListener( + ArrayUtils.removeElement(PositionUpdateListener.class, mListeners, listener)); + } + + @Override + public void positionChanged(long frameNumber, int left, int top, int right, int bottom) { + for (PositionUpdateListener pul : mListeners) { + pul.positionChanged(frameNumber, left, top, right, bottom); + } + } + + @Override + public void positionLost(long frameNumber) { + for (PositionUpdateListener pul : mListeners) { + pul.positionLost(frameNumber); + } + } + } + /** - * Enable callbacks for position changes. + * Enable callbacks for position changes. Call only from the UI thread or with + * external synchronization. * * @hide */ - public void requestPositionUpdates(PositionUpdateListener listener) { - nRequestPositionUpdates(mNativeRenderNode, listener); + public void addPositionUpdateListener(@NonNull PositionUpdateListener listener) { + CompositePositionUpdateListener comp = mCompositePositionUpdateListener; + if (comp == null) { + comp = new CompositePositionUpdateListener(listener); + } else { + comp = comp.with(listener); + } + mCompositePositionUpdateListener = comp; + nRequestPositionUpdates(mNativeRenderNode, comp); } + /** + * Disable a callback for position changes. Call only from the UI thread or with + * external synchronization. + * + * @param listener Callback to remove + * @hide + */ + public void removePositionUpdateListener(@NonNull PositionUpdateListener listener) { + CompositePositionUpdateListener comp = mCompositePositionUpdateListener; + if (comp != null) { + comp = comp.without(listener); + mCompositePositionUpdateListener = comp; + nRequestPositionUpdates(mNativeRenderNode, comp); + } + } /** * Starts recording a display list for the render node. All -- cgit v1.2.3-59-g8ed1b