Loading api/current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -50502,6 +50502,7 @@ package android.view { method public android.animation.StateListAnimator getStateListAnimator(); method protected int getSuggestedMinimumHeight(); method protected int getSuggestedMinimumWidth(); method @NonNull public java.util.List<android.graphics.Rect> getSystemGestureExclusionRects(); method public int getSystemUiVisibility(); method @android.view.ViewDebug.ExportedProperty public Object getTag(); method public Object getTag(int); Loading Loading @@ -50840,6 +50841,7 @@ package android.view { method public void setSelected(boolean); method public void setSoundEffectsEnabled(boolean); method public void setStateListAnimator(android.animation.StateListAnimator); method public void setSystemGestureExclusionRects(@NonNull java.util.List<android.graphics.Rect>); method public void setSystemUiVisibility(int); method public void setTag(Object); method public void setTag(int, Object); Loading Loading @@ -51668,6 +51670,7 @@ package android.view { method public void addOnGlobalLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener); method public void addOnPreDrawListener(android.view.ViewTreeObserver.OnPreDrawListener); method public void addOnScrollChangedListener(android.view.ViewTreeObserver.OnScrollChangedListener); method public void addOnSystemGestureExclusionRectsChangedListener(java.util.function.Consumer<java.util.List<android.graphics.Rect>>); method public void addOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener); method public void addOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener); method public void addOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener); Loading @@ -51682,6 +51685,7 @@ package android.view { method public void removeOnGlobalLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener); method public void removeOnPreDrawListener(android.view.ViewTreeObserver.OnPreDrawListener); method public void removeOnScrollChangedListener(android.view.ViewTreeObserver.OnScrollChangedListener); method public void removeOnSystemGestureExclusionRectsChangedListener(java.util.function.Consumer<java.util.List<android.graphics.Rect>>); method public void removeOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener); method public void removeOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener); method public void removeOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener); core/java/android/view/GestureExclusionTracker.java 0 → 100644 +125 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.view; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Rect; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; /** * Used by {@link ViewRootImpl} to track system gesture exclusion rects reported by views. */ class GestureExclusionTracker { private boolean mGestureExclusionViewsChanged = false; private List<GestureExclusionViewInfo> mGestureExclusionViewInfos = new ArrayList<>(); private List<Rect> mGestureExclusionRects = Collections.emptyList(); public void updateRectsForView(@NonNull View view) { boolean found = false; final Iterator<GestureExclusionViewInfo> i = mGestureExclusionViewInfos.iterator(); while (i.hasNext()) { final GestureExclusionViewInfo info = i.next(); final View v = info.getView(); if (v == null || !v.isAttachedToWindow()) { mGestureExclusionViewsChanged = true; i.remove(); continue; } if (v == view) { found = true; info.mDirty = true; break; } } if (!found && view.isAttachedToWindow()) { mGestureExclusionViewInfos.add(new GestureExclusionViewInfo(view)); mGestureExclusionViewsChanged = true; } } @Nullable public List<Rect> computeChangedRects() { boolean changed = false; final Iterator<GestureExclusionViewInfo> i = mGestureExclusionViewInfos.iterator(); final List<Rect> rects = new ArrayList<>(); while (i.hasNext()) { final GestureExclusionViewInfo info = i.next(); switch (info.update()) { case GestureExclusionViewInfo.CHANGED: changed = true; // Deliberate fall-through case GestureExclusionViewInfo.UNCHANGED: rects.addAll(info.mExclusionRects); break; case GestureExclusionViewInfo.GONE: mGestureExclusionViewsChanged = true; i.remove(); break; } } if (changed || mGestureExclusionViewsChanged) { mGestureExclusionViewsChanged = false; if (!mGestureExclusionRects.equals(rects)) { mGestureExclusionRects = rects; return rects; } } return null; } private static class GestureExclusionViewInfo { public static final int CHANGED = 0; public static final int UNCHANGED = 1; public static final int GONE = 2; private final WeakReference<View> mView; boolean mDirty = true; List<Rect> mExclusionRects = Collections.emptyList(); GestureExclusionViewInfo(View view) { mView = new WeakReference<>(view); } public View getView() { return mView.get(); } public int update() { final View excludedView = getView(); if (excludedView == null || !excludedView.isAttachedToWindow()) return GONE; final List<Rect> localRects = excludedView.getSystemGestureExclusionRects(); final List<Rect> newRects = new ArrayList<>(localRects.size()); for (Rect src : localRects) { Rect mappedRect = new Rect(src); ViewParent p = excludedView.getParent(); if (p != null && p.getChildVisibleRect(excludedView, mappedRect, null)) { newRects.add(mappedRect); } } if (mExclusionRects.equals(localRects)) return UNCHANGED; mExclusionRects = newRects; return CHANGED; } } } core/java/android/view/SurfaceView.java +1 −1 Original line number Diff line number Diff line Loading @@ -210,7 +210,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); mRenderNode.requestPositionUpdates(mPositionListener); mRenderNode.addPositionUpdateListener(mPositionListener); setWillNotDraw(true); } Loading core/java/android/view/View.java +99 −0 Original line number Diff line number Diff line Loading @@ -4597,6 +4597,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private ArrayList<OnUnhandledKeyEventListener> mUnhandledKeyListeners; private WindowInsetsAnimationListener mWindowInsetsAnimationListener; /** * This lives here since it's only valid for interactive views. */ private List<Rect> mSystemGestureExclusionRects; /** * Used to track {@link #mSystemGestureExclusionRects} */ public RenderNode.PositionUpdateListener mPositionUpdateListener; } @UnsupportedAppUsage Loading Loading @@ -10962,6 +10972,95 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } /** * Sets a list of areas within this view's post-layout coordinate space where the system * should not intercept touch or other pointing device gestures. <em>This method should * be called by {@link #onLayout(boolean, int, int, int, int)} or {@link #onDraw(Canvas)}.</em> * * <p>Use this to tell the system which specific sub-areas of a view need to receive gesture * input in order to function correctly in the presence of global system gestures that may * conflict. For example, if the system wishes to capture swipe-in-from-screen-edge gestures * to provide system-level navigation functionality, a view such as a navigation drawer * container can mark the left (or starting) edge of itself as requiring gesture capture * priority using this API. The system may then choose to relax its own gesture recognition * to allow the app to consume the user's gesture. It is not necessary for an app to register * exclusion rects for broadly spanning regions such as the entirety of a * <code>ScrollView</code> or for simple press and release click targets such as * <code>Button</code>. Mark an exclusion rect when interacting with a view requires * a precision touch gesture in a small area in either the X or Y dimension, such as * an edge swipe or dragging a <code>SeekBar</code> thumb.</p> * * <p>Do not modify the provided list after this method is called.</p> * * @param rects A list of precision gesture regions that this view needs to function correctly */ public void setSystemGestureExclusionRects(@NonNull List<Rect> rects) { if (rects.isEmpty() && mListenerInfo == null) return; final ListenerInfo info = getListenerInfo(); if (rects.isEmpty()) { info.mSystemGestureExclusionRects = null; if (info.mPositionUpdateListener != null) { mRenderNode.removePositionUpdateListener(info.mPositionUpdateListener); } } else { info.mSystemGestureExclusionRects = rects; if (info.mPositionUpdateListener == null) { info.mPositionUpdateListener = new RenderNode.PositionUpdateListener() { @Override public void positionChanged(long n, int l, int t, int r, int b) { postUpdateSystemGestureExclusionRects(); } @Override public void positionLost(long frameNumber) { postUpdateSystemGestureExclusionRects(); } }; mRenderNode.addPositionUpdateListener(info.mPositionUpdateListener); } } postUpdateSystemGestureExclusionRects(); } /** * WARNING: this can be called by a hwui worker thread, not just the UI thread! */ void postUpdateSystemGestureExclusionRects() { // Potentially racey from a background thread. It's ok if it's not perfect. final Handler h = getHandler(); if (h != null) { h.postAtFrontOfQueue(this::updateSystemGestureExclusionRects); } } void updateSystemGestureExclusionRects() { final AttachInfo ai = mAttachInfo; if (ai != null) { ai.mViewRootImpl.updateSystemGestureExclusionRectsForView(this); } } /** * Retrieve the list of areas within this view's post-layout coordinate space where the system * should not intercept touch or other pointing device gestures. * * <p>Do not modify the returned list.</p> * * @return the list set by {@link #setSystemGestureExclusionRects(List)} */ @NonNull public List<Rect> getSystemGestureExclusionRects() { final ListenerInfo info = mListenerInfo; if (info != null) { final List<Rect> list = info.mSystemGestureExclusionRects; if (list != null) { return list; } } return Collections.emptyList(); } /** * Compute the view's coordinate within the surface. * core/java/android/view/ViewRootImpl.java +53 −29 Original line number Diff line number Diff line Loading @@ -605,6 +605,8 @@ public final class ViewRootImpl implements ViewParent, private final InsetsController mInsetsController = new InsetsController(this); private final GestureExclusionTracker mGestureExclusionTracker = new GestureExclusionTracker(); static final class SystemUiVisibilityInfo { int seq; int globalVisibility; Loading Loading @@ -3977,6 +3979,20 @@ public final class ViewRootImpl implements ViewParent, return mAttachInfo.mAccessibilityFocusDrawable; } void updateSystemGestureExclusionRectsForView(View view) { mGestureExclusionTracker.updateRectsForView(view); mHandler.sendEmptyMessage(MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED); } void systemGestureExclusionChanged() { final List<Rect> rectsForWindowManager = mGestureExclusionTracker.computeChangedRects(); if (rectsForWindowManager != null) { // TODO Send to WM mAttachInfo.mTreeObserver .dispatchOnSystemGestureExclusionRectsChanged(rectsForWindowManager); } } /** * Requests that the root render node is invalidated next time we perform a draw, such that * {@link WindowCallbacks#onPostDraw} gets called. Loading Loading @@ -4433,35 +4449,36 @@ public final class ViewRootImpl implements ViewParent, } } private final static int MSG_INVALIDATE = 1; private final static int MSG_INVALIDATE_RECT = 2; private final static int MSG_DIE = 3; private final static int MSG_RESIZED = 4; private final static int MSG_RESIZED_REPORT = 5; private final static int MSG_WINDOW_FOCUS_CHANGED = 6; private final static int MSG_DISPATCH_INPUT_EVENT = 7; private final static int MSG_DISPATCH_APP_VISIBILITY = 8; private final static int MSG_DISPATCH_GET_NEW_SURFACE = 9; private final static int MSG_DISPATCH_KEY_FROM_IME = 11; private final static int MSG_DISPATCH_KEY_FROM_AUTOFILL = 12; private final static int MSG_CHECK_FOCUS = 13; private final static int MSG_CLOSE_SYSTEM_DIALOGS = 14; private final static int MSG_DISPATCH_DRAG_EVENT = 15; private final static int MSG_DISPATCH_DRAG_LOCATION_EVENT = 16; private final static int MSG_DISPATCH_SYSTEM_UI_VISIBILITY = 17; private final static int MSG_UPDATE_CONFIGURATION = 18; private final static int MSG_PROCESS_INPUT_EVENTS = 19; private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 21; private final static int MSG_INVALIDATE_WORLD = 22; private final static int MSG_WINDOW_MOVED = 23; private final static int MSG_SYNTHESIZE_INPUT_EVENT = 24; private final static int MSG_DISPATCH_WINDOW_SHOWN = 25; private final static int MSG_REQUEST_KEYBOARD_SHORTCUTS = 26; private final static int MSG_UPDATE_POINTER_ICON = 27; private final static int MSG_POINTER_CAPTURE_CHANGED = 28; private final static int MSG_DRAW_FINISHED = 29; private final static int MSG_INSETS_CHANGED = 30; private final static int MSG_INSETS_CONTROL_CHANGED = 31; private static final int MSG_INVALIDATE = 1; private static final int MSG_INVALIDATE_RECT = 2; private static final int MSG_DIE = 3; private static final int MSG_RESIZED = 4; private static final int MSG_RESIZED_REPORT = 5; private static final int MSG_WINDOW_FOCUS_CHANGED = 6; private static final int MSG_DISPATCH_INPUT_EVENT = 7; private static final int MSG_DISPATCH_APP_VISIBILITY = 8; private static final int MSG_DISPATCH_GET_NEW_SURFACE = 9; private static final int MSG_DISPATCH_KEY_FROM_IME = 11; private static final int MSG_DISPATCH_KEY_FROM_AUTOFILL = 12; private static final int MSG_CHECK_FOCUS = 13; private static final int MSG_CLOSE_SYSTEM_DIALOGS = 14; private static final int MSG_DISPATCH_DRAG_EVENT = 15; private static final int MSG_DISPATCH_DRAG_LOCATION_EVENT = 16; private static final int MSG_DISPATCH_SYSTEM_UI_VISIBILITY = 17; private static final int MSG_UPDATE_CONFIGURATION = 18; private static final int MSG_PROCESS_INPUT_EVENTS = 19; private static final int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 21; private static final int MSG_INVALIDATE_WORLD = 22; private static final int MSG_WINDOW_MOVED = 23; private static final int MSG_SYNTHESIZE_INPUT_EVENT = 24; private static final int MSG_DISPATCH_WINDOW_SHOWN = 25; private static final int MSG_REQUEST_KEYBOARD_SHORTCUTS = 26; private static final int MSG_UPDATE_POINTER_ICON = 27; private static final int MSG_POINTER_CAPTURE_CHANGED = 28; private static final int MSG_DRAW_FINISHED = 29; private static final int MSG_INSETS_CHANGED = 30; private static final int MSG_INSETS_CONTROL_CHANGED = 31; private static final int MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED = 32; final class ViewRootHandler extends Handler { @Override Loading Loading @@ -4519,6 +4536,10 @@ public final class ViewRootImpl implements ViewParent, return "MSG_DRAW_FINISHED"; case MSG_INSETS_CHANGED: return "MSG_INSETS_CHANGED"; case MSG_INSETS_CONTROL_CHANGED: return "MSG_INSETS_CONTROL_CHANGED"; case MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED: return "MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED"; } return super.getMessageName(message); } Loading Loading @@ -4750,6 +4771,9 @@ public final class ViewRootImpl implements ViewParent, case MSG_DRAW_FINISHED: { pendingDrawFinished(); } break; case MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED: { systemGestureExclusionChanged(); } break; } } } Loading Loading
api/current.txt +4 −0 Original line number Diff line number Diff line Loading @@ -50502,6 +50502,7 @@ package android.view { method public android.animation.StateListAnimator getStateListAnimator(); method protected int getSuggestedMinimumHeight(); method protected int getSuggestedMinimumWidth(); method @NonNull public java.util.List<android.graphics.Rect> getSystemGestureExclusionRects(); method public int getSystemUiVisibility(); method @android.view.ViewDebug.ExportedProperty public Object getTag(); method public Object getTag(int); Loading Loading @@ -50840,6 +50841,7 @@ package android.view { method public void setSelected(boolean); method public void setSoundEffectsEnabled(boolean); method public void setStateListAnimator(android.animation.StateListAnimator); method public void setSystemGestureExclusionRects(@NonNull java.util.List<android.graphics.Rect>); method public void setSystemUiVisibility(int); method public void setTag(Object); method public void setTag(int, Object); Loading Loading @@ -51668,6 +51670,7 @@ package android.view { method public void addOnGlobalLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener); method public void addOnPreDrawListener(android.view.ViewTreeObserver.OnPreDrawListener); method public void addOnScrollChangedListener(android.view.ViewTreeObserver.OnScrollChangedListener); method public void addOnSystemGestureExclusionRectsChangedListener(java.util.function.Consumer<java.util.List<android.graphics.Rect>>); method public void addOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener); method public void addOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener); method public void addOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener); Loading @@ -51682,6 +51685,7 @@ package android.view { method public void removeOnGlobalLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener); method public void removeOnPreDrawListener(android.view.ViewTreeObserver.OnPreDrawListener); method public void removeOnScrollChangedListener(android.view.ViewTreeObserver.OnScrollChangedListener); method public void removeOnSystemGestureExclusionRectsChangedListener(java.util.function.Consumer<java.util.List<android.graphics.Rect>>); method public void removeOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener); method public void removeOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener); method public void removeOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener);
core/java/android/view/GestureExclusionTracker.java 0 → 100644 +125 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.view; import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Rect; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; /** * Used by {@link ViewRootImpl} to track system gesture exclusion rects reported by views. */ class GestureExclusionTracker { private boolean mGestureExclusionViewsChanged = false; private List<GestureExclusionViewInfo> mGestureExclusionViewInfos = new ArrayList<>(); private List<Rect> mGestureExclusionRects = Collections.emptyList(); public void updateRectsForView(@NonNull View view) { boolean found = false; final Iterator<GestureExclusionViewInfo> i = mGestureExclusionViewInfos.iterator(); while (i.hasNext()) { final GestureExclusionViewInfo info = i.next(); final View v = info.getView(); if (v == null || !v.isAttachedToWindow()) { mGestureExclusionViewsChanged = true; i.remove(); continue; } if (v == view) { found = true; info.mDirty = true; break; } } if (!found && view.isAttachedToWindow()) { mGestureExclusionViewInfos.add(new GestureExclusionViewInfo(view)); mGestureExclusionViewsChanged = true; } } @Nullable public List<Rect> computeChangedRects() { boolean changed = false; final Iterator<GestureExclusionViewInfo> i = mGestureExclusionViewInfos.iterator(); final List<Rect> rects = new ArrayList<>(); while (i.hasNext()) { final GestureExclusionViewInfo info = i.next(); switch (info.update()) { case GestureExclusionViewInfo.CHANGED: changed = true; // Deliberate fall-through case GestureExclusionViewInfo.UNCHANGED: rects.addAll(info.mExclusionRects); break; case GestureExclusionViewInfo.GONE: mGestureExclusionViewsChanged = true; i.remove(); break; } } if (changed || mGestureExclusionViewsChanged) { mGestureExclusionViewsChanged = false; if (!mGestureExclusionRects.equals(rects)) { mGestureExclusionRects = rects; return rects; } } return null; } private static class GestureExclusionViewInfo { public static final int CHANGED = 0; public static final int UNCHANGED = 1; public static final int GONE = 2; private final WeakReference<View> mView; boolean mDirty = true; List<Rect> mExclusionRects = Collections.emptyList(); GestureExclusionViewInfo(View view) { mView = new WeakReference<>(view); } public View getView() { return mView.get(); } public int update() { final View excludedView = getView(); if (excludedView == null || !excludedView.isAttachedToWindow()) return GONE; final List<Rect> localRects = excludedView.getSystemGestureExclusionRects(); final List<Rect> newRects = new ArrayList<>(localRects.size()); for (Rect src : localRects) { Rect mappedRect = new Rect(src); ViewParent p = excludedView.getParent(); if (p != null && p.getChildVisibleRect(excludedView, mappedRect, null)) { newRects.add(mappedRect); } } if (mExclusionRects.equals(localRects)) return UNCHANGED; mExclusionRects = newRects; return CHANGED; } } }
core/java/android/view/SurfaceView.java +1 −1 Original line number Diff line number Diff line Loading @@ -210,7 +210,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); mRenderNode.requestPositionUpdates(mPositionListener); mRenderNode.addPositionUpdateListener(mPositionListener); setWillNotDraw(true); } Loading
core/java/android/view/View.java +99 −0 Original line number Diff line number Diff line Loading @@ -4597,6 +4597,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private ArrayList<OnUnhandledKeyEventListener> mUnhandledKeyListeners; private WindowInsetsAnimationListener mWindowInsetsAnimationListener; /** * This lives here since it's only valid for interactive views. */ private List<Rect> mSystemGestureExclusionRects; /** * Used to track {@link #mSystemGestureExclusionRects} */ public RenderNode.PositionUpdateListener mPositionUpdateListener; } @UnsupportedAppUsage Loading Loading @@ -10962,6 +10972,95 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } /** * Sets a list of areas within this view's post-layout coordinate space where the system * should not intercept touch or other pointing device gestures. <em>This method should * be called by {@link #onLayout(boolean, int, int, int, int)} or {@link #onDraw(Canvas)}.</em> * * <p>Use this to tell the system which specific sub-areas of a view need to receive gesture * input in order to function correctly in the presence of global system gestures that may * conflict. For example, if the system wishes to capture swipe-in-from-screen-edge gestures * to provide system-level navigation functionality, a view such as a navigation drawer * container can mark the left (or starting) edge of itself as requiring gesture capture * priority using this API. The system may then choose to relax its own gesture recognition * to allow the app to consume the user's gesture. It is not necessary for an app to register * exclusion rects for broadly spanning regions such as the entirety of a * <code>ScrollView</code> or for simple press and release click targets such as * <code>Button</code>. Mark an exclusion rect when interacting with a view requires * a precision touch gesture in a small area in either the X or Y dimension, such as * an edge swipe or dragging a <code>SeekBar</code> thumb.</p> * * <p>Do not modify the provided list after this method is called.</p> * * @param rects A list of precision gesture regions that this view needs to function correctly */ public void setSystemGestureExclusionRects(@NonNull List<Rect> rects) { if (rects.isEmpty() && mListenerInfo == null) return; final ListenerInfo info = getListenerInfo(); if (rects.isEmpty()) { info.mSystemGestureExclusionRects = null; if (info.mPositionUpdateListener != null) { mRenderNode.removePositionUpdateListener(info.mPositionUpdateListener); } } else { info.mSystemGestureExclusionRects = rects; if (info.mPositionUpdateListener == null) { info.mPositionUpdateListener = new RenderNode.PositionUpdateListener() { @Override public void positionChanged(long n, int l, int t, int r, int b) { postUpdateSystemGestureExclusionRects(); } @Override public void positionLost(long frameNumber) { postUpdateSystemGestureExclusionRects(); } }; mRenderNode.addPositionUpdateListener(info.mPositionUpdateListener); } } postUpdateSystemGestureExclusionRects(); } /** * WARNING: this can be called by a hwui worker thread, not just the UI thread! */ void postUpdateSystemGestureExclusionRects() { // Potentially racey from a background thread. It's ok if it's not perfect. final Handler h = getHandler(); if (h != null) { h.postAtFrontOfQueue(this::updateSystemGestureExclusionRects); } } void updateSystemGestureExclusionRects() { final AttachInfo ai = mAttachInfo; if (ai != null) { ai.mViewRootImpl.updateSystemGestureExclusionRectsForView(this); } } /** * Retrieve the list of areas within this view's post-layout coordinate space where the system * should not intercept touch or other pointing device gestures. * * <p>Do not modify the returned list.</p> * * @return the list set by {@link #setSystemGestureExclusionRects(List)} */ @NonNull public List<Rect> getSystemGestureExclusionRects() { final ListenerInfo info = mListenerInfo; if (info != null) { final List<Rect> list = info.mSystemGestureExclusionRects; if (list != null) { return list; } } return Collections.emptyList(); } /** * Compute the view's coordinate within the surface. *
core/java/android/view/ViewRootImpl.java +53 −29 Original line number Diff line number Diff line Loading @@ -605,6 +605,8 @@ public final class ViewRootImpl implements ViewParent, private final InsetsController mInsetsController = new InsetsController(this); private final GestureExclusionTracker mGestureExclusionTracker = new GestureExclusionTracker(); static final class SystemUiVisibilityInfo { int seq; int globalVisibility; Loading Loading @@ -3977,6 +3979,20 @@ public final class ViewRootImpl implements ViewParent, return mAttachInfo.mAccessibilityFocusDrawable; } void updateSystemGestureExclusionRectsForView(View view) { mGestureExclusionTracker.updateRectsForView(view); mHandler.sendEmptyMessage(MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED); } void systemGestureExclusionChanged() { final List<Rect> rectsForWindowManager = mGestureExclusionTracker.computeChangedRects(); if (rectsForWindowManager != null) { // TODO Send to WM mAttachInfo.mTreeObserver .dispatchOnSystemGestureExclusionRectsChanged(rectsForWindowManager); } } /** * Requests that the root render node is invalidated next time we perform a draw, such that * {@link WindowCallbacks#onPostDraw} gets called. Loading Loading @@ -4433,35 +4449,36 @@ public final class ViewRootImpl implements ViewParent, } } private final static int MSG_INVALIDATE = 1; private final static int MSG_INVALIDATE_RECT = 2; private final static int MSG_DIE = 3; private final static int MSG_RESIZED = 4; private final static int MSG_RESIZED_REPORT = 5; private final static int MSG_WINDOW_FOCUS_CHANGED = 6; private final static int MSG_DISPATCH_INPUT_EVENT = 7; private final static int MSG_DISPATCH_APP_VISIBILITY = 8; private final static int MSG_DISPATCH_GET_NEW_SURFACE = 9; private final static int MSG_DISPATCH_KEY_FROM_IME = 11; private final static int MSG_DISPATCH_KEY_FROM_AUTOFILL = 12; private final static int MSG_CHECK_FOCUS = 13; private final static int MSG_CLOSE_SYSTEM_DIALOGS = 14; private final static int MSG_DISPATCH_DRAG_EVENT = 15; private final static int MSG_DISPATCH_DRAG_LOCATION_EVENT = 16; private final static int MSG_DISPATCH_SYSTEM_UI_VISIBILITY = 17; private final static int MSG_UPDATE_CONFIGURATION = 18; private final static int MSG_PROCESS_INPUT_EVENTS = 19; private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 21; private final static int MSG_INVALIDATE_WORLD = 22; private final static int MSG_WINDOW_MOVED = 23; private final static int MSG_SYNTHESIZE_INPUT_EVENT = 24; private final static int MSG_DISPATCH_WINDOW_SHOWN = 25; private final static int MSG_REQUEST_KEYBOARD_SHORTCUTS = 26; private final static int MSG_UPDATE_POINTER_ICON = 27; private final static int MSG_POINTER_CAPTURE_CHANGED = 28; private final static int MSG_DRAW_FINISHED = 29; private final static int MSG_INSETS_CHANGED = 30; private final static int MSG_INSETS_CONTROL_CHANGED = 31; private static final int MSG_INVALIDATE = 1; private static final int MSG_INVALIDATE_RECT = 2; private static final int MSG_DIE = 3; private static final int MSG_RESIZED = 4; private static final int MSG_RESIZED_REPORT = 5; private static final int MSG_WINDOW_FOCUS_CHANGED = 6; private static final int MSG_DISPATCH_INPUT_EVENT = 7; private static final int MSG_DISPATCH_APP_VISIBILITY = 8; private static final int MSG_DISPATCH_GET_NEW_SURFACE = 9; private static final int MSG_DISPATCH_KEY_FROM_IME = 11; private static final int MSG_DISPATCH_KEY_FROM_AUTOFILL = 12; private static final int MSG_CHECK_FOCUS = 13; private static final int MSG_CLOSE_SYSTEM_DIALOGS = 14; private static final int MSG_DISPATCH_DRAG_EVENT = 15; private static final int MSG_DISPATCH_DRAG_LOCATION_EVENT = 16; private static final int MSG_DISPATCH_SYSTEM_UI_VISIBILITY = 17; private static final int MSG_UPDATE_CONFIGURATION = 18; private static final int MSG_PROCESS_INPUT_EVENTS = 19; private static final int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 21; private static final int MSG_INVALIDATE_WORLD = 22; private static final int MSG_WINDOW_MOVED = 23; private static final int MSG_SYNTHESIZE_INPUT_EVENT = 24; private static final int MSG_DISPATCH_WINDOW_SHOWN = 25; private static final int MSG_REQUEST_KEYBOARD_SHORTCUTS = 26; private static final int MSG_UPDATE_POINTER_ICON = 27; private static final int MSG_POINTER_CAPTURE_CHANGED = 28; private static final int MSG_DRAW_FINISHED = 29; private static final int MSG_INSETS_CHANGED = 30; private static final int MSG_INSETS_CONTROL_CHANGED = 31; private static final int MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED = 32; final class ViewRootHandler extends Handler { @Override Loading Loading @@ -4519,6 +4536,10 @@ public final class ViewRootImpl implements ViewParent, return "MSG_DRAW_FINISHED"; case MSG_INSETS_CHANGED: return "MSG_INSETS_CHANGED"; case MSG_INSETS_CONTROL_CHANGED: return "MSG_INSETS_CONTROL_CHANGED"; case MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED: return "MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED"; } return super.getMessageName(message); } Loading Loading @@ -4750,6 +4771,9 @@ public final class ViewRootImpl implements ViewParent, case MSG_DRAW_FINISHED: { pendingDrawFinished(); } break; case MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED: { systemGestureExclusionChanged(); } break; } } } Loading