summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/IDecorViewGestureListener.aidl32
-rw-r--r--core/java/android/view/IWindowManager.aidl15
-rw-r--r--core/java/android/view/IWindowSession.aidl5
-rw-r--r--core/java/android/view/ViewRootImpl.java27
-rw-r--r--core/java/android/view/WindowlessWindowManager.java10
-rw-r--r--core/java/com/android/internal/policy/DecorView.java20
-rw-r--r--core/java/com/android/internal/policy/WearGestureInterceptionDetector.java211
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java24
-rw-r--r--services/core/java/com/android/server/wm/Session.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java61
10 files changed, 407 insertions, 8 deletions
diff --git a/core/java/android/view/IDecorViewGestureListener.aidl b/core/java/android/view/IDecorViewGestureListener.aidl
new file mode 100644
index 000000000000..1022dbfb70eb
--- /dev/null
+++ b/core/java/android/view/IDecorViewGestureListener.aidl
@@ -0,0 +1,32 @@
+/**
+ * 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;
+
+/**
+ * Listener for changes to gesture interception detector running at DecorView.
+ *
+ * {@hide}
+ */
+oneway interface IDecorViewGestureListener {
+ /**
+ * Called when a DecorView has started intercepting gesture.
+ *
+ * @param windowToken Where did this gesture interception result comes from.
+ * @param intercepted Whether the gesture interception detector has started interception.
+ */
+ void onInterceptionChanged(in IBinder windowToken, in boolean intercepted);
+}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index cccac95b9caa..c10fc9f9cb09 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -48,6 +48,7 @@ import android.view.IScrollCaptureResponseListener;
import android.view.RemoteAnimationAdapter;
import android.view.IRotationWatcher;
import android.view.ISystemGestureExclusionListener;
+import android.view.IDecorViewGestureListener;
import android.view.IWallpaperVisibilityListener;
import android.view.IWindow;
import android.view.IWindowSession;
@@ -1062,4 +1063,18 @@ interface IWindowManager
@JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ ".permission.ACCESS_SURFACE_FLINGER)")
boolean replaceContentOnDisplay(int displayId, in SurfaceControl sc);
+
+ /**
+ * Registers a DecorView gesture listener for a given display.
+ */
+ @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ + ".permission.MONITOR_INPUT)")
+ void registerDecorViewGestureListener(IDecorViewGestureListener listener, int displayId);
+
+ /**
+ * Unregisters a DecorView gesture listener for a given display.
+ */
+ @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ + ".permission.MONITOR_INPUT)")
+ void unregisterDecorViewGestureListener(IDecorViewGestureListener listener, int displayId);
}
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 83de2a0fafbe..7acf2f8ce06d 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -284,6 +284,11 @@ interface IWindowSession {
oneway void reportSystemGestureExclusionChanged(IWindow window, in List<Rect> exclusionRects);
/**
+ * Called when the DecorView gesture interception state has changed.
+ */
+ oneway void reportDecorViewGestureInterceptionChanged(IWindow window, in boolean intercepted);
+
+ /**
* Called when the keep-clear areas for this window have changed.
*/
oneway void reportKeepClearAreasChanged(IWindow window, in List<Rect> restricted,
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index f4213510a1c1..810ca508ee79 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -5286,6 +5286,29 @@ public final class ViewRootImpl implements ViewParent,
}
/**
+ * Called from DecorView when gesture interception state has changed.
+ *
+ * @param intercepted If DecorView is intercepting touch events
+ */
+ public void updateDecorViewGestureInterception(boolean intercepted) {
+ mHandler.sendMessage(
+ mHandler.obtainMessage(
+ MSG_DECOR_VIEW_GESTURE_INTERCEPTION,
+ /* arg1= */ intercepted ? 1 : 0,
+ /* arg2= */ 0));
+ }
+
+ void decorViewInterceptionChanged(boolean intercepted) {
+ if (mView != null) {
+ try {
+ mWindowSession.reportDecorViewGestureInterceptionChanged(mWindow, intercepted);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
* Set the root-level system gesture exclusion rects. These are added to those provided by
* the root's view hierarchy.
*/
@@ -5908,6 +5931,7 @@ public final class ViewRootImpl implements ViewParent,
private static final int MSG_KEEP_CLEAR_RECTS_CHANGED = 35;
private static final int MSG_REPORT_KEEP_CLEAR_RECTS = 36;
private static final int MSG_PAUSED_FOR_SYNC_TIMEOUT = 37;
+ private static final int MSG_DECOR_VIEW_GESTURE_INTERCEPTION = 38;
final class ViewRootHandler extends Handler {
@Override
@@ -6186,6 +6210,9 @@ public final class ViewRootImpl implements ViewParent,
case MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED: {
systemGestureExclusionChanged();
} break;
+ case MSG_DECOR_VIEW_GESTURE_INTERCEPTION: {
+ decorViewInterceptionChanged(/* intercepted= */ msg.arg1 == 1);
+ } break;
case MSG_KEEP_CLEAR_RECTS_CHANGED: {
keepClearRectsChanged(/* accessibilityFocusRectChanged= */ msg.arg1 == 1);
} break;
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 7d3d283a45f2..f67ce2089381 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -583,9 +583,13 @@ public class WindowlessWindowManager implements IWindowSession {
}
@Override
- public void reportKeepClearAreasChanged(android.view.IWindow window, List<Rect> restrictedRects,
- List<Rect> unrestrictedRects) {
- }
+ public void reportDecorViewGestureInterceptionChanged(IWindow window, boolean intercepted) {}
+
+ @Override
+ public void reportKeepClearAreasChanged(
+ android.view.IWindow window,
+ List<Rect> restrictedRects,
+ List<Rect> unrestrictedRects) {}
@Override
public void grantInputChannel(int displayId, SurfaceControl surface, IWindow window,
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 1be916f44f5b..85662634c22d 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -290,11 +290,12 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
};
private Consumer<Boolean> mCrossWindowBlurEnabledListener;
+ private final WearGestureInterceptionDetector mWearGestureInterceptionDetector;
+
DecorView(Context context, int featureId, PhoneWindow window,
WindowManager.LayoutParams params) {
super(context);
mFeatureId = featureId;
-
mShowInterpolator = AnimationUtils.loadInterpolator(context,
android.R.interpolator.linear_out_slow_in);
mHideInterpolator = AnimationUtils.loadInterpolator(context,
@@ -314,6 +315,11 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
updateLogTag(params);
mLegacyNavigationBarBackgroundPaint.setColor(Color.BLACK);
+
+ mWearGestureInterceptionDetector =
+ WearGestureInterceptionDetector.isEnabled(context)
+ ? new WearGestureInterceptionDetector(context, this)
+ : null;
}
void setBackgroundFallback(@Nullable Drawable fallbackDrawable) {
@@ -544,6 +550,18 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
}
}
+ ViewRootImpl viewRootImpl = getViewRootImpl();
+ if (viewRootImpl != null && mWearGestureInterceptionDetector != null) {
+ boolean wasIntercepting = mWearGestureInterceptionDetector.isIntercepting();
+ boolean intercepting = mWearGestureInterceptionDetector.onInterceptTouchEvent(event);
+ if (wasIntercepting != intercepting) {
+ viewRootImpl.updateDecorViewGestureInterception(intercepting);
+ }
+ if (intercepting) {
+ return true;
+ }
+ }
+
if (!SWEEP_OPEN_MENU) {
return false;
}
diff --git a/core/java/com/android/internal/policy/WearGestureInterceptionDetector.java b/core/java/com/android/internal/policy/WearGestureInterceptionDetector.java
new file mode 100644
index 000000000000..6fd50180e78b
--- /dev/null
+++ b/core/java/com/android/internal/policy/WearGestureInterceptionDetector.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2023 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 com.android.internal.policy;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.TypedArray;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+
+/**
+ * Wear-specific gesture interception detector to be installed at DecorView, for compatibility of
+ * apps depending on legacy SwipeDismissLayout behavior.
+ *
+ * <p>Results of the detector will be used by {@code DecorView} to intercept motion events. The
+ * interception state will also be sent to {@code android.view.ViewRootImpl} and {@code
+ * com.android.server.wm.DisplayContent} through {@code android.view.IWindowSession}.
+ *
+ * <p>SystemUI can register {@code android.view.IDecorViewGestureListener} to listen for the result
+ * of the detector. The result will be valid for between a pair of touch down/up events.
+ */
+public class WearGestureInterceptionDetector {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "WearGestureInterceptionDetector";
+
+ private final DecorView mInstalledDecorView;
+ private final float mTouchSlop;
+ private final float mSwipingStartThreshold;
+ private boolean mSwiping;
+
+ private float mDownX;
+ private float mDownY;
+ private int mActivePointerId;
+ private boolean mDiscardIntercept;
+
+ WearGestureInterceptionDetector(Context context, DecorView installedDecorView) {
+ mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+ mInstalledDecorView = installedDecorView;
+ mSwipingStartThreshold = mTouchSlop * 2;
+ }
+
+ /** Check if this gesture interception detector should be enabled. */
+ public static boolean isEnabled(Context context) {
+ PackageManager pm = context.getPackageManager();
+ if (!pm.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+ return false;
+ }
+
+ // Compatibility check for flag that disables legacy SwipeDismissLayout.
+ TypedArray windowAttr =
+ context.obtainStyledAttributes(new int[] {android.R.attr.windowSwipeToDismiss});
+ boolean windowSwipeToDismiss = true;
+ if (windowAttr.getIndexCount() > 0) {
+ windowSwipeToDismiss = windowAttr.getBoolean(0, true);
+ }
+ windowAttr.recycle();
+ return windowSwipeToDismiss;
+ }
+
+ private boolean isPointerIndexValid(MotionEvent ev) {
+ int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ if (pointerIndex == -1) {
+ if (DEBUG) {
+ Log.e(TAG, "Invalid pointer index: ignoring.");
+ }
+ mDiscardIntercept = true;
+ return false;
+ }
+ return true;
+ }
+
+ private void updateSwiping(MotionEvent ev) {
+ if (mSwiping) {
+ return;
+ }
+ float deltaX = ev.getRawX() - mDownX;
+ float deltaY = ev.getRawY() - mDownY;
+ // Check if we have left the touch slop area.
+ if ((deltaX * deltaX) + (deltaY * deltaY) > (mTouchSlop * mTouchSlop)) {
+ mSwiping = deltaX > mSwipingStartThreshold && Math.abs(deltaY) < Math.abs(deltaX);
+ }
+ }
+
+ private void updateDiscardIntercept(MotionEvent ev) {
+ if (!mSwiping) {
+ // Don't look at canScroll until we have passed the touch slop
+ return;
+ }
+ if (mDiscardIntercept) {
+ return;
+ }
+ final boolean checkLeft = mDownX < ev.getRawX();
+ final float x = ev.getX(mActivePointerId);
+ final float y = ev.getY(mActivePointerId);
+ if (canScroll(mInstalledDecorView, false, checkLeft, x, y)) {
+ mDiscardIntercept = true;
+ }
+ }
+
+ /** Resets internal members when canceling. */
+ private void resetMembers() {
+ mDownX = 0;
+ mDownY = 0;
+ mSwiping = false;
+ mDiscardIntercept = false;
+ }
+
+ /** Should we intercept the MotionEvent for system gesture? */
+ public boolean isIntercepting() {
+ return !mDiscardIntercept && mSwiping;
+ }
+
+ /** Tests if the MotionEvent should be intercepted */
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ switch (ev.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ resetMembers();
+ mDownX = ev.getRawX();
+ mDownY = ev.getRawY();
+ mActivePointerId = ev.getPointerId(0);
+ break;
+ case MotionEvent.ACTION_POINTER_DOWN:
+ mActivePointerId = ev.getPointerId(ev.getActionIndex());
+ break;
+ case MotionEvent.ACTION_POINTER_UP:
+ int associatedPointerIndex = ev.getActionIndex();
+ if (ev.getPointerId(associatedPointerIndex) == mActivePointerId) {
+ // This was our active pointer going up.
+ // Choose the first available pointer index.
+ int newActionIndex = associatedPointerIndex == 0 ? 1 : 0;
+ mActivePointerId = ev.getPointerId(newActionIndex);
+ }
+ break;
+ case MotionEvent.ACTION_MOVE:
+ if (mDiscardIntercept) {
+ break;
+ }
+ if (!isPointerIndexValid(ev)) {
+ break;
+ }
+ updateSwiping(ev);
+ updateDiscardIntercept(ev);
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ resetMembers();
+ break;
+ }
+ return isIntercepting();
+ }
+
+ /**
+ * Tests scroll-ability within child views of v in the direction of dx.
+ *
+ * @param v View to test for horizontal scroll-ability
+ * @param checkSelf Whether the view v passed should itself be checked for scroll-ability
+ * (true), or just its children (false).
+ * @param checkLeft Which direction to check? Left = true, right = false.
+ * @param x X coordinate of the active touch point
+ * @param y Y coordinate of the active touch point
+ * @return true if child views of v can be scrolled by delta of dx.
+ */
+ private boolean canScroll(View v, boolean checkSelf, boolean checkLeft, float x, float y) {
+ if (v instanceof ViewGroup) {
+ final ViewGroup group = (ViewGroup) v;
+ final int scrollX = v.getScrollX();
+ final int scrollY = v.getScrollY();
+ final int count = group.getChildCount();
+ for (int i = count - 1; i >= 0; i--) {
+ final View child = group.getChildAt(i);
+
+ if (x + scrollX < child.getLeft()
+ || x + scrollX >= child.getRight()
+ || y + scrollY < child.getTop()
+ || y + scrollY >= child.getBottom()) {
+ // This child is out of bound, don't bother checking.
+ continue;
+ }
+
+ // Recursively check until finding the first scrollable or none is scrollable.
+ if (canScroll(
+ /* view= */ child,
+ /* checkSelf= */ true,
+ /* checkLeft= */ checkLeft,
+ /* x= */ x + scrollX - child.getLeft(),
+ /* y= */ y + scrollY - child.getTop())) {
+ return true;
+ }
+ }
+ }
+
+ return checkSelf && v.canScrollHorizontally(checkLeft ? -1 : 1);
+ }
+}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index ca42400dad26..6c15623a25d6 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -218,6 +218,7 @@ import android.view.DisplayCutout;
import android.view.DisplayInfo;
import android.view.DisplayShape;
import android.view.Gravity;
+import android.view.IDecorViewGestureListener;
import android.view.IDisplayWindowInsetsController;
import android.view.ISystemGestureExclusionListener;
import android.view.IWindow;
@@ -471,6 +472,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
private final RemoteCallbackList<ISystemGestureExclusionListener>
mSystemGestureExclusionListeners = new RemoteCallbackList<>();
+ private final RemoteCallbackList<IDecorViewGestureListener> mDecorViewGestureListener =
+ new RemoteCallbackList<>();
private final Region mSystemGestureExclusion = new Region();
private boolean mSystemGestureExclusionWasRestricted = false;
private final Region mSystemGestureExclusionUnrestricted = new Region();
@@ -5968,6 +5971,27 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mSystemGestureExclusionListeners.unregister(listener);
}
+ void registerDecorViewGestureListener(IDecorViewGestureListener listener) {
+ mDecorViewGestureListener.register(listener);
+ }
+
+ void unregisterDecorViewGestureListener(IDecorViewGestureListener listener) {
+ mDecorViewGestureListener.unregister(listener);
+ }
+
+ void updateDecorViewGestureIntercepted(IBinder token, boolean intercepted) {
+ for (int i = mDecorViewGestureListener.beginBroadcast() - 1; i >= 0; --i) {
+ try {
+ mDecorViewGestureListener
+ .getBroadcastItem(i)
+ .onInterceptionChanged(token, intercepted);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to notify DecorViewGestureListener", e);
+ }
+ }
+ mDecorViewGestureListener.finishBroadcast();
+ }
+
void updateKeepClearAreas() {
final Set<Rect> restrictedKeepClearAreas = new ArraySet<>();
final Set<Rect> unrestrictedKeepClearAreas = new ArraySet<>();
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index bbe44c540c39..8599694b0cd9 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -560,6 +560,16 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
}
@Override
+ public void reportDecorViewGestureInterceptionChanged(IWindow window, boolean intercepted) {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mService.reportDecorViewGestureChanged(this, window, intercepted);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
public void reportKeepClearAreasChanged(IWindow window, List<Rect> restricted,
List<Rect> unrestricted) {
if (!mSetsUnrestrictedKeepClearAreas && !unrestricted.isEmpty()) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 3db7765963f7..de531c91889a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -249,6 +249,7 @@ import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.IAppTransitionAnimationSpecsFuture;
import android.view.ICrossWindowBlurEnabledListener;
+import android.view.IDecorViewGestureListener;
import android.view.IDisplayChangeWindowController;
import android.view.IDisplayFoldListener;
import android.view.IDisplayWindowInsetsController;
@@ -4637,8 +4638,9 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized (mGlobalLock) {
final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent == null) {
- throw new IllegalArgumentException("Trying to register visibility event "
- + "for invalid display: " + displayId);
+ throw new IllegalArgumentException(
+ "Trying to register system gesture exclusion event for invalid display: "
+ + displayId);
}
displayContent.registerSystemGestureExclusionListener(listener);
}
@@ -4650,13 +4652,64 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized (mGlobalLock) {
final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent == null) {
- throw new IllegalArgumentException("Trying to register visibility event "
- + "for invalid display: " + displayId);
+ throw new IllegalArgumentException(
+ "Trying to unregister system gesture exclusion event for invalid display: "
+ + displayId);
}
displayContent.unregisterSystemGestureExclusionListener(listener);
}
}
+ @Override
+ public void registerDecorViewGestureListener(
+ IDecorViewGestureListener listener, int displayId) {
+ if (!checkCallingPermission(android.Manifest.permission.MONITOR_INPUT,
+ "registerDecorViewGestureListener()")) {
+ throw new SecurityException("Requires MONITOR_INPUT permission");
+ }
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ if (displayContent == null) {
+ throw new IllegalArgumentException(
+ "Trying to register DecorView gesture event listener"
+ + "for invalid display: "
+ + displayId);
+ }
+ displayContent.registerDecorViewGestureListener(listener);
+ }
+ }
+
+ @Override
+ public void unregisterDecorViewGestureListener(
+ IDecorViewGestureListener listener, int displayId) {
+ if (!checkCallingPermission(android.Manifest.permission.MONITOR_INPUT,
+ "unregisterSystemGestureExclusionListener()")) {
+ throw new SecurityException("Requires MONITOR_INPUT permission");
+ }
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ if (displayContent == null) {
+ throw new IllegalArgumentException(
+ "Trying to unregister DecorView gesture event listener"
+ + "for invalid display: "
+ + displayId);
+ }
+ displayContent.unregisterDecorViewGestureListener(listener);
+ }
+ }
+
+ void reportDecorViewGestureChanged(Session session, IWindow window, boolean intercepted) {
+ synchronized (mGlobalLock) {
+ final WindowState win =
+ windowForClientLocked(session, window, false /* throwOnError */);
+ if (win == null) {
+ return;
+ }
+ win.getDisplayContent()
+ .updateDecorViewGestureIntercepted(win.mToken.token, intercepted);
+ }
+ }
+
void reportSystemGestureExclusionChanged(Session session, IWindow window,
List<Rect> exclusionRects) {
synchronized (mGlobalLock) {