Loading libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java +5 −7 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import static android.view.DragEvent.ACTION_DROP; import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.view.WindowManager.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; Loading Loading @@ -247,9 +246,8 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll R.layout.global_drop_target, null); rootView.setOnDragListener(this); rootView.setVisibility(View.INVISIBLE); DragLayout dragLayout = new DragLayout(context, mSplitScreen, mIconProvider); rootView.addView(dragLayout, new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)); DragLayoutProvider dragLayout = new DragLayout(context, mSplitScreen, mIconProvider); dragLayout.addDraggingView(rootView); try { wm.addView(rootView, layoutParams); addDisplayDropTarget(displayId, context, wm, rootView, dragLayout); Loading @@ -261,7 +259,7 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll @VisibleForTesting void addDisplayDropTarget(int displayId, Context context, WindowManager wm, FrameLayout rootView, DragLayout dragLayout) { FrameLayout rootView, DragLayoutProvider dragLayout) { mDisplayDropTargets.put(displayId, new PerDisplay(displayId, context, wm, rootView, dragLayout)); } Loading Loading @@ -564,7 +562,7 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll final Context context; final WindowManager wm; final FrameLayout rootView; final DragLayout dragLayout; final DragLayoutProvider dragLayout; // Tracks whether the window has fully drawn since it was last made visible boolean hasDrawn; Loading @@ -575,7 +573,7 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll // The active drag session DragSession dragSession; PerDisplay(int dispId, Context c, WindowManager w, FrameLayout rv, DragLayout dl) { PerDisplay(int dispId, Context c, WindowManager w, FrameLayout rv, DragLayoutProvider dl) { displayId = dispId; context = c; wm = w; Loading libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java +22 −14 Original line number Diff line number Diff line Loading @@ -23,10 +23,10 @@ import static android.content.pm.ActivityInfo.CONFIG_UI_MODE; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_LEFT; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_TOP; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_BOTTOM; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_LEFT; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_RIGHT; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_TOP; import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; Loading @@ -47,6 +47,7 @@ import android.graphics.Region; import android.graphics.drawable.Drawable; import android.view.DragEvent; import android.view.SurfaceControl; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.WindowInsets; import android.view.WindowInsets.Type; Loading @@ -66,13 +67,13 @@ import com.android.wm.shell.shared.animation.Interpolators; import com.android.wm.shell.splitscreen.SplitScreenController; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; /** * Coordinates the visible drop targets for the current drag within a single display. */ public class DragLayout extends LinearLayout implements ViewTreeObserver.OnComputeInternalInsetsListener { implements ViewTreeObserver.OnComputeInternalInsetsListener, DragLayoutProvider { // While dragging the status bar is hidden. private static final int HIDE_STATUS_BAR_FLAGS = StatusBarManager.DISABLE_NOTIFICATION_ICONS Loading @@ -80,7 +81,7 @@ public class DragLayout extends LinearLayout | StatusBarManager.DISABLE_CLOCK | StatusBarManager.DISABLE_SYSTEM_INFO; private final DragAndDropPolicy mPolicy; private final DropTarget mPolicy; private final SplitScreenController mSplitScreenController; private final IconProvider mIconProvider; private final StatusBarManager mStatusBarManager; Loading @@ -91,7 +92,7 @@ public class DragLayout extends LinearLayout // Whether the device is currently in left/right split mode private boolean mIsLeftRightSplit; private DragAndDropPolicy.Target mCurrentTarget = null; private SplitDragPolicy.Target mCurrentTarget = null; private DropZoneView mDropZoneView1; private DropZoneView mDropZoneView2; Loading @@ -113,7 +114,7 @@ public class DragLayout extends LinearLayout super(context); mSplitScreenController = splitScreenController; mIconProvider = iconProvider; mPolicy = new DragAndDropPolicy(context, splitScreenController); mPolicy = new SplitDragPolicy(context, splitScreenController); mStatusBarManager = context.getSystemService(StatusBarManager.class); mLastConfiguration.setTo(context.getResources().getConfiguration()); Loading Loading @@ -387,6 +388,13 @@ public class DragLayout extends LinearLayout recomputeDropTargets(); } @NonNull @Override public void addDraggingView(ViewGroup rootView) { // TODO(b/349828130) We need to separate out view + logic here rootView.addView(this, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); } /** * Recalculates the drop targets based on the current policy. */ Loading @@ -394,9 +402,9 @@ public class DragLayout extends LinearLayout if (!mIsShowing) { return; } final ArrayList<DragAndDropPolicy.Target> targets = mPolicy.getTargets(mInsets); final List<SplitDragPolicy.Target> targets = mPolicy.getTargets(mInsets); for (int i = 0; i < targets.size(); i++) { final DragAndDropPolicy.Target target = targets.get(i); final SplitDragPolicy.Target target = targets.get(i); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Add target: %s", target); // Inset the draw region by a little bit target.drawRegion.inset(mDisplayMargin, mDisplayMargin); Loading @@ -419,7 +427,7 @@ public class DragLayout extends LinearLayout } // Find containing region, if the same as mCurrentRegion, then skip, otherwise, animate the // visibility of the current region DragAndDropPolicy.Target target = mPolicy.getTargetAtLocation(x, y); SplitDragPolicy.Target target = mPolicy.getTargetAtLocation(x, y); if (mCurrentTarget != target) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Current target: %s", target); if (target == null) { Loading Loading @@ -493,7 +501,7 @@ public class DragLayout extends LinearLayout mHasDropped = true; // Process the drop mPolicy.handleDrop(mCurrentTarget, hideTaskToken); mPolicy.onDropped(mCurrentTarget, hideTaskToken); // Start animating the drop UI out with the drag surface hide(event, dropCompleteCallback); Loading Loading @@ -576,7 +584,7 @@ public class DragLayout extends LinearLayout } } private void animateHighlight(DragAndDropPolicy.Target target) { private void animateHighlight(SplitDragPolicy.Target target) { if (target.type == TYPE_SPLIT_LEFT || target.type == TYPE_SPLIT_TOP) { mDropZoneView1.setShowingHighlight(true); mDropZoneView2.setShowingHighlight(false); Loading libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayoutProvider.kt 0 → 100644 +80 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.wm.shell.draganddrop import android.content.res.Configuration import android.view.DragEvent import android.view.SurfaceControl import android.view.ViewGroup import android.window.WindowContainerToken import com.android.internal.logging.InstanceId import java.io.PrintWriter /** Interface to be implemented by any controllers providing a layout for DragAndDrop in Shell */ interface DragLayoutProvider { /** * Updates the drag layout based on the given drag session. */ fun updateSession(session: DragSession) /** * Called when a new drag is started. */ fun prepare(session: DragSession, loggerSessionId: InstanceId?) /** * Shows the drag layout. */ fun show() /** * Updates the visible drop target as the user drags. */ fun update(event: DragEvent?) /** * Hides the drag layout and animates out the visible drop targets. */ fun hide(event: DragEvent?, hideCompleteCallback: Runnable?) /** * Whether target has already been dropped or not */ fun hasDropped(): Boolean /** * Handles the drop onto a target and animates out the visible drop targets. */ fun drop( event: DragEvent?, dragSurface: SurfaceControl, hideTaskToken: WindowContainerToken?, dropCompleteCallback: Runnable? ): Boolean /** * Dumps information about this drag layout. */ fun dump(pw: PrintWriter, prefix: String?) /** * @return a View which will be added to the global root view for drag and drop */ fun addDraggingView(viewGroup: ViewGroup) /** * Called when the configuration changes. */ fun onConfigChanged(newConfig: Configuration?) } No newline at end of file libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropTarget.kt 0 → 100644 +56 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.wm.shell.draganddrop import android.graphics.Insets import android.window.WindowContainerToken import com.android.internal.logging.InstanceId /** * Interface to be implemented by classes which want to provide drop targets * for DragAndDrop in Shell */ interface DropTarget { // TODO(b/349828130) Delete after flexible split launches /** * Called at the start of a Drag, before input events are processed. */ fun start(dragSession: DragSession, logSessionId: InstanceId) /** * @return [SplitDragPolicy.Target] corresponding to the given coords in display bounds. */ fun getTargetAtLocation(x: Int, y: Int) : SplitDragPolicy.Target /** * @return total number of drop targets for the current drag session. */ fun getNumTargets() : Int // TODO(b/349828130) /** * @return [List<SplitDragPolicy.Target>] to show for the current drag session. */ fun getTargets(insets: Insets) : List<SplitDragPolicy.Target> /** * Called when user is hovering Drag object over the given Target */ fun onHoveringOver(target: SplitDragPolicy.Target) {} /** * Called when the user has dropped the provided target (need not be the same target as * [onHoveringOver]) */ fun onDropped(target: SplitDragPolicy.Target, hideTaskToken: WindowContainerToken) } No newline at end of file libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java→libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/SplitDragPolicy.java +20 −17 Original line number Diff line number Diff line Loading @@ -32,11 +32,11 @@ import static android.content.Intent.EXTRA_USER; import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_FULLSCREEN; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_LEFT; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_TOP; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_FULLSCREEN; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_BOTTOM; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_LEFT; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_RIGHT; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_TOP; import static com.android.wm.shell.shared.draganddrop.DragAndDropConstants.EXTRA_DISALLOW_HIT_REGION; import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; Loading Loading @@ -80,9 +80,9 @@ import java.util.ArrayList; /** * The policy for handling drag and drop operations to shell. */ public class DragAndDropPolicy { public class SplitDragPolicy implements DropTarget { private static final String TAG = DragAndDropPolicy.class.getSimpleName(); private static final String TAG = SplitDragPolicy.class.getSimpleName(); private final Context mContext; // Used only for launching a fullscreen task (or as a fallback if there is no split starter) Loading @@ -90,18 +90,18 @@ public class DragAndDropPolicy { // Used for launching tasks into splitscreen private final Starter mSplitscreenStarter; private final SplitScreenController mSplitScreen; private final ArrayList<DragAndDropPolicy.Target> mTargets = new ArrayList<>(); private final ArrayList<SplitDragPolicy.Target> mTargets = new ArrayList<>(); private final RectF mDisallowHitRegion = new RectF(); private InstanceId mLoggerSessionId; private DragSession mSession; public DragAndDropPolicy(Context context, SplitScreenController splitScreen) { public SplitDragPolicy(Context context, SplitScreenController splitScreen) { this(context, splitScreen, new DefaultStarter(context)); } @VisibleForTesting DragAndDropPolicy(Context context, SplitScreenController splitScreen, SplitDragPolicy(Context context, SplitScreenController splitScreen, Starter fullscreenStarter) { mContext = context; mSplitScreen = splitScreen; Loading @@ -112,7 +112,7 @@ public class DragAndDropPolicy { /** * Starts a new drag session with the given initial drag data. */ void start(DragSession session, InstanceId loggerSessionId) { public void start(DragSession session, InstanceId loggerSessionId) { mLoggerSessionId = loggerSessionId; mSession = session; RectF disallowHitRegion = mSession.appData != null Loading @@ -128,7 +128,8 @@ public class DragAndDropPolicy { /** * Returns the number of targets. */ int getNumTargets() { @Override public int getNumTargets() { return mTargets.size(); } Loading @@ -136,7 +137,8 @@ public class DragAndDropPolicy { * Returns the target's regions based on the current state of the device and display. */ @NonNull ArrayList<Target> getTargets(Insets insets) { @Override public ArrayList<Target> getTargets(@NonNull Insets insets) { mTargets.clear(); if (mSession == null) { // Return early if this isn't an app drag Loading Loading @@ -222,12 +224,12 @@ public class DragAndDropPolicy { * Returns the target at the given position based on the targets previously calculated. */ @Nullable Target getTargetAtLocation(int x, int y) { public Target getTargetAtLocation(int x, int y) { if (mDisallowHitRegion.contains(x, y)) { return null; } for (int i = mTargets.size() - 1; i >= 0; i--) { DragAndDropPolicy.Target t = mTargets.get(i); SplitDragPolicy.Target t = mTargets.get(i); if (t.hitRegion.contains(x, y)) { return t; } Loading @@ -241,7 +243,7 @@ public class DragAndDropPolicy { * container transaction if possible. */ @VisibleForTesting void handleDrop(Target target, @Nullable WindowContainerToken hideTaskToken) { public void onDropped(Target target, @Nullable WindowContainerToken hideTaskToken) { if (target == null || !mTargets.contains(target)) { return; } Loading Loading @@ -419,8 +421,9 @@ public class DragAndDropPolicy { /** * Represents a drop target. * TODO(b/349828130): Move this into {@link DropTarget} */ static class Target { public static class Target { static final int TYPE_FULLSCREEN = 0; static final int TYPE_SPLIT_LEFT = 1; static final int TYPE_SPLIT_TOP = 2; Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java +5 −7 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import static android.view.DragEvent.ACTION_DROP; import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.view.WindowManager.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; Loading Loading @@ -247,9 +246,8 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll R.layout.global_drop_target, null); rootView.setOnDragListener(this); rootView.setVisibility(View.INVISIBLE); DragLayout dragLayout = new DragLayout(context, mSplitScreen, mIconProvider); rootView.addView(dragLayout, new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)); DragLayoutProvider dragLayout = new DragLayout(context, mSplitScreen, mIconProvider); dragLayout.addDraggingView(rootView); try { wm.addView(rootView, layoutParams); addDisplayDropTarget(displayId, context, wm, rootView, dragLayout); Loading @@ -261,7 +259,7 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll @VisibleForTesting void addDisplayDropTarget(int displayId, Context context, WindowManager wm, FrameLayout rootView, DragLayout dragLayout) { FrameLayout rootView, DragLayoutProvider dragLayout) { mDisplayDropTargets.put(displayId, new PerDisplay(displayId, context, wm, rootView, dragLayout)); } Loading Loading @@ -564,7 +562,7 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll final Context context; final WindowManager wm; final FrameLayout rootView; final DragLayout dragLayout; final DragLayoutProvider dragLayout; // Tracks whether the window has fully drawn since it was last made visible boolean hasDrawn; Loading @@ -575,7 +573,7 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll // The active drag session DragSession dragSession; PerDisplay(int dispId, Context c, WindowManager w, FrameLayout rv, DragLayout dl) { PerDisplay(int dispId, Context c, WindowManager w, FrameLayout rv, DragLayoutProvider dl) { displayId = dispId; context = c; wm = w; Loading
libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java +22 −14 Original line number Diff line number Diff line Loading @@ -23,10 +23,10 @@ import static android.content.pm.ActivityInfo.CONFIG_UI_MODE; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_LEFT; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_TOP; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_BOTTOM; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_LEFT; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_RIGHT; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_TOP; import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; Loading @@ -47,6 +47,7 @@ import android.graphics.Region; import android.graphics.drawable.Drawable; import android.view.DragEvent; import android.view.SurfaceControl; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.WindowInsets; import android.view.WindowInsets.Type; Loading @@ -66,13 +67,13 @@ import com.android.wm.shell.shared.animation.Interpolators; import com.android.wm.shell.splitscreen.SplitScreenController; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; /** * Coordinates the visible drop targets for the current drag within a single display. */ public class DragLayout extends LinearLayout implements ViewTreeObserver.OnComputeInternalInsetsListener { implements ViewTreeObserver.OnComputeInternalInsetsListener, DragLayoutProvider { // While dragging the status bar is hidden. private static final int HIDE_STATUS_BAR_FLAGS = StatusBarManager.DISABLE_NOTIFICATION_ICONS Loading @@ -80,7 +81,7 @@ public class DragLayout extends LinearLayout | StatusBarManager.DISABLE_CLOCK | StatusBarManager.DISABLE_SYSTEM_INFO; private final DragAndDropPolicy mPolicy; private final DropTarget mPolicy; private final SplitScreenController mSplitScreenController; private final IconProvider mIconProvider; private final StatusBarManager mStatusBarManager; Loading @@ -91,7 +92,7 @@ public class DragLayout extends LinearLayout // Whether the device is currently in left/right split mode private boolean mIsLeftRightSplit; private DragAndDropPolicy.Target mCurrentTarget = null; private SplitDragPolicy.Target mCurrentTarget = null; private DropZoneView mDropZoneView1; private DropZoneView mDropZoneView2; Loading @@ -113,7 +114,7 @@ public class DragLayout extends LinearLayout super(context); mSplitScreenController = splitScreenController; mIconProvider = iconProvider; mPolicy = new DragAndDropPolicy(context, splitScreenController); mPolicy = new SplitDragPolicy(context, splitScreenController); mStatusBarManager = context.getSystemService(StatusBarManager.class); mLastConfiguration.setTo(context.getResources().getConfiguration()); Loading Loading @@ -387,6 +388,13 @@ public class DragLayout extends LinearLayout recomputeDropTargets(); } @NonNull @Override public void addDraggingView(ViewGroup rootView) { // TODO(b/349828130) We need to separate out view + logic here rootView.addView(this, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); } /** * Recalculates the drop targets based on the current policy. */ Loading @@ -394,9 +402,9 @@ public class DragLayout extends LinearLayout if (!mIsShowing) { return; } final ArrayList<DragAndDropPolicy.Target> targets = mPolicy.getTargets(mInsets); final List<SplitDragPolicy.Target> targets = mPolicy.getTargets(mInsets); for (int i = 0; i < targets.size(); i++) { final DragAndDropPolicy.Target target = targets.get(i); final SplitDragPolicy.Target target = targets.get(i); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Add target: %s", target); // Inset the draw region by a little bit target.drawRegion.inset(mDisplayMargin, mDisplayMargin); Loading @@ -419,7 +427,7 @@ public class DragLayout extends LinearLayout } // Find containing region, if the same as mCurrentRegion, then skip, otherwise, animate the // visibility of the current region DragAndDropPolicy.Target target = mPolicy.getTargetAtLocation(x, y); SplitDragPolicy.Target target = mPolicy.getTargetAtLocation(x, y); if (mCurrentTarget != target) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_DRAG_AND_DROP, "Current target: %s", target); if (target == null) { Loading Loading @@ -493,7 +501,7 @@ public class DragLayout extends LinearLayout mHasDropped = true; // Process the drop mPolicy.handleDrop(mCurrentTarget, hideTaskToken); mPolicy.onDropped(mCurrentTarget, hideTaskToken); // Start animating the drop UI out with the drag surface hide(event, dropCompleteCallback); Loading Loading @@ -576,7 +584,7 @@ public class DragLayout extends LinearLayout } } private void animateHighlight(DragAndDropPolicy.Target target) { private void animateHighlight(SplitDragPolicy.Target target) { if (target.type == TYPE_SPLIT_LEFT || target.type == TYPE_SPLIT_TOP) { mDropZoneView1.setShowingHighlight(true); mDropZoneView2.setShowingHighlight(false); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayoutProvider.kt 0 → 100644 +80 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.wm.shell.draganddrop import android.content.res.Configuration import android.view.DragEvent import android.view.SurfaceControl import android.view.ViewGroup import android.window.WindowContainerToken import com.android.internal.logging.InstanceId import java.io.PrintWriter /** Interface to be implemented by any controllers providing a layout for DragAndDrop in Shell */ interface DragLayoutProvider { /** * Updates the drag layout based on the given drag session. */ fun updateSession(session: DragSession) /** * Called when a new drag is started. */ fun prepare(session: DragSession, loggerSessionId: InstanceId?) /** * Shows the drag layout. */ fun show() /** * Updates the visible drop target as the user drags. */ fun update(event: DragEvent?) /** * Hides the drag layout and animates out the visible drop targets. */ fun hide(event: DragEvent?, hideCompleteCallback: Runnable?) /** * Whether target has already been dropped or not */ fun hasDropped(): Boolean /** * Handles the drop onto a target and animates out the visible drop targets. */ fun drop( event: DragEvent?, dragSurface: SurfaceControl, hideTaskToken: WindowContainerToken?, dropCompleteCallback: Runnable? ): Boolean /** * Dumps information about this drag layout. */ fun dump(pw: PrintWriter, prefix: String?) /** * @return a View which will be added to the global root view for drag and drop */ fun addDraggingView(viewGroup: ViewGroup) /** * Called when the configuration changes. */ fun onConfigChanged(newConfig: Configuration?) } No newline at end of file
libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DropTarget.kt 0 → 100644 +56 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.wm.shell.draganddrop import android.graphics.Insets import android.window.WindowContainerToken import com.android.internal.logging.InstanceId /** * Interface to be implemented by classes which want to provide drop targets * for DragAndDrop in Shell */ interface DropTarget { // TODO(b/349828130) Delete after flexible split launches /** * Called at the start of a Drag, before input events are processed. */ fun start(dragSession: DragSession, logSessionId: InstanceId) /** * @return [SplitDragPolicy.Target] corresponding to the given coords in display bounds. */ fun getTargetAtLocation(x: Int, y: Int) : SplitDragPolicy.Target /** * @return total number of drop targets for the current drag session. */ fun getNumTargets() : Int // TODO(b/349828130) /** * @return [List<SplitDragPolicy.Target>] to show for the current drag session. */ fun getTargets(insets: Insets) : List<SplitDragPolicy.Target> /** * Called when user is hovering Drag object over the given Target */ fun onHoveringOver(target: SplitDragPolicy.Target) {} /** * Called when the user has dropped the provided target (need not be the same target as * [onHoveringOver]) */ fun onDropped(target: SplitDragPolicy.Target, hideTaskToken: WindowContainerToken) } No newline at end of file
libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java→libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/SplitDragPolicy.java +20 −17 Original line number Diff line number Diff line Loading @@ -32,11 +32,11 @@ import static android.content.Intent.EXTRA_USER; import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_FULLSCREEN; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_BOTTOM; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_LEFT; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_RIGHT; import static com.android.wm.shell.draganddrop.DragAndDropPolicy.Target.TYPE_SPLIT_TOP; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_FULLSCREEN; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_BOTTOM; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_LEFT; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_RIGHT; import static com.android.wm.shell.draganddrop.SplitDragPolicy.Target.TYPE_SPLIT_TOP; import static com.android.wm.shell.shared.draganddrop.DragAndDropConstants.EXTRA_DISALLOW_HIT_REGION; import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.shared.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; Loading Loading @@ -80,9 +80,9 @@ import java.util.ArrayList; /** * The policy for handling drag and drop operations to shell. */ public class DragAndDropPolicy { public class SplitDragPolicy implements DropTarget { private static final String TAG = DragAndDropPolicy.class.getSimpleName(); private static final String TAG = SplitDragPolicy.class.getSimpleName(); private final Context mContext; // Used only for launching a fullscreen task (or as a fallback if there is no split starter) Loading @@ -90,18 +90,18 @@ public class DragAndDropPolicy { // Used for launching tasks into splitscreen private final Starter mSplitscreenStarter; private final SplitScreenController mSplitScreen; private final ArrayList<DragAndDropPolicy.Target> mTargets = new ArrayList<>(); private final ArrayList<SplitDragPolicy.Target> mTargets = new ArrayList<>(); private final RectF mDisallowHitRegion = new RectF(); private InstanceId mLoggerSessionId; private DragSession mSession; public DragAndDropPolicy(Context context, SplitScreenController splitScreen) { public SplitDragPolicy(Context context, SplitScreenController splitScreen) { this(context, splitScreen, new DefaultStarter(context)); } @VisibleForTesting DragAndDropPolicy(Context context, SplitScreenController splitScreen, SplitDragPolicy(Context context, SplitScreenController splitScreen, Starter fullscreenStarter) { mContext = context; mSplitScreen = splitScreen; Loading @@ -112,7 +112,7 @@ public class DragAndDropPolicy { /** * Starts a new drag session with the given initial drag data. */ void start(DragSession session, InstanceId loggerSessionId) { public void start(DragSession session, InstanceId loggerSessionId) { mLoggerSessionId = loggerSessionId; mSession = session; RectF disallowHitRegion = mSession.appData != null Loading @@ -128,7 +128,8 @@ public class DragAndDropPolicy { /** * Returns the number of targets. */ int getNumTargets() { @Override public int getNumTargets() { return mTargets.size(); } Loading @@ -136,7 +137,8 @@ public class DragAndDropPolicy { * Returns the target's regions based on the current state of the device and display. */ @NonNull ArrayList<Target> getTargets(Insets insets) { @Override public ArrayList<Target> getTargets(@NonNull Insets insets) { mTargets.clear(); if (mSession == null) { // Return early if this isn't an app drag Loading Loading @@ -222,12 +224,12 @@ public class DragAndDropPolicy { * Returns the target at the given position based on the targets previously calculated. */ @Nullable Target getTargetAtLocation(int x, int y) { public Target getTargetAtLocation(int x, int y) { if (mDisallowHitRegion.contains(x, y)) { return null; } for (int i = mTargets.size() - 1; i >= 0; i--) { DragAndDropPolicy.Target t = mTargets.get(i); SplitDragPolicy.Target t = mTargets.get(i); if (t.hitRegion.contains(x, y)) { return t; } Loading @@ -241,7 +243,7 @@ public class DragAndDropPolicy { * container transaction if possible. */ @VisibleForTesting void handleDrop(Target target, @Nullable WindowContainerToken hideTaskToken) { public void onDropped(Target target, @Nullable WindowContainerToken hideTaskToken) { if (target == null || !mTargets.contains(target)) { return; } Loading Loading @@ -419,8 +421,9 @@ public class DragAndDropPolicy { /** * Represents a drop target. * TODO(b/349828130): Move this into {@link DropTarget} */ static class Target { public static class Target { static final int TYPE_FULLSCREEN = 0; static final int TYPE_SPLIT_LEFT = 1; static final int TYPE_SPLIT_TOP = 2; Loading