Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +4 −0 Original line number Diff line number Diff line Loading @@ -201,9 +201,11 @@ public abstract class WMShellModule { @Provides static WindowDecorViewModel provideWindowDecorViewModel( Context context, @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler, @ShellMainThread Choreographer mainChoreographer, ShellInit shellInit, IWindowManager windowManager, ShellCommandHandler shellCommandHandler, ShellTaskOrganizer taskOrganizer, DisplayController displayController, Loading @@ -216,10 +218,12 @@ public abstract class WMShellModule { if (DesktopModeStatus.isEnabled()) { return new DesktopModeWindowDecorViewModel( context, mainExecutor, mainHandler, mainChoreographer, shellInit, shellCommandHandler, windowManager, taskOrganizer, displayController, shellController, Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java +1 −0 Original line number Diff line number Diff line Loading @@ -190,6 +190,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL mRelayoutParams.mShadowRadiusId = shadowRadiusID; mRelayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw; mRelayoutParams.mSetTaskPositionAndCrop = setTaskCropAndPosition; mRelayoutParams.mAllowCaptionInputFallthrough = false; relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult); // After this line, mTaskInfo is up-to-date and should be used instead of taskInfo Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +81 −0 Original line number Diff line number Diff line Loading @@ -48,9 +48,13 @@ import android.graphics.Region; import android.hardware.input.InputManager; import android.os.Handler; import android.os.Looper; import android.os.RemoteException; import android.util.Log; import android.util.SparseArray; import android.view.Choreographer; import android.view.GestureDetector; import android.view.ISystemGestureExclusionListener; import android.view.IWindowManager; import android.view.InputChannel; import android.view.InputEvent; import android.view.InputEventReceiver; Loading @@ -73,6 +77,7 @@ import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; import com.android.wm.shell.desktopmode.DesktopModeStatus; Loading @@ -88,6 +93,7 @@ import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.ExclusionRegionListener; import com.android.wm.shell.windowdecor.extension.TaskInfoKt; import java.io.PrintWriter; import java.util.Optional; Loading @@ -102,6 +108,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private static final String TAG = "DesktopModeWindowDecorViewModel"; private final DesktopModeWindowDecoration.Factory mDesktopModeWindowDecorFactory; private final IWindowManager mWindowManager; private final ShellExecutor mMainExecutor; private final ActivityTaskManager mActivityTaskManager; private final ShellCommandHandler mShellCommandHandler; private final ShellTaskOrganizer mTaskOrganizer; Loading @@ -112,6 +120,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private final DisplayController mDisplayController; private final SyncTransactionQueue mSyncQueue; private final Optional<DesktopTasksController> mDesktopTasksController; private final InputManager mInputManager; private boolean mTransitionDragActive; private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>(); Loading @@ -135,14 +145,31 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { new DesktopModeKeyguardChangeListener(); private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; private final DisplayInsetsController mDisplayInsetsController; private final Region mExclusionRegion = Region.obtain(); private boolean mInImmersiveMode; private final ISystemGestureExclusionListener mGestureExclusionListener = new ISystemGestureExclusionListener.Stub() { @Override public void onSystemGestureExclusionChanged(int displayId, Region systemGestureExclusion, Region systemGestureExclusionUnrestricted) { if (mContext.getDisplayId() != displayId) { return; } mMainExecutor.execute(() -> { mExclusionRegion.set(systemGestureExclusion); }); } }; public DesktopModeWindowDecorViewModel( Context context, ShellExecutor shellExecutor, Handler mainHandler, Choreographer mainChoreographer, ShellInit shellInit, ShellCommandHandler shellCommandHandler, IWindowManager windowManager, ShellTaskOrganizer taskOrganizer, DisplayController displayController, ShellController shellController, Loading @@ -154,10 +181,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { ) { this( context, shellExecutor, mainHandler, mainChoreographer, shellInit, shellCommandHandler, windowManager, taskOrganizer, displayController, shellController, Loading @@ -174,10 +203,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { @VisibleForTesting DesktopModeWindowDecorViewModel( Context context, ShellExecutor shellExecutor, Handler mainHandler, Choreographer mainChoreographer, ShellInit shellInit, ShellCommandHandler shellCommandHandler, IWindowManager windowManager, ShellTaskOrganizer taskOrganizer, DisplayController displayController, ShellController shellController, Loading @@ -190,6 +221,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { Supplier<SurfaceControl.Transaction> transactionFactory, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) { mContext = context; mMainExecutor = shellExecutor; mMainHandler = mainHandler; mMainChoreographer = mainChoreographer; mActivityTaskManager = mContext.getSystemService(ActivityTaskManager.class); Loading @@ -201,10 +233,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { mTransitions = transitions; mDesktopTasksController = desktopTasksController; mShellCommandHandler = shellCommandHandler; mWindowManager = windowManager; mDesktopModeWindowDecorFactory = desktopModeWindowDecorFactory; mInputMonitorFactory = inputMonitorFactory; mTransactionFactory = transactionFactory; mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; mInputManager = mContext.getSystemService(InputManager.class); shellInit.addInitCallback(this::onInit, this); } Loading @@ -216,6 +250,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { new DesktopModeOnInsetsChangedListener()); mDesktopTasksController.ifPresent(c -> c.setOnTaskResizeAnimationListener( new DeskopModeOnTaskResizeAnimationListener())); try { mWindowManager.registerSystemGestureExclusionListener(mGestureExclusionListener, mContext.getDisplayId()); } catch (RemoteException e) { Log.e(TAG, "Failed to register window manager callbacks", e); } } @Override Loading Loading @@ -315,12 +355,19 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { implements View.OnClickListener, View.OnTouchListener, View.OnLongClickListener, View.OnGenericMotionListener , DragDetector.MotionEventHandler { private static final int CLOSE_MAXIMIZE_MENU_DELAY_MS = 150; private final int mTaskId; private final WindowContainerToken mTaskToken; private final DragPositioningCallback mDragPositioningCallback; private final DragDetector mDragDetector; private final GestureDetector mGestureDetector; /** * Whether to pilfer the next motion event to send cancellations to the windows below. * Useful when the caption window is spy and the gesture should be handle by the system * instead of by the app for their custom header content. */ private boolean mShouldPilferCaptionEvents; private boolean mIsDragging; private boolean mTouchscreenInUse; private boolean mHasLongClicked; Loading Loading @@ -438,6 +485,40 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId); moveTaskToFront(decoration.mTaskInfo); final int actionMasked = e.getActionMasked(); final boolean isDown = actionMasked == MotionEvent.ACTION_DOWN; final boolean isUpOrCancel = actionMasked == MotionEvent.ACTION_CANCEL || actionMasked == MotionEvent.ACTION_UP; if (isDown) { final boolean downInCustomizableCaptionRegion = decoration.checkTouchEventInCustomizableRegion(e); final boolean downInExclusionRegion = mExclusionRegion.contains( (int) e.getRawX(), (int) e.getRawY()); final boolean isTransparentCaption = TaskInfoKt.isTransparentCaptionBarAppearance(decoration.mTaskInfo); // The caption window may be a spy window when the caption background is // transparent, which means events will fall through to the app window. Make // sure to cancel these events if they do not happen in the intersection of the // customizable region and what the app reported as exclusion areas, because // the drag-move or other caption gestures should take priority outside those // regions. mShouldPilferCaptionEvents = !(downInCustomizableCaptionRegion && downInExclusionRegion && isTransparentCaption); } if (!mShouldPilferCaptionEvents) { // The event will be handled by a window below. return false; } // Otherwise pilfer so that windows below receive cancellations for this gesture, and // continue normal handling as a caption gesture. if (mInputManager != null) { mInputManager.pilferPointers(v.getViewRootImpl().getInputToken()); } if (isUpOrCancel) { // Gesture is finished, reset state. mShouldPilferCaptionEvents = false; } if (!mHasLongClicked && id != R.id.maximize_window) { decoration.closeMaximizeMenuIfNeeded(e); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +10 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.desktopmode.DesktopModeStatus; import com.android.wm.shell.desktopmode.DesktopTasksController; import com.android.wm.shell.windowdecor.extension.TaskInfoKt; import com.android.wm.shell.windowdecor.viewholder.DesktopModeAppControlsWindowDecorationViewHolder; import com.android.wm.shell.windowdecor.viewholder.DesktopModeFocusedWindowDecorationViewHolder; import com.android.wm.shell.windowdecor.viewholder.DesktopModeWindowDecorationViewHolder; Loading Loading @@ -337,6 +338,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin controlsElement.mWidthResId = R.dimen.desktop_mode_right_edge_buttons_width; controlsElement.mAlignment = RelayoutParams.OccludingCaptionElement.Alignment.END; relayoutParams.mOccludingCaptionElements.add(controlsElement); relayoutParams.mAllowCaptionInputFallthrough = TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo); } if (DesktopModeStatus.useWindowShadow(/* isFocusedWindow= */ taskInfo.isFocused)) { relayoutParams.mShadowRadiusId = taskInfo.isFocused Loading Loading @@ -698,6 +701,13 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin && inputPoint.y <= mResult.mCaptionHeight; } /** * Checks whether the touch event falls inside the customizable caption region. */ boolean checkTouchEventInCustomizableRegion(MotionEvent ev) { return mResult.mCustomizableCaptionRegion.contains((int) ev.getRawX(), (int) ev.getRawY()); } /** * Check a passed MotionEvent if a click has occurred on any button on this caption * Note this should only be called when a regular onClick is not possible Loading libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +20 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; import android.os.Binder; import android.view.Display; import android.view.InsetsSource; Loading Loading @@ -311,6 +312,10 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> if (numOfElements == 0) { boundingRects = null; } else { // The customizable region can at most be equal to the caption bar. if (params.mAllowCaptionInputFallthrough) { outResult.mCustomizableCaptionRegion.set(mCaptionInsetsRect); } boundingRects = new Rect[numOfElements]; for (int i = 0; i < numOfElements; i++) { final OccludingCaptionElement element = Loading @@ -319,9 +324,14 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> resources.getDimensionPixelSize(element.mWidthResId); boundingRects[i] = calculateBoundingRect(element, elementWidthPx, mCaptionInsetsRect); // Subtract the regions used by the caption elements, the rest is // customizable. if (params.mAllowCaptionInputFallthrough) { outResult.mCustomizableCaptionRegion.op(boundingRects[i], Region.Op.DIFFERENCE); } } } // Add this caption as an inset source. wct.addInsetsSource(mTaskInfo.token, mOwner, 0 /* index */, WindowInsets.Type.captionBar(), mCaptionInsetsRect, Loading Loading @@ -389,6 +399,11 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT); lp.setTitle("Caption of Task=" + mTaskInfo.taskId); lp.setTrustedOverlay(); if (params.mAllowCaptionInputFallthrough) { lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_SPY; } else { lp.inputFeatures &= ~WindowManager.LayoutParams.INPUT_FEATURE_SPY; } if (mViewHost == null) { mViewHost = mSurfaceControlViewHostFactory.create(mDecorWindowContext, mDisplay, mCaptionWindowManager); Loading Loading @@ -596,6 +611,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> int mCaptionHeightId; int mCaptionWidthId; final List<OccludingCaptionElement> mOccludingCaptionElements = new ArrayList<>(); boolean mAllowCaptionInputFallthrough; int mShadowRadiusId; int mCornerRadius; Loading @@ -610,6 +626,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> mCaptionHeightId = Resources.ID_NULL; mCaptionWidthId = Resources.ID_NULL; mOccludingCaptionElements.clear(); mAllowCaptionInputFallthrough = false; mShadowRadiusId = Resources.ID_NULL; mCornerRadius = 0; Loading Loading @@ -637,6 +654,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> int mCaptionHeight; int mCaptionWidth; int mCaptionX; final Region mCustomizableCaptionRegion = Region.obtain(); int mWidth; int mHeight; T mRootView; Loading @@ -647,6 +665,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> mCaptionHeight = 0; mCaptionWidth = 0; mCaptionX = 0; mCustomizableCaptionRegion.setEmpty(); mRootView = null; } } Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +4 −0 Original line number Diff line number Diff line Loading @@ -201,9 +201,11 @@ public abstract class WMShellModule { @Provides static WindowDecorViewModel provideWindowDecorViewModel( Context context, @ShellMainThread ShellExecutor mainExecutor, @ShellMainThread Handler mainHandler, @ShellMainThread Choreographer mainChoreographer, ShellInit shellInit, IWindowManager windowManager, ShellCommandHandler shellCommandHandler, ShellTaskOrganizer taskOrganizer, DisplayController displayController, Loading @@ -216,10 +218,12 @@ public abstract class WMShellModule { if (DesktopModeStatus.isEnabled()) { return new DesktopModeWindowDecorViewModel( context, mainExecutor, mainHandler, mainChoreographer, shellInit, shellCommandHandler, windowManager, taskOrganizer, displayController, shellController, Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java +1 −0 Original line number Diff line number Diff line Loading @@ -190,6 +190,7 @@ public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearL mRelayoutParams.mShadowRadiusId = shadowRadiusID; mRelayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw; mRelayoutParams.mSetTaskPositionAndCrop = setTaskCropAndPosition; mRelayoutParams.mAllowCaptionInputFallthrough = false; relayout(mRelayoutParams, startT, finishT, wct, oldRootView, mResult); // After this line, mTaskInfo is up-to-date and should be used instead of taskInfo Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java +81 −0 Original line number Diff line number Diff line Loading @@ -48,9 +48,13 @@ import android.graphics.Region; import android.hardware.input.InputManager; import android.os.Handler; import android.os.Looper; import android.os.RemoteException; import android.util.Log; import android.util.SparseArray; import android.view.Choreographer; import android.view.GestureDetector; import android.view.ISystemGestureExclusionListener; import android.view.IWindowManager; import android.view.InputChannel; import android.view.InputEvent; import android.view.InputEventReceiver; Loading @@ -73,6 +77,7 @@ import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayInsetsController; import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.common.split.SplitScreenConstants.SplitPosition; import com.android.wm.shell.desktopmode.DesktopModeStatus; Loading @@ -88,6 +93,7 @@ import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.sysui.ShellInit; import com.android.wm.shell.transition.Transitions; import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration.ExclusionRegionListener; import com.android.wm.shell.windowdecor.extension.TaskInfoKt; import java.io.PrintWriter; import java.util.Optional; Loading @@ -102,6 +108,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private static final String TAG = "DesktopModeWindowDecorViewModel"; private final DesktopModeWindowDecoration.Factory mDesktopModeWindowDecorFactory; private final IWindowManager mWindowManager; private final ShellExecutor mMainExecutor; private final ActivityTaskManager mActivityTaskManager; private final ShellCommandHandler mShellCommandHandler; private final ShellTaskOrganizer mTaskOrganizer; Loading @@ -112,6 +120,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { private final DisplayController mDisplayController; private final SyncTransactionQueue mSyncQueue; private final Optional<DesktopTasksController> mDesktopTasksController; private final InputManager mInputManager; private boolean mTransitionDragActive; private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>(); Loading @@ -135,14 +145,31 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { new DesktopModeKeyguardChangeListener(); private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer; private final DisplayInsetsController mDisplayInsetsController; private final Region mExclusionRegion = Region.obtain(); private boolean mInImmersiveMode; private final ISystemGestureExclusionListener mGestureExclusionListener = new ISystemGestureExclusionListener.Stub() { @Override public void onSystemGestureExclusionChanged(int displayId, Region systemGestureExclusion, Region systemGestureExclusionUnrestricted) { if (mContext.getDisplayId() != displayId) { return; } mMainExecutor.execute(() -> { mExclusionRegion.set(systemGestureExclusion); }); } }; public DesktopModeWindowDecorViewModel( Context context, ShellExecutor shellExecutor, Handler mainHandler, Choreographer mainChoreographer, ShellInit shellInit, ShellCommandHandler shellCommandHandler, IWindowManager windowManager, ShellTaskOrganizer taskOrganizer, DisplayController displayController, ShellController shellController, Loading @@ -154,10 +181,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { ) { this( context, shellExecutor, mainHandler, mainChoreographer, shellInit, shellCommandHandler, windowManager, taskOrganizer, displayController, shellController, Loading @@ -174,10 +203,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { @VisibleForTesting DesktopModeWindowDecorViewModel( Context context, ShellExecutor shellExecutor, Handler mainHandler, Choreographer mainChoreographer, ShellInit shellInit, ShellCommandHandler shellCommandHandler, IWindowManager windowManager, ShellTaskOrganizer taskOrganizer, DisplayController displayController, ShellController shellController, Loading @@ -190,6 +221,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { Supplier<SurfaceControl.Transaction> transactionFactory, RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) { mContext = context; mMainExecutor = shellExecutor; mMainHandler = mainHandler; mMainChoreographer = mainChoreographer; mActivityTaskManager = mContext.getSystemService(ActivityTaskManager.class); Loading @@ -201,10 +233,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { mTransitions = transitions; mDesktopTasksController = desktopTasksController; mShellCommandHandler = shellCommandHandler; mWindowManager = windowManager; mDesktopModeWindowDecorFactory = desktopModeWindowDecorFactory; mInputMonitorFactory = inputMonitorFactory; mTransactionFactory = transactionFactory; mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer; mInputManager = mContext.getSystemService(InputManager.class); shellInit.addInitCallback(this::onInit, this); } Loading @@ -216,6 +250,12 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { new DesktopModeOnInsetsChangedListener()); mDesktopTasksController.ifPresent(c -> c.setOnTaskResizeAnimationListener( new DeskopModeOnTaskResizeAnimationListener())); try { mWindowManager.registerSystemGestureExclusionListener(mGestureExclusionListener, mContext.getDisplayId()); } catch (RemoteException e) { Log.e(TAG, "Failed to register window manager callbacks", e); } } @Override Loading Loading @@ -315,12 +355,19 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { implements View.OnClickListener, View.OnTouchListener, View.OnLongClickListener, View.OnGenericMotionListener , DragDetector.MotionEventHandler { private static final int CLOSE_MAXIMIZE_MENU_DELAY_MS = 150; private final int mTaskId; private final WindowContainerToken mTaskToken; private final DragPositioningCallback mDragPositioningCallback; private final DragDetector mDragDetector; private final GestureDetector mGestureDetector; /** * Whether to pilfer the next motion event to send cancellations to the windows below. * Useful when the caption window is spy and the gesture should be handle by the system * instead of by the app for their custom header content. */ private boolean mShouldPilferCaptionEvents; private boolean mIsDragging; private boolean mTouchscreenInUse; private boolean mHasLongClicked; Loading Loading @@ -438,6 +485,40 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel { final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId); moveTaskToFront(decoration.mTaskInfo); final int actionMasked = e.getActionMasked(); final boolean isDown = actionMasked == MotionEvent.ACTION_DOWN; final boolean isUpOrCancel = actionMasked == MotionEvent.ACTION_CANCEL || actionMasked == MotionEvent.ACTION_UP; if (isDown) { final boolean downInCustomizableCaptionRegion = decoration.checkTouchEventInCustomizableRegion(e); final boolean downInExclusionRegion = mExclusionRegion.contains( (int) e.getRawX(), (int) e.getRawY()); final boolean isTransparentCaption = TaskInfoKt.isTransparentCaptionBarAppearance(decoration.mTaskInfo); // The caption window may be a spy window when the caption background is // transparent, which means events will fall through to the app window. Make // sure to cancel these events if they do not happen in the intersection of the // customizable region and what the app reported as exclusion areas, because // the drag-move or other caption gestures should take priority outside those // regions. mShouldPilferCaptionEvents = !(downInCustomizableCaptionRegion && downInExclusionRegion && isTransparentCaption); } if (!mShouldPilferCaptionEvents) { // The event will be handled by a window below. return false; } // Otherwise pilfer so that windows below receive cancellations for this gesture, and // continue normal handling as a caption gesture. if (mInputManager != null) { mInputManager.pilferPointers(v.getViewRootImpl().getInputToken()); } if (isUpOrCancel) { // Gesture is finished, reset state. mShouldPilferCaptionEvents = false; } if (!mHasLongClicked && id != R.id.maximize_window) { decoration.closeMaximizeMenuIfNeeded(e); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecoration.java +10 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.SyncTransactionQueue; import com.android.wm.shell.desktopmode.DesktopModeStatus; import com.android.wm.shell.desktopmode.DesktopTasksController; import com.android.wm.shell.windowdecor.extension.TaskInfoKt; import com.android.wm.shell.windowdecor.viewholder.DesktopModeAppControlsWindowDecorationViewHolder; import com.android.wm.shell.windowdecor.viewholder.DesktopModeFocusedWindowDecorationViewHolder; import com.android.wm.shell.windowdecor.viewholder.DesktopModeWindowDecorationViewHolder; Loading Loading @@ -337,6 +338,8 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin controlsElement.mWidthResId = R.dimen.desktop_mode_right_edge_buttons_width; controlsElement.mAlignment = RelayoutParams.OccludingCaptionElement.Alignment.END; relayoutParams.mOccludingCaptionElements.add(controlsElement); relayoutParams.mAllowCaptionInputFallthrough = TaskInfoKt.isTransparentCaptionBarAppearance(taskInfo); } if (DesktopModeStatus.useWindowShadow(/* isFocusedWindow= */ taskInfo.isFocused)) { relayoutParams.mShadowRadiusId = taskInfo.isFocused Loading Loading @@ -698,6 +701,13 @@ public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLin && inputPoint.y <= mResult.mCaptionHeight; } /** * Checks whether the touch event falls inside the customizable caption region. */ boolean checkTouchEventInCustomizableRegion(MotionEvent ev) { return mResult.mCustomizableCaptionRegion.contains((int) ev.getRawX(), (int) ev.getRawY()); } /** * Check a passed MotionEvent if a click has occurred on any button on this caption * Note this should only be called when a regular onClick is not possible Loading
libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java +20 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.graphics.Color; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; import android.os.Binder; import android.view.Display; import android.view.InsetsSource; Loading Loading @@ -311,6 +312,10 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> if (numOfElements == 0) { boundingRects = null; } else { // The customizable region can at most be equal to the caption bar. if (params.mAllowCaptionInputFallthrough) { outResult.mCustomizableCaptionRegion.set(mCaptionInsetsRect); } boundingRects = new Rect[numOfElements]; for (int i = 0; i < numOfElements; i++) { final OccludingCaptionElement element = Loading @@ -319,9 +324,14 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> resources.getDimensionPixelSize(element.mWidthResId); boundingRects[i] = calculateBoundingRect(element, elementWidthPx, mCaptionInsetsRect); // Subtract the regions used by the caption elements, the rest is // customizable. if (params.mAllowCaptionInputFallthrough) { outResult.mCustomizableCaptionRegion.op(boundingRects[i], Region.Op.DIFFERENCE); } } } // Add this caption as an inset source. wct.addInsetsSource(mTaskInfo.token, mOwner, 0 /* index */, WindowInsets.Type.captionBar(), mCaptionInsetsRect, Loading Loading @@ -389,6 +399,11 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT); lp.setTitle("Caption of Task=" + mTaskInfo.taskId); lp.setTrustedOverlay(); if (params.mAllowCaptionInputFallthrough) { lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_SPY; } else { lp.inputFeatures &= ~WindowManager.LayoutParams.INPUT_FEATURE_SPY; } if (mViewHost == null) { mViewHost = mSurfaceControlViewHostFactory.create(mDecorWindowContext, mDisplay, mCaptionWindowManager); Loading Loading @@ -596,6 +611,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> int mCaptionHeightId; int mCaptionWidthId; final List<OccludingCaptionElement> mOccludingCaptionElements = new ArrayList<>(); boolean mAllowCaptionInputFallthrough; int mShadowRadiusId; int mCornerRadius; Loading @@ -610,6 +626,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> mCaptionHeightId = Resources.ID_NULL; mCaptionWidthId = Resources.ID_NULL; mOccludingCaptionElements.clear(); mAllowCaptionInputFallthrough = false; mShadowRadiusId = Resources.ID_NULL; mCornerRadius = 0; Loading Loading @@ -637,6 +654,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> int mCaptionHeight; int mCaptionWidth; int mCaptionX; final Region mCustomizableCaptionRegion = Region.obtain(); int mWidth; int mHeight; T mRootView; Loading @@ -647,6 +665,7 @@ public abstract class WindowDecoration<T extends View & TaskFocusStateConsumer> mCaptionHeight = 0; mCaptionWidth = 0; mCaptionX = 0; mCustomizableCaptionRegion.setEmpty(); mRootView = null; } } Loading